{"id":19568441,"url":"https://github.com/medooze/semantic-sdp-js","last_synced_at":"2025-03-31T05:06:12.973Z","repository":{"id":49729938,"uuid":"82541217","full_name":"medooze/semantic-sdp-js","owner":"medooze","description":"WebRTC Semantic SDP - Minimal SDP information semantic data model and parsing tools","archived":false,"fork":false,"pushed_at":"2024-09-20T07:48:50.000Z","size":1610,"stargazers_count":73,"open_issues_count":0,"forks_count":14,"subscribers_count":8,"default_branch":"master","last_synced_at":"2024-10-15T01:31:58.215Z","etag":null,"topics":["sdp","webrtc"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/medooze.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,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-02-20T09:40:10.000Z","updated_at":"2024-09-20T07:48:51.000Z","dependencies_parsed_at":"2023-01-18T16:00:16.018Z","dependency_job_id":"6bef74ed-7dc4-4706-9f8f-3d8c65b92a45","html_url":"https://github.com/medooze/semantic-sdp-js","commit_stats":{"total_commits":271,"total_committers":16,"mean_commits":16.9375,"dds":"0.40590405904059046","last_synced_commit":"0904b508f5168f750e662e76c98e1d6b20a00709"},"previous_names":[],"tags_count":94,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/medooze%2Fsemantic-sdp-js","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/medooze%2Fsemantic-sdp-js/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/medooze%2Fsemantic-sdp-js/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/medooze%2Fsemantic-sdp-js/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/medooze","download_url":"https://codeload.github.com/medooze/semantic-sdp-js/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246418639,"owners_count":20773935,"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":["sdp","webrtc"],"created_at":"2024-11-11T06:04:24.757Z","updated_at":"2025-03-31T05:06:12.933Z","avatar_url":"https://github.com/medooze.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# WebRTC Semantic SDP\nMinimal SDP information semantic data model and parsing tools.\n\n## Motivation\nHave you ever tried to mangle or process an SDP and got stuck about how to you change the information instead of what information do you want to access?\n\nThis project provies an abstraction layer on top of SDP that allows to acces and modify the information semantically, that is, it stores the SDP information and their relationships and allows you to get free of the acutal SDP semantics.\n\nAs it is meant to be used on WebRTC to WebRTC scenarios, so some SDP information can be safelly ignored, allowing to provide a simple and intuitive API.\n\nBoth Unified and Plan B are currently supported\n\n## Assumptions\n\nWe assume that:\n- Bundle is used\n- Trickle ICE or ICE lite is used\n- DTLS is used\n- RTCP mux is used\n\n## For the future\nIf you think it further exchanging the SDP information is all that it is needed to perform a peer to peer SDP exchange, so the intention is to provide serialization functions to be able to use this over the wire and only parse/serialize it on the endpoints or server side.\n\nNote also that there is some similarity ORTC RTP parameters, but well done ;)\n\n## Install\n\n```\nnpm i --save semantic-sdp\n```\n\n## Usage\n\n```javascript\nconst SemanticSDP = require('semantic-sdp');\n```\n## API Documention\nYou can check the full object documentation [here](https://medooze.github.io/semantic-sdp-js/).\n\n## Example\n\n```javascript\nconst SemanticSDP\t= require(\"semantic-sdp\");\n\n//Process the sdp\nvar offer = SemanticSDP.SDPInfo.process(sdp);\n\n//Set the local DTLS and ICE info\nconst dtls = new DTLSInfo(Setup.PASSIVE,\"sha-256\",\"F2:AA:0E:C3:22:59:5E:14:95:69:92:3D:13:B4:84:24:2C:C2:A2:C0:3E:FD:34:8E:5E:EA:6F:AF:52:CE:E6:0F\");\nconst ice  = new ICEInfo(\"af46F\",\"a34FasdS++jdfofdslkjsd/SDV\");\n\n//Get local candidte\nconst candidate = new CandidateInfo(1,1, \"udp\", 2122260223, \"192.168.0.196\", 56143, \"host\");\n\n//Create local SDP info\nlet answer = new SDPInfo();\n\n\n//Add ice and dtls info\nanswer.setDTLS(dtls);\nanswer.setICE(ice);\nanswer.addCandidate(candidate);\n\n//Get remote audio m-line info \nlet audioOffer = offer.getMedia(\"audio\");\n\n//If we have audio\nif (audioOffer)\n{\n\t//Create audio media\n\tlet audio = new MediaInfo(\"audio\", \"audio\");\n\t\n\t//Get codec type\n\tlet opus = audioOffer.getCodec(\"opus\");\n\t//Add opus codec\n\taudio.addCodec(opus);\n\n\t//Add audio extensions\n\tfor (let extension of audioOffer.getExtensions().entries())\n\t\t//Add it\n\t\taudio.addExtension(extension[0], extension[1]);\n\t//Add it to answer\n\tanswer.addMedia(audio);\n}\n\n//Get remote video m-line info \nlet videoOffer = offer.getMedia(\"video\");\n\n//If offer had video\nif (videoOffer)\n{\n\t//Create video media\n\tlet  video = new MediaInfo(\"video\", \"video\");\n\t//Get codec types\n\tlet vp9 = videoOffer.getCodec(\"vp9\");\n\tlet fec = videoOffer.getCodec(\"flexfec-03\");\n\t//Add video codecs\n\tvideo.addCodec(vp9);\n\tif (fec)\n\t\tvideo.addCodec(fec);\n\t//Limit incoming bitrate\n\tvideo.setBitrate(1024);\n\n\t//Add video extensions\n\tfor (let extension of videoOffer.getExtensions().entries())\n\t\t//Add it\n\t\tvideo.addExtension(extension[0], extension[1]);\n\n\t//Add it to answer\n\tanswer.addMedia(video);\n}\n\nlet ssrc = 1000;\n//For each stream\nfor (let i=1;i\u003c4;i++)\n{\n\tlet track;\n\t//Create stream\n\tlet stream = new StreamInfo(\"sream\"+i);\n\t//Create track\n\ttrack = new TrackInfo(\"video\", \"track1\");\n\t//Get ssrc, rtx and fec \n\tconst media = ssrc++;\n\tconst rtx = ssrc++;\n\tconst fec = ssrc++;\n\t//Add ssrcs to track\n\ttrack.addSSRC(media);\n\ttrack.addSSRC(rtx);\n\ttrack.addSSRC(fec);\n\t//Add RTX and FEC group\t\n\ttrack.addSourceGroup(new SourceGroupInfo(\"FID\",[media,rtx]));\n\ttrack.addSourceGroup(new SourceGroupInfo(\"FEC-FR\",[media,fec]));\n\t//Add it\n\tstream.addTrack(track);\n\t//Create track\n\ttrack = new TrackInfo(\"audio\", \"track2\");\n\t//Add ssrc\n\ttrack.addSSRC(ssrc++);\n\t//Add it\n\tstream.addTrack(track);\n\t//Add stream\n\tanswer.addStream(stream);\n}\n\n//Get answer SDP\nconst str = answer.toString();\nconst json = JSON.stringifu(answer.plain());\n```\n\nThe SDP output will be :\n\n```\nv=0\no=- 1489500633629 1 IN IP4 127.0.0.1\ns=semantic-sdp\nc=IN IP4 0.0.0.0\nt=0 0\na=msid-semantic: WMS *\nm=audio 9 UDP/TLS/RTP/SAVPF 111\na=rtpmap:111 opus/48000/2\na=rtcp-fb:111 transport-cc\na=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level\na=setup:passive\na=mid:audio\na=sendrecv\na=ice-ufrag:af46F\na=ice-pwd:a34FasdS++jdfofdslkjsd/SDV\na=fingerprint:sha-256 F2:AA:0E:C3:22:59:5E:14:95:69:92:3D:13:B4:84:24:2C:C2:A2:C0:3E:FD:34:8E:5E:EA:6F:AF:52:CE:E6:0F\na=candidate:1 1 udp 2122260223 192.168.0.196 56143 typ host\na=ssrc:1003 cname:sream1\na=ssrc:1003 msid:sream1 track2\na=ssrc:1007 cname:sream2\na=ssrc:1007 msid:sream2 track2\na=ssrc:1011 cname:sream3\na=ssrc:1011 msid:sream3 track2\na=rtcp-mux\na=rtcp-rsize\nm=video 9 UDP/TLS/RTP/SAVPF 98 99 125\nb=AS:1024\na=rtpmap:98 VP9/90000\na=rtpmap:99 rtx/90000\na=rtpmap:125 flexfec-03/90000\na=fmtp:99 apt=98\na=rtcp-fb:98 transport-cc\na=rtcp-fb:125 transport-cc\na=extmap:2 urn:ietf:params:rtp-hdrext:toffset\na=extmap:3 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time\na=extmap:4 urn:3gpp:video-orientation\na=extmap:5 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01\na=extmap:6 http://www.webrtc.org/experiments/rtp-hdrext/playout-delay\na=setup:passive\na=mid:video\na=sendrecv\na=ice-ufrag:af46F\na=ice-pwd:a34FasdS++jdfofdslkjsd/SDV\na=fingerprint:sha-256 F2:AA:0E:C3:22:59:5E:14:95:69:92:3D:13:B4:84:24:2C:C2:A2:C0:3E:FD:34:8E:5E:EA:6F:AF:52:CE:E6:0F\na=candidate:1 1 udp 2122260223 192.168.0.196 56143 typ host\na=ssrc:1000 cname:sream1\na=ssrc:1000 msid:sream1 track1\na=ssrc:1001 cname:sream1\na=ssrc:1001 msid:sream1 track1\na=ssrc:1002 cname:sream1\na=ssrc:1002 msid:sream1 track1\na=ssrc:1004 cname:sream2\na=ssrc:1004 msid:sream2 track1\na=ssrc:1005 cname:sream2\na=ssrc:1005 msid:sream2 track1\na=ssrc:1006 cname:sream2\na=ssrc:1006 msid:sream2 track1\na=ssrc:1008 cname:sream3\na=ssrc:1008 msid:sream3 track1\na=ssrc:1009 cname:sream3\na=ssrc:1009 msid:sream3 track1\na=ssrc:1010 cname:sream3\na=ssrc:1010 msid:sream3 track1\na=ssrc-group:FID 1000 1001\na=ssrc-group:FEC-FR 1000 1002\na=ssrc-group:FID 1004 1005\na=ssrc-group:FEC-FR 1004 1006\na=ssrc-group:FID 1008 1009\na=ssrc-group:FEC-FR 1008 1010\na=rtcp-mux\na=rtcp-rsize\n\n```\n\nAnd the serialized JSON string:\n```json\n{\n  \"version\": 1,\n  \"streams\": [\n    {\n      \"tracks\": [\n        {\n          \"media\": \"video\",\n          \"id\": \"track1\",\n          \"ssrcs\": [\n            1000,\n            1001,\n            1002\n          ],\n          \"groups\": [\n            {\n              \"semantics\": \"FID\",\n              \"ssrcs\": [\n                1000,\n                1001\n              ]\n            },\n            {\n              \"semantics\": \"FEC-FR\",\n              \"ssrcs\": [\n                1000,\n                1002\n              ]\n            }\n          ]\n        },\n        {\n          \"media\": \"audio\",\n          \"id\": \"track2\",\n          \"ssrcs\": [\n            1003\n          ],\n          \"groups\": [\n            \n          ]\n        }\n      ]\n    },\n    {\n      \"tracks\": [\n        {\n          \"media\": \"video\",\n          \"id\": \"track1\",\n          \"ssrcs\": [\n            1004,\n            1005,\n            1006\n          ],\n          \"groups\": [\n            {\n              \"semantics\": \"FID\",\n              \"ssrcs\": [\n                1004,\n                1005\n              ]\n            },\n            {\n              \"semantics\": \"FEC-FR\",\n              \"ssrcs\": [\n                1004,\n                1006\n              ]\n            }\n          ]\n        },\n        {\n          \"media\": \"audio\",\n          \"id\": \"track2\",\n          \"ssrcs\": [\n            1007\n          ],\n          \"groups\": [\n            \n          ]\n        }\n      ]\n    },\n    {\n      \"tracks\": [\n        {\n          \"media\": \"video\",\n          \"id\": \"track1\",\n          \"ssrcs\": [\n            1008,\n            1009,\n            1010\n          ],\n          \"groups\": [\n            {\n              \"semantics\": \"FID\",\n              \"ssrcs\": [\n                1008,\n                1009\n              ]\n            },\n            {\n              \"semantics\": \"FEC-FR\",\n              \"ssrcs\": [\n                1008,\n                1010\n              ]\n            }\n          ]\n        },\n        {\n          \"media\": \"audio\",\n          \"id\": \"track2\",\n          \"ssrcs\": [\n            1011\n          ],\n          \"groups\": [\n            \n          ]\n        }\n      ]\n    }\n  ],\n  \"medias\": [\n    {\n      \"type\": \"audio\",\n      \"direction\": \"sendrecv\",\n      \"extensions\": {\n        \"1\": \"urn:ietf:params:rtp-hdrext:ssrc-audio-level\"\n      },\n      \"codecs\": [\n        {\n          \"codec\": \"opus\",\n          \"type\": 111,\n          \"params\": {\n            \"minptime\": \"10\",\n            \"useinbandfec\": \"1\"\n          }\n        }\n      ]\n    },\n    {\n      \"type\": \"video\",\n      \"direction\": \"sendrecv\",\n      \"extensions\": {\n        \"2\": \"urn:ietf:params:rtp-hdrext:toffset\",\n        \"3\": \"http:\\/\\/www.webrtc.org\\/experiments\\/rtp-hdrext\\/abs-send-time\",\n        \"4\": \"urn:3gpp:video-orientation\",\n        \"5\": \"http:\\/\\/www.ietf.org\\/id\\/draft-holmer-rmcat-transport-wide-cc-extensions-01\",\n        \"6\": \"http:\\/\\/www.webrtc.org\\/experiments\\/rtp-hdrext\\/playout-delay\"\n      },\n      \"codecs\": [\n        {\n          \"codec\": \"VP9\",\n          \"type\": 98,\n          \"params\": {\n            \n          }\n        },\n        {\n          \"codec\": \"flexfec-03\",\n          \"type\": 125,\n          \"params\": {\n            \"repair-window\": \"10000000\"\n          }\n        }\n      ],\n      \"bitrate\": 1024\n    }\n  ],\n  \"candidates\": [\n    {\n      \"foundation\": 1,\n      \"componentId\": 1,\n      \"transport\": \"udp\",\n      \"priority\": 2122260223,\n      \"address\": \"192.168.0.196\",\n      \"port\": 56143,\n      \"type\": \"host\"\n    }\n  ],\n  \"ice\": {\n    \"ufrag\": \"af46F\",\n    \"pwd\": \"a34FasdS++jdfofdslkjsd\\/SDV\"\n  },\n  \"dtls\": {\n    \"hash\": \"sha-256\",\n    \"fingerprint\": \"F2:AA:0E:C3:22:59:5E:14:95:69:92:3D:13:B4:84:24:2C:C2:A2:C0:3E:FD:34:8E:5E:EA:6F:AF:52:CE:E6:0F\"\n  }\n}\n```\n## Author\n\nSergio Garcia Murillo @ Medooze\n\n## License\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmedooze%2Fsemantic-sdp-js","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmedooze%2Fsemantic-sdp-js","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmedooze%2Fsemantic-sdp-js/lists"}