{"id":13413973,"url":"https://github.com/gortc/sdp","last_synced_at":"2025-03-14T20:30:57.800Z","repository":{"id":57481301,"uuid":"58747679","full_name":"gortc/sdp","owner":"gortc","description":"RFC 4566 SDP implementation in go","archived":true,"fork":false,"pushed_at":"2020-05-03T07:27:16.000Z","size":1776,"stargazers_count":113,"open_issues_count":5,"forks_count":31,"subscribers_count":8,"default_branch":"master","last_synced_at":"2025-03-06T09:22:41.361Z","etag":null,"topics":["decoder","encoding","go","golang","gortc","protocol","rfc-4566","sdp","webrtc"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/gortc.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-05-13T14:35:11.000Z","updated_at":"2024-03-03T16:22:18.000Z","dependencies_parsed_at":"2022-09-13T03:11:27.234Z","dependency_job_id":null,"html_url":"https://github.com/gortc/sdp","commit_stats":null,"previous_names":["ernado/sdp"],"tags_count":19,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gortc%2Fsdp","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gortc%2Fsdp/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gortc%2Fsdp/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gortc%2Fsdp/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/gortc","download_url":"https://codeload.github.com/gortc/sdp/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243642066,"owners_count":20323953,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["decoder","encoding","go","golang","gortc","protocol","rfc-4566","sdp","webrtc"],"created_at":"2024-07-30T20:01:54.151Z","updated_at":"2025-03-14T20:30:57.330Z","avatar_url":"https://github.com/gortc.png","language":"Go","readme":"[![Master status](https://tc.gortc.io/app/rest/builds/buildType:(id:sdp_MasterStatus)/statusIcon.svg)](https://tc.gortc.io/project.html?projectId=sdp\u0026tab=projectOverview\u0026guest=1)\n[![codecov](https://codecov.io/gh/gortc/sdp/branch/master/graph/badge.svg)](https://codecov.io/gh/gortc/sdp)\n[![GoDoc](https://godoc.org/gortc.io/sdp?status.svg)](https://godoc.org/gortc.io/sdp)\n\n\n# SDP\nPackage sdp implements SDP: Session Description Protocol [[RFC4566](https://tools.ietf.org/html/rfc4566)].\nComplies to [gortc principles](https://gortc.io/#principles) as core package.\n\n### Examples\nSee [examples](https://github.com/gortc/sdp/tree/master/examples) folder.\nAlso there is [online SDP example](https://gortc.io/x/sdp/) that gets\n`RTCPeerConnection.localDescription.sdp` using WebRTC, \nsends it to server, decodes as `sdp.Session` and renders it on web page.\n\nSDP example:\n```sdp\nv=0\no=jdoe 2890844526 2890842807 IN IP4 10.47.16.5\ns=SDP Seminar\ni=A Seminar on the session description protocol\nu=http://www.example.com/seminars/sdp.pdf\ne=j.doe@example.com (Jane Doe)\np=12345\nc=IN IP4 224.2.17.12/127\nb=CT:154798\nt=2873397496 2873404696\nr=7d 1h 0 25h\nk=clear:ab8c4df8b8f4as8v8iuy8re\na=recvonly\nm=audio 49170 RTP/AVP 0\nm=video 51372 RTP/AVP 99\nb=AS:66781\nk=prompt\na=rtpmap:99 h263-1998/90000\n```\nEncode:\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\t\"net\"\n\t\"time\"\n\t\n\t\"gortc.io/sdp\"\n)\n\nfunc main()  {\n\tvar (\n\t\ts sdp.Session\n\t\tb []byte\n\t)\n\t// defining medias\n\taudio := sdp.Media{\n\t\tDescription: sdp.MediaDescription{\n\t\t\tType:     \"audio\",\n\t\t\tPort:     49170,\n\t\t\tFormats:   []string{\"0\"},\n\t\t\tProtocol: \"RTP/AVP\",\n\t\t},\n\t}\n\tvideo := sdp.Media{\n\t\tDescription: sdp.MediaDescription{\n\t\t\tType:     \"video\",\n\t\t\tPort:     51372,\n\t\t\tFormats:   []string{\"99\"},\n\t\t\tProtocol: \"RTP/AVP\",\n\t\t},\n\t\tBandwidths: sdp.Bandwidths{\n\t\t\tsdp.BandwidthApplicationSpecific: 66781,\n\t\t},\n\t\tEncryption: sdp.Encryption{\n\t\t\tMethod: \"prompt\",\n\t\t},\n\t}\n\tvideo.AddAttribute(\"rtpmap\", \"99\", \"h263-1998/90000\")\n\n\t// defining message\n\tm := \u0026sdp.Message{\n\t\tOrigin: sdp.Origin{\n\t\t\tUsername:       \"jdoe\",\n\t\t\tSessionID:      2890844526,\n\t\t\tSessionVersion: 2890842807,\n\t\t\tAddress:        \"10.47.16.5\",\n\t\t},\n\t\tName:  \"SDP Seminar\",\n\t\tInfo:  \"A Seminar on the session description protocol\",\n\t\tURI:   \"http://www.example.com/seminars/sdp.pdf\",\n\t\tEmail: \"j.doe@example.com (Jane Doe)\",\n\t\tPhone: \"12345\",\n\t\tConnection: sdp.ConnectionData{\n\t\t\tIP:  net.ParseIP(\"224.2.17.12\"),\n\t\t\tTTL: 127,\n\t\t},\n\t\tBandwidths: sdp.Bandwidths{\n\t\t\tsdp.BandwidthConferenceTotal: 154798,\n\t\t},\n\t\tTiming: []sdp.Timing{\n\t\t\t{\n\t\t\t\tStart:  sdp.NTPToTime(2873397496),\n\t\t\t\tEnd:    sdp.NTPToTime(2873404696),\n\t\t\t\tRepeat: 7 * time.Hour * 24,\n\t\t\t\tActive: 3600 * time.Second,\n\t\t\t\tOffsets: []time.Duration{\n\t\t\t\t\t0,\n\t\t\t\t\t25 * time.Hour,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\tEncryption: sdp.Encryption{\n\t\t\tMethod: \"clear\",\n\t\t\tKey: \"ab8c4df8b8f4as8v8iuy8re\",\n\t\t},\n\t\tMedias: []sdp.Media{audio, video},\n\t}\n\tm.AddFlag(\"recvonly\")\n\n\t// appending message to session\n\ts = m.Append(s)\n\n\t// appending session to byte buffer\n\tb = s.AppendTo(b)\n\tfmt.Println(string(b))\n}\n```\nDecode:\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"io/ioutil\"\n\t\"log\"\n\t\"os\"\n\n\t\"gortc.io/sdp\"\n)\n\nfunc main() {\n\tname := \"example.sdp\"\n\tif len(os.Args) \u003e 1 {\n\t\tname = os.Args[1]\n\t}\n\tvar (\n\t\ts   sdp.Session\n\t\tb   []byte\n\t\terr error\n\t\tf   io.ReadCloser\n\t)\n\tfmt.Println(\"sdp file:\", name)\n\tif f, err = os.Open(name); err != nil {\n\t\tlog.Fatal(\"err:\", err)\n\t}\n\tdefer f.Close()\n\tif b, err = ioutil.ReadAll(f); err != nil {\n\t\tlog.Fatal(\"err:\", err)\n\t}\n\tif s, err = sdp.DecodeSession(b, s); err != nil {\n\t\tlog.Fatal(\"err:\", err)\n\t}\n\tfor k, v := range s {\n\t\tfmt.Println(k, v)\n\t}\n\td := sdp.NewDecoder(s)\n\tm := new(sdp.Message)\n\tif err = d.Decode(m); err != nil {\n\t\tlog.Fatal(\"err:\", err)\n\t}\n\tfmt.Println(\"Decoded session\", m.Name)\n\tfmt.Println(\"Info:\", m.Info)\n\tfmt.Println(\"Origin:\", m.Origin)\n}\n```\nAlso, low-level Session struct can be used directly to compose SDP message:\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\n\t\"gortc.io/sdp\"\n)\n\nfunc main() {\n\tvar (\n\t\ts sdp.Session\n\t\tb []byte\n\t)\n\tb = s.AddVersion(0).\n\t\tAddMediaDescription(sdp.MediaDescription{\n\t\t\tType:     \"video\",\n\t\t\tPort:     51372,\n\t\t\tFormats:   []string{\"99\"},\n\t\t\tProtocol: \"RTP/AVP\",\n\t\t}).\n\t\tAddAttribute(\"rtpmap\", \"99\", \"h263-1998/90000\").\n\t\tAddLine(sdp.TypeEmail, \"test@test.com\").\n\t\tAddRaw('ü', \"vαlue\").\n\t\tAppendTo(b)\n\t// and so on\n\tfmt.Println(string(b))\n\t// Output:\n\t//\tv=0\n\t//\tm=video 51372 RTP/AVP 99\n\t//\ta=rtpmap:99 h263-1998/90000\n\t//\te=test@test.com\n\t//\tü=vαlue\n}\n```\n\n### Supported params\n- [x] v (protocol version)\n- [x] o (originator and session identifier)\n- [x] s (session name)\n- [x] i (session information)\n- [x] u (URI of description)\n- [x] e (email address)\n- [x] p (phone number)\n- [x] c (connection information)\n- [x] b (zero or more bandwidth information lines)\n- [x] t (time)\n- [x] r (repeat)\n- [x] z (time zone adjustments)\n- [x] k (encryption key)\n- [x] a (zero or more session attribute lines)\n- [x] m (media name and transport address)\n\n### TODO:\n- [x] Encoding\n- [x] Parsing\n- [x] High level encoding\n- [x] High level decoding\n- [x] Examples\n- [x] CI\n- [x] More examples and docs\n- [x] Online example\n- [ ] io.Reader and io.Writer interop\n- [ ] Include to high-level CI\n\n### Possible optimizations\nThere are comments `// ALLOCATIONS: suboptimal.` and `// CPU: suboptimal. `\nthat indicate suboptimal implementation that can be optimized. There are often\na benchmarks for this pieces.\n\n### Benchmarks\n```\ngoos: linux\ngoarch: amd64\npkg: github.com/gortc/sdp\nPASS\nbenchmark                                    iter       time/iter   bytes alloc         allocs\n---------                                    ----       ---------   -----------         ------\nBenchmarkDecoder_Decode-12                 300000   4884.00 ns/op     3166 B/op   93 allocs/op\nBenchmarkEncode-12                        1000000   1577.00 ns/op        0 B/op    0 allocs/op\nBenchmarkSession_AddConnectionData-12    20000000    114.00 ns/op        0 B/op    0 allocs/op\nBenchmarkAppendIP-12                     50000000     37.90 ns/op        0 B/op    0 allocs/op\nBenchmarkAppendByte-12                  100000000     11.00 ns/op        0 B/op    0 allocs/op\nBenchmarkAppendInt-12                   100000000     11.90 ns/op        0 B/op    0 allocs/op\nBenchmarkSession_EX1-12                   3000000    578.00 ns/op       16 B/op    1 allocs/op\nBenchmarkAppendRune-12                  200000000      6.70 ns/op        0 B/op    0 allocs/op\nBenchmarkDecode-12                      100000000     13.10 ns/op        0 B/op    0 allocs/op\nBenchmarkDecodeSession-12                 5000000    234.00 ns/op        0 B/op    0 allocs/op\nok  \tgithub.com/gortc/sdp\t16.820s\n```\n\n## Build status\n[![Build Status](https://travis-ci.com/gortc/sdp.svg?branch=master)](https://travis-ci.com/gortc/sdp)\n[![Build status](https://ci.appveyor.com/api/projects/status/gcxr3fq9ebadmu9b?svg=true)](https://ci.appveyor.com/project/ernado/sdp)\n\n## License\n[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Fgortc%2Fsdp.svg?type=large)](https://app.fossa.io/projects/git%2Bgithub.com%2Fgortc%2Fsdp?ref=badge_large)\n","funding_links":[],"categories":["Text Processing","文本处理","Specific Formats","文本处理`解析和操作文本的代码库`","Bot Building"],"sub_categories":["HTTP Clients","查询语","解析 器/Encoders/Decoders","Parsers/Encoders/Decoders","交流"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgortc%2Fsdp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgortc%2Fsdp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgortc%2Fsdp/lists"}