From 825bd93e0dcb6a2c0749e643eff1759e5828de3b Mon Sep 17 00:00:00 2001 From: Sangwon Oh Date: Mon, 13 Mar 2023 08:50:41 +0900 Subject: [PATCH] Add the ability to set preferred video codec instance.startStreaming(connectionUrl, connectionConfig) ConnectionConfig.preferredVideoFormat - type - String: Video codec name (eq. H256, VP8) - If set the specified codec will be preferred if available. --- README.md | 6 ++++++ package-lock.json | 7 +++---- package.json | 2 +- src/OvenLiveKit.js | 47 +++++++++++++++++++++++++++++++++++++++++++--- 4 files changed, 54 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index db5d34d..04ef5fc 100644 --- a/README.md +++ b/README.md @@ -271,6 +271,11 @@ ovenLivekit.getUserMedia().then(function () { - When this API is called, the media stream starts to be streamed according to OvenMediaEngine's signaling protocol. #### `ConnectionConfig` + +##### `preferredVideoFormat` +- type + - String: Video codec name (eq. H256, VP8) +- If set the specified codec will be preferred if available. ##### `iceServers` - type - [`RTCConfiguration.iceServers`](https://developer.mozilla.org/en-US/docs/Web/API/RTCConfiguration/iceServers) @@ -289,6 +294,7 @@ ovenLivekit.getUserMedia().then(function () { - String: String you want to append to a=fmtp of SDP. - If set video format is appended to the a=fmtp sections of SDP. + #### `instance.stopStreaming()` - Close peer connection and websocket associated with OvenMediaEngine. diff --git a/package-lock.json b/package-lock.json index 45f48dd..a7b214e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "ovenlivekit", - "version": "1.0.0", + "version": "1.0.5", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "ovenlivekit", - "version": "1.0.0", + "version": "1.0.5", "license": "MIT", "devDependencies": { "webpack": "^5.48.0", @@ -765,7 +765,6 @@ "anymatch": "^2.0.0", "async-each": "^1.0.1", "braces": "^2.3.2", - "fsevents": "^1.2.7", "glob-parent": "^3.1.0", "inherits": "^2.0.3", "is-binary-path": "^1.0.0", @@ -10102,4 +10101,4 @@ "dev": true } } -} +} \ No newline at end of file diff --git a/package.json b/package.json index 003fb64..6604ed5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ovenlivekit", - "version": "1.0.4", + "version": "1.0.5", "description": "OvenLiveKit for Web is an open source JavaScript SDK suite for live streaming from web browsers to OvenMediaEngine.", "main": "dist/OvenLiveKit.min.js", "scripts": { diff --git a/src/OvenLiveKit.js b/src/OvenLiveKit.js index 74b83e4..a2b0fd5 100644 --- a/src/OvenLiveKit.js +++ b/src/OvenLiveKit.js @@ -1,6 +1,6 @@ const OvenLiveKit = {}; -const version = '1.0.4'; +const version = '1.0.5'; const logHeader = 'OvenLiveKit.js :'; const logEventHeader = 'OvenLiveKit.js ===='; @@ -43,8 +43,9 @@ function getFormatNumber(sdp, format) { lines[i] = lines[i].toLowerCase(); - if (lines[i].indexOf('a=rtpmap') > -1 && lines[i].indexOf(format.toLowerCase()) > -1) { + if (lines[i].indexOf('a=rtpmap') === 0 && lines[i].indexOf(format.toLowerCase()) > -1) { // parsing "a=rtpmap:100 H264/90000" line + // a=rtpmap: /[/] formatNumber = lines[i].split(' ')[0].split(':')[1]; break; } @@ -53,6 +54,37 @@ function getFormatNumber(sdp, format) { return formatNumber; } +function setPreferredVideoFormat(sdp, formatName) { + + const formatNumber = getFormatNumber(sdp, formatName); + + if (formatNumber === -1) { + return sdp; + } + + let newLines = []; + const lines = sdp.split('\r\n'); + + for (let i = 0; i < lines.length - 1; i++) { + + const line = lines[i]; + + if (line.indexOf('m=video') === 0) { + + // m= / + const others = line.split(' ').slice(0, 3); + const formats = line.split(' ').slice(3); + formats.sort(function (x, y) { return x == formatNumber ? -1 : y == formatNumber ? 1 : 0; }); + newLines.push(others.concat(formats).join(' ')); + } else { + newLines.push(line); + } + + } + + return newLines.join('\r\n') + '\r\n'; +} + function removeFormat(sdp, formatNumber) { let newLines = []; let lines = sdp.split('\r\n'); @@ -570,7 +602,13 @@ function addMethod(instance) { offer.sdp = appendFmtp(offer.sdp); } + if (instance.connectionConfig.preferredVideoFormat) { + offer.sdp = setPreferredVideoFormat(offer.sdp, instance.connectionConfig.preferredVideoFormat) + } + + // offer.sdp = appendOrientation(offer.sdp); + console.info(logHeader, 'Modified offer sdp\n\n' + offer.sdp); peerConnection.setRemoteDescription(new RTCSessionDescription(offer)) .then(function () { @@ -583,6 +621,9 @@ function addMethod(instance) { answer.sdp = appendFmtp(answer.sdp); } + answer.sdp = setPreferredVideoFormat(answer.sdp, instance.connectionConfig.preferredVideoFormat) + console.info(logHeader, 'Modified answer sdp\n\n' + answer.sdp); + peerConnection.setLocalDescription(answer) .then(function () { @@ -738,7 +779,7 @@ function addMethod(instance) { instance.startStreaming = function (connectionUrl, connectionConfig) { - console.info(logEventHeader, 'Start Streaming'); + console.info(logEventHeader, 'Start Streaming with connectionConfig', connectionConfig); if (connectionConfig) {