ovenlivekit 1.1.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +50 -2
- package/dist/OvenLiveKit.min.js +1 -1
- package/dist/OvenLiveKit.min.js.map +1 -1
- package/package.json +4 -4
- package/src/OvenLiveKit.js +38 -0
package/README.md
CHANGED
|
@@ -42,7 +42,14 @@ const ovenLivekit = OvenLiveKit.create();
|
|
|
42
42
|
ovenLivekit.getUserMedia().then(function () {
|
|
43
43
|
|
|
44
44
|
// Got device stream and start streaming to OvenMediaEngine
|
|
45
|
-
ovenLivekit.startStreaming('wss://your_oven_media_engine:
|
|
45
|
+
ovenLivekit.startStreaming('wss://your_oven_media_engine:3334/app/stream?direction=send');
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
// Or you can get media stream of your display. Choose either user device or display.
|
|
49
|
+
ovenLivekit.getDisplayMedia().then(function () {
|
|
50
|
+
|
|
51
|
+
// Got device stream and start streaming to OvenMediaEngine
|
|
52
|
+
ovenLivekit.startStreaming('wss://your_oven_media_engine:3334/app/stream?direction=send');
|
|
46
53
|
});
|
|
47
54
|
```
|
|
48
55
|
### Quick demo
|
|
@@ -73,6 +80,8 @@ $ npm run start
|
|
|
73
80
|
- [`Media APIs`](#)
|
|
74
81
|
- `instance.attachMedia(videoElement)`
|
|
75
82
|
- `instance.getUserMedia()`
|
|
83
|
+
- `instance.getDisplayMedia()`
|
|
84
|
+
- `instance.setMediaStream(mediaStream)`
|
|
76
85
|
- [`Streaming APIs`](#)
|
|
77
86
|
- `instance.startStreaming()`
|
|
78
87
|
- `instance.stopStreaming()`
|
|
@@ -118,7 +127,7 @@ To make the library lightweight and easy to use, only callback options are imple
|
|
|
118
127
|
- parameters
|
|
119
128
|
- error: Various Type of Error
|
|
120
129
|
- A callback that receives any errors that occur in an instance of OvenLiveKit.
|
|
121
|
-
- Errors are could occur from `getUserMedia`, `webSocket`, or `peerConnection`.
|
|
130
|
+
- Errors are could occur from `getUserMedia`, `getDisplayMedia`, `webSocket`, or `peerConnection`.
|
|
122
131
|
|
|
123
132
|
##### `callbacks.connected`
|
|
124
133
|
- type
|
|
@@ -220,13 +229,31 @@ const ovenLivekit = OvenLiveKit.create();
|
|
|
220
229
|
// Attaching video element for playing device stream
|
|
221
230
|
ovenLivekit.attachMedia(document.getElementById('myVideo'));
|
|
222
231
|
|
|
232
|
+
const constraint = {
|
|
233
|
+
audio: true,
|
|
234
|
+
video: true
|
|
235
|
+
};
|
|
236
|
+
|
|
223
237
|
// Gets a device stream with a constraint that specifies the type of media to request.
|
|
224
238
|
ovenLivekit.getUserMedia(constraints).then(function (stream) {
|
|
225
239
|
|
|
226
240
|
// Got device stream. Ready for streaming.
|
|
241
|
+
ovenLivekit.startStreaming('wss://your_oven_media_engine:3334/app/stream?direction=send');
|
|
242
|
+
}).catch(function (error) {
|
|
243
|
+
|
|
244
|
+
// Failed to get device stream.
|
|
245
|
+
console.error("Error", error);
|
|
246
|
+
});
|
|
247
|
+
|
|
248
|
+
// Display media also works in the same way.
|
|
249
|
+
ovenLivekit.getDisplayMedia(constraints).then(function (stream) {
|
|
250
|
+
|
|
251
|
+
// Got device stream. Ready for streaming.
|
|
252
|
+
ovenLivekit.startStreaming('wss://your_oven_media_engine:3334/app/stream?direction=send');
|
|
227
253
|
}).catch(function (error) {
|
|
228
254
|
|
|
229
255
|
// Failed to get device stream.
|
|
256
|
+
console.error("Error", error);
|
|
230
257
|
});
|
|
231
258
|
```
|
|
232
259
|
#### `instance.attachMedia(videoElement)`
|
|
@@ -246,6 +273,27 @@ ovenLivekit.getUserMedia(constraints).then(function (stream) {
|
|
|
246
273
|
- This API is the most important API in OvenLiveKit. Make the OvenLiveKit streamable by getting the media stream from the user input device. You can get the media stream from any user input device you want using the `constraints` parameter. The device ID to be used in the `constraints` parameter can also be obtained from `OvenLiveKit.getDevices()`.
|
|
247
274
|
- For natural behavior, you can have the browser automatically select the device stream without passing a `constraints` parameter. However, if you want to control the device stream strictly (e.g., specify input devices, video resolution, video frame rates), you can control it by passing the constraints parameter.
|
|
248
275
|
|
|
276
|
+
#### `instance.getDisplayMedia(constraints)`
|
|
277
|
+
- parameters
|
|
278
|
+
- constraints: [MediaStreamConstraints](https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getDisplayMedia#parameters)
|
|
279
|
+
- returns Promise
|
|
280
|
+
- resolved
|
|
281
|
+
- stream: [MediaStream](https://developer.mozilla.org/en-US/docs/Web/API/MediaStream). You can use this stream for whatever you need.
|
|
282
|
+
- rejected
|
|
283
|
+
- error: Throws error while getting the stream from the display.
|
|
284
|
+
- Captures the entire screen, application window, or browser tab.
|
|
285
|
+
|
|
286
|
+
#### `instance.setMediaStream(stream)`
|
|
287
|
+
- parameters
|
|
288
|
+
- stream: [MediaStream](https://developer.mozilla.org/en-US/docs/Web/API/MediaStream) - The valid MediaStream you want OvenLiveKit to utilize.
|
|
289
|
+
- returns Promise
|
|
290
|
+
- resolved
|
|
291
|
+
- stream: [MediaStream](https://developer.mozilla.org/en-US/docs/Web/API/MediaStream) - Returns the same stream provided as an input, confirming its successful attachment.
|
|
292
|
+
- rejected
|
|
293
|
+
- error: Throws an error if an invalid MediaStream is provided.
|
|
294
|
+
- The `setMediaStream` function is designed to let developers directly attach an external or pre-existing MediaStream. This can be particularly useful when you're sourcing the stream not directly from user input devices, but other origins.
|
|
295
|
+
|
|
296
|
+
|
|
249
297
|
### Streaming APIs
|
|
250
298
|
Congrats on getting the media stream from the user device and then ready to stream into OvenMediaEngine.
|
|
251
299
|
```JavaScript
|
package/dist/OvenLiveKit.min.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
!function(e,n){"object"==typeof exports&&"object"==typeof module?module.exports=n():"function"==typeof define&&define.amd?define([],n):"object"==typeof exports?exports.OvenLiveKit=n():e.OvenLiveKit=n()}(self,(function(){return(()=>{"use strict";var e={d:(n,o)=>{for(var t in o)e.o(o,t)&&!e.o(n,t)&&Object.defineProperty(n,t,{enumerable:!0,get:o[t]})},o:(e,n)=>Object.prototype.hasOwnProperty.call(e,n)},n={};e.d(n,{default:()=>u});const o={},t="OvenLiveKit.js :",i="OvenLiveKit.js ====";function c(e,n){e&&e.send(JSON.stringify(n))}function r(e){let n,o="";return(n=e.match(/^(?:wss?:\/\/)?(?:[^@\n]+@)?(?:www\.)?([^:\/\n\?\=]+)/im))&&(o=n[1]),o}function a(e){let n,o="";return(n=e.match(new RegExp("\\b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\b","gi")))&&(o=n[0]),o}function l(e,n){const o=function(e,n){const o=e.split("\r\n");let t=-1;for(let e=0;e<o.length-1;e++)if(o[e]=o[e].toLowerCase(),0===o[e].indexOf("a=rtpmap")&&o[e].indexOf(n.toLowerCase())>-1){t=o[e].split(" ")[0].split(":")[1];break}return t}(e,n);if(-1===o)return e;let t=[];const i=e.split("\r\n");for(let e=0;e<i.length-1;e++){const n=i[e];if(0===n.indexOf("m=video")){const e=n.split(" ").slice(0,3),i=n.split(" ").slice(3);i.sort((function(e,n){return e==o?-1:n==o?1:0})),t.push(e.concat(i).join(" "))}else t.push(n)}return t.join("\r\n")+"\r\n"}async function s(e){const n={};return"both"===e?(n.audio=!0,n.video=!0):"audio"===e?n.audio=!0:"video"===e&&(n.video=!0),await navigator.mediaDevices.getUserMedia(n)}function d(e){function n(n){e.callbacks.error&&e.callbacks.error(n)}function o(n){const o=e.connectionConfig.sdp.appendFmtp,t=n.split("\r\n"),i=[];for(let e=0;e<t.length;e++)if(0===t[e].indexOf("m=video")){let n=t[e].split(" ");for(let e=3;e<n.length;e++)i.push(n[e]);break}for(let e=0;e<i.length;e++){let n=!1;for(let c=0;c<t.length;c++)0===t[c].indexOf("a=fmtp:"+i[e])&&(n=!0,t[c]+=";"+o);if(!n)for(let n=0;n<t.length;n++)0===t[n].indexOf("a=rtpmap:"+i[e])&&(t[n]+="\r\na=fmtp:"+i[e]+" "+o)}return t.join("\r\n")}function s(){e.peerConnection&&(e.peerConnection.getSenders().forEach((function(n){e.peerConnection.removeTrack(n)})),e.peerConnection.close(),e.peerConnection=null,delete e.peerConnection)}function d(){e.webSocket&&(e.webSocket.close(),e.webSocket=null,delete e.webSocket)}e.attachMedia=function(n){e.videoElement=n},e.getUserMedia=function(o){return function(o){return o||(o={video:{deviceId:void 0},audio:{deviceId:void 0}}),console.info(t,"Request Stream To Input Devices With Constraints",o),navigator.mediaDevices.getUserMedia(o).then((function(n){console.info(t,"Received Media Stream From Input Device",n),e.inputStream=n;let o=e.videoElement;return o&&(o.srcObject=n,o.onloadedmetadata=function(e){o.play()}),new Promise((function(e){e(n)}))})).catch((function(e){return console.error(t,"Can't Get Media Stream From Input Device",e),n(e),new Promise((function(n,o){o(e)}))}))}(o)},e.getDisplayMedia=function(o){return function(o){return o||(o={}),console.info(t,"Request Stream To Display With Constraints",o),navigator.mediaDevices.getDisplayMedia(o).then((function(n){console.info(t,"Received Media Stream From Display",n),e.inputStream=n;let o=e.videoElement;return o&&(o.srcObject=n,o.onloadedmetadata=function(e){o.play()}),new Promise((function(e){e(n)}))})).catch((function(e){return console.error(t,"Can't Get Media Stream From Display",e),n(e),new Promise((function(n,o){o(e)}))}))}(o)},e.startStreaming=function(s,d){console.info(i,"Start Streaming with connectionConfig",d),d&&(e.connectionConfig=d),function(i){if(!i)return void n("connectionUrl is required");e.connectionUrl=i;let s=null;try{s=new WebSocket(i)}catch(e){n(e)}e.webSocket=s,s.onopen=function(){c(s,{command:"request_offer"})},s.onmessage=function(i){let s=JSON.parse(i.data);s.error&&(console.error("webSocket.onmessage",s.error),n(s.error)),"offer"===s.command&&function(i,s,d,u,f){let p={};if(e.connectionConfig.iceServers)p.iceServers=e.connectionConfig.iceServers,e.connectionConfig.iceTransportPolicy&&(p.iceTransportPolicy=e.connectionConfig.iceTransportPolicy);else if(f){p.iceServers=[];for(let n=0;n<f.length;n++){let o=f[n],t={};t.urls=o.urls;let i=!1,c=r(e.connectionUrl);for(let e=0;e<t.urls.length;e++)if(t.urls[e].indexOf(c)>-1){i=!0;break}if(!i&&t.urls.length>0){let e=t.urls[0],n=a(e);c&&n&&t.urls.push(e.replace(n,c))}t.username=o.user_name,t.credential=o.credential,p.iceServers.push(t)}p.iceTransportPolicy="relay"}else e.iceTransportPolicy&&(p.iceTransportPolicy=e.iceTransportPolicy);console.info(t,"Create Peer Connection With Config",p);let m=new RTCPeerConnection(p);e.peerConnection=m,e.inputStream.getTracks().forEach((function(n){console.info(t,"Add Track To Peer Connection",n),m.addTrack(n,e.inputStream)})),e.connectionConfig.maxVideoBitrate&&(d.sdp=function(e,n,o){let t=e.split("\r\n"),i=-1;for(let e=0;e<t.length;e++)if(0===t[e].indexOf("m=video")){i=e;break}if(-1===i)return e;for(i++;0===t[i].indexOf("i=")||0===t[i].indexOf("c=");)i++;if(0===t[i].indexOf("b"))return t[i]="b=AS:"+o,t.join("\r\n");let c=t.slice(0,i);return c.push("b=AS:"+o),c=c.concat(t.slice(i,t.length)),c.join("\r\n")}(d.sdp,0,e.connectionConfig.maxVideoBitrate)),e.connectionConfig.sdp&&e.connectionConfig.sdp.appendFmtp&&(d.sdp=o(d.sdp)),e.connectionConfig.preferredVideoFormat&&(d.sdp=l(d.sdp,e.connectionConfig.preferredVideoFormat)),console.info(t,"Modified offer sdp\n\n"+d.sdp),m.setRemoteDescription(new RTCSessionDescription(d)).then((function(){m.createAnswer().then((function(r){e.connectionConfig.sdp&&e.connectionConfig.sdp.appendFmtp&&(r.sdp=o(r.sdp)),e.connectionConfig.preferredVideoFormat&&(r.sdp=l(r.sdp,e.connectionConfig.preferredVideoFormat)),console.info(t,"Modified answer sdp\n\n"+r.sdp),m.setLocalDescription(r).then((function(){c(e.webSocket,{id:i,peer_id:s,command:"answer",sdp:r})})).catch((function(e){console.error("peerConnection.setLocalDescription",e),n(e)}))})).catch((function(e){console.error("peerConnection.createAnswer",e),n(e)}))})).catch((function(e){console.error("peerConnection.setRemoteDescription",e),n(e)})),u&&function(e,o){for(let t=0;t<o.length;t++)if(o[t]&&o[t].candidate){let i=o[t];e.addIceCandidate(new RTCIceCandidate(i)).then((function(){})).catch((function(e){console.error("peerConnection.addIceCandidate",e),n(e)}))}}(m,u),m.onicecandidate=function(n){n.candidate&&n.candidate.candidate&&c(e.webSocket,{id:i,peer_id:s,command:"candidate",candidates:[n.candidate]})},m.oniceconnectionstatechange=function(n){let o=m.iceConnectionState;e.callbacks.iceStateChange&&(console.info(t,"ICE State","["+o+"]"),e.callbacks.iceStateChange(o)),"connected"===o&&e.callbacks.connected&&e.callbacks.connected(n),"failed"!==o&&"disconnected"!==o&&"closed"!==o||e.callbacks.connectionClosed&&(console.error(t,"Iceconnection Closed",n),e.callbacks.connectionClosed("ice",n))}}(s.id,s.peer_id,s.sdp,s.candidates,s.ice_servers)},s.onerror=function(e){console.error("webSocket.onerror",e),n(e)},s.onclose=function(n){e.webSocketClosedByUser||e.callbacks.connectionClosed&&e.callbacks.connectionClosed("websocket",n)}}(s)},e.stopStreaming=function(){e.webSocketClosedByUser=!0,d(),s()},e.remove=function(){e.webSocketClosedByUser=!0,d(),s(),e.inputStream&&(e.inputStream.getTracks().forEach((n=>{n.stop(),e.inputStream.removeTrack(n)})),e.videoElement&&(e.videoElement.srcObject=null),e.inputStream=null,delete e.inputStream),console.info(i,"Removed")}}o.getVersion=function(){return"1.1.0"},o.create=function(e){console.info(i,"Create WebRTC Input 1.1.0");let n={webSocketClosedByUser:!1};return function(e,n){e.inputStream=null,e.webSocket=null,e.peerConnection=null,e.connectionConfig={},e.videoElement=null,e.connectionUrl=null,n&&n.callbacks?e.callbacks=n.callbacks:e.callbacks={}}(n,e),d(n),n},o.getDevices=async function(){try{await s("both")}catch(e){console.warn(t,"Can not find Video and Audio devices",e);let n=null,o=null;try{n=await s("video")}catch(e){console.warn(t,"Can not find Video devices",e)}try{o=await s("audio")}catch(e){console.warn(t,"Can not find Audio devices",e)}if(!n&&!o)throw new Error("No input devices were found.")}return function(e){let n={audioinput:[],audiooutput:[],videoinput:[],other:[]};for(let o=0;o!==e.length;++o){const t=e[o];let i={};i.deviceId=t.deviceId,"audioinput"===t.kind?(i.label=t.label||`microphone ${n.audioinput.length+1}`,n.audioinput.push(i)):"audiooutput"===t.kind?(i.label=t.label||`speaker ${n.audiooutput.length+1}`,n.audiooutput.push(i)):"videoinput"===t.kind?(i.label=t.label||`camera ${n.videoinput.length+1}`,n.videoinput.push(i)):(i.label=t.label||`other ${n.other.length+1}`,n.other.push(i))}return n}(await async function(){return await navigator.mediaDevices.enumerateDevices()}())};const u=o;return n.default})()}));
|
|
1
|
+
!function(e,n){"object"==typeof exports&&"object"==typeof module?module.exports=n():"function"==typeof define&&define.amd?define([],n):"object"==typeof exports?exports.OvenLiveKit=n():e.OvenLiveKit=n()}(self,(function(){return(()=>{"use strict";var e={d:(n,o)=>{for(var t in o)e.o(o,t)&&!e.o(n,t)&&Object.defineProperty(n,t,{enumerable:!0,get:o[t]})},o:(e,n)=>Object.prototype.hasOwnProperty.call(e,n)},n={};e.d(n,{default:()=>u});const o={},t="OvenLiveKit.js :",i="OvenLiveKit.js ====";function c(e,n){e&&e.send(JSON.stringify(n))}function r(e){let n,o="";return(n=e.match(/^(?:wss?:\/\/)?(?:[^@\n]+@)?(?:www\.)?([^:\/\n\?\=]+)/im))&&(o=n[1]),o}function a(e){let n,o="";return(n=e.match(new RegExp("\\b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\b","gi")))&&(o=n[0]),o}function l(e,n){const o=function(e,n){const o=e.split("\r\n");let t=-1;for(let e=0;e<o.length-1;e++)if(o[e]=o[e].toLowerCase(),0===o[e].indexOf("a=rtpmap")&&o[e].indexOf(n.toLowerCase())>-1){t=o[e].split(" ")[0].split(":")[1];break}return t}(e,n);if(-1===o)return e;let t=[];const i=e.split("\r\n");for(let e=0;e<i.length-1;e++){const n=i[e];if(0===n.indexOf("m=video")){const e=n.split(" ").slice(0,3),i=n.split(" ").slice(3);i.sort((function(e,n){return e==o?-1:n==o?1:0})),t.push(e.concat(i).join(" "))}else t.push(n)}return t.join("\r\n")+"\r\n"}async function s(e){const n={};return"both"===e?(n.audio=!0,n.video=!0):"audio"===e?n.audio=!0:"video"===e&&(n.video=!0),await navigator.mediaDevices.getUserMedia(n)}function d(e){function n(n){e.callbacks.error&&e.callbacks.error(n)}function o(n){const o=e.connectionConfig.sdp.appendFmtp,t=n.split("\r\n"),i=[];for(let e=0;e<t.length;e++)if(0===t[e].indexOf("m=video")){let n=t[e].split(" ");for(let e=3;e<n.length;e++)i.push(n[e]);break}for(let e=0;e<i.length;e++){let n=!1;for(let c=0;c<t.length;c++)0===t[c].indexOf("a=fmtp:"+i[e])&&(n=!0,t[c]+=";"+o);if(!n)for(let n=0;n<t.length;n++)0===t[n].indexOf("a=rtpmap:"+i[e])&&(t[n]+="\r\na=fmtp:"+i[e]+" "+o)}return t.join("\r\n")}function s(){e.peerConnection&&(e.peerConnection.getSenders().forEach((function(n){e.peerConnection.removeTrack(n)})),e.peerConnection.close(),e.peerConnection=null,delete e.peerConnection)}function d(){e.webSocket&&(e.webSocket.close(),e.webSocket=null,delete e.webSocket)}e.attachMedia=function(n){e.videoElement=n},e.getUserMedia=function(o){return function(o){return o||(o={video:{deviceId:void 0},audio:{deviceId:void 0}}),console.info(t,"Request Stream To Input Devices With Constraints",o),navigator.mediaDevices.getUserMedia(o).then((function(n){console.info(t,"Received Media Stream From Input Device",n),e.inputStream=n;let o=e.videoElement;return o&&(o.srcObject=n,o.onloadedmetadata=function(e){o.play()}),new Promise((function(e){e(n)}))})).catch((function(e){return console.error(t,"Can't Get Media Stream From Input Device",e),n(e),new Promise((function(n,o){o(e)}))}))}(o)},e.getDisplayMedia=function(o){return function(o){return o||(o={}),console.info(t,"Request Stream To Display With Constraints",o),navigator.mediaDevices.getDisplayMedia(o).then((function(n){console.info(t,"Received Media Stream From Display",n),e.inputStream=n;let o=e.videoElement;return o&&(o.srcObject=n,o.onloadedmetadata=function(e){o.play()}),new Promise((function(e){e(n)}))})).catch((function(e){return console.error(t,"Can't Get Media Stream From Display",e),n(e),new Promise((function(n,o){o(e)}))}))}(o)},e.setMediaStream=function(o){return function(o){if(!(o&&o instanceof MediaStream)){const e=new Error("Invalid MediaStream provided");return console.error(t,"Invalid MediaStream",e),n(e),new Promise((function(n,o){o(e)}))}console.info(t,"Received Media Stream",o),e.inputStream=o;let i=e.videoElement;return i&&(i.srcObject=o,i.onloadedmetadata=function(e){i.play()}),new Promise((function(e){e(o)}))}(o)},e.startStreaming=function(s,d){console.info(i,"Start Streaming with connectionConfig",d),d&&(e.connectionConfig=d),function(i){if(!i)return void n("connectionUrl is required");e.connectionUrl=i;let s=null;try{s=new WebSocket(i)}catch(e){n(e)}e.webSocket=s,s.onopen=function(){c(s,{command:"request_offer"})},s.onmessage=function(i){let s=JSON.parse(i.data);s.error&&(console.error("webSocket.onmessage",s.error),n(s.error)),"offer"===s.command&&function(i,s,d,u,f){let p={};if(e.connectionConfig.iceServers)p.iceServers=e.connectionConfig.iceServers,e.connectionConfig.iceTransportPolicy&&(p.iceTransportPolicy=e.connectionConfig.iceTransportPolicy);else if(f){p.iceServers=[];for(let n=0;n<f.length;n++){let o=f[n],t={};t.urls=o.urls;let i=!1,c=r(e.connectionUrl);for(let e=0;e<t.urls.length;e++)if(t.urls[e].indexOf(c)>-1){i=!0;break}if(!i&&t.urls.length>0){let e=t.urls[0],n=a(e);c&&n&&t.urls.push(e.replace(n,c))}t.username=o.user_name,t.credential=o.credential,p.iceServers.push(t)}p.iceTransportPolicy="relay"}else e.iceTransportPolicy&&(p.iceTransportPolicy=e.iceTransportPolicy);console.info(t,"Create Peer Connection With Config",p);let m=new RTCPeerConnection(p);e.peerConnection=m,e.inputStream.getTracks().forEach((function(n){console.info(t,"Add Track To Peer Connection",n),m.addTrack(n,e.inputStream)})),e.connectionConfig.maxVideoBitrate&&(d.sdp=function(e,n,o){let t=e.split("\r\n"),i=-1;for(let e=0;e<t.length;e++)if(0===t[e].indexOf("m=video")){i=e;break}if(-1===i)return e;for(i++;0===t[i].indexOf("i=")||0===t[i].indexOf("c=");)i++;if(0===t[i].indexOf("b"))return t[i]="b=AS:"+o,t.join("\r\n");let c=t.slice(0,i);return c.push("b=AS:"+o),c=c.concat(t.slice(i,t.length)),c.join("\r\n")}(d.sdp,0,e.connectionConfig.maxVideoBitrate)),e.connectionConfig.sdp&&e.connectionConfig.sdp.appendFmtp&&(d.sdp=o(d.sdp)),e.connectionConfig.preferredVideoFormat&&(d.sdp=l(d.sdp,e.connectionConfig.preferredVideoFormat)),console.info(t,"Modified offer sdp\n\n"+d.sdp),m.setRemoteDescription(new RTCSessionDescription(d)).then((function(){m.createAnswer().then((function(r){e.connectionConfig.sdp&&e.connectionConfig.sdp.appendFmtp&&(r.sdp=o(r.sdp)),e.connectionConfig.preferredVideoFormat&&(r.sdp=l(r.sdp,e.connectionConfig.preferredVideoFormat)),console.info(t,"Modified answer sdp\n\n"+r.sdp),m.setLocalDescription(r).then((function(){c(e.webSocket,{id:i,peer_id:s,command:"answer",sdp:r})})).catch((function(e){console.error("peerConnection.setLocalDescription",e),n(e)}))})).catch((function(e){console.error("peerConnection.createAnswer",e),n(e)}))})).catch((function(e){console.error("peerConnection.setRemoteDescription",e),n(e)})),u&&function(e,o){for(let t=0;t<o.length;t++)if(o[t]&&o[t].candidate){let i=o[t];e.addIceCandidate(new RTCIceCandidate(i)).then((function(){})).catch((function(e){console.error("peerConnection.addIceCandidate",e),n(e)}))}}(m,u),m.onicecandidate=function(n){n.candidate&&n.candidate.candidate&&c(e.webSocket,{id:i,peer_id:s,command:"candidate",candidates:[n.candidate]})},m.oniceconnectionstatechange=function(n){let o=m.iceConnectionState;e.callbacks.iceStateChange&&(console.info(t,"ICE State","["+o+"]"),e.callbacks.iceStateChange(o)),"connected"===o&&e.callbacks.connected&&e.callbacks.connected(n),"failed"!==o&&"disconnected"!==o&&"closed"!==o||e.callbacks.connectionClosed&&(console.error(t,"Iceconnection Closed",n),e.callbacks.connectionClosed("ice",n))}}(s.id,s.peer_id,s.sdp,s.candidates,s.ice_servers)},s.onerror=function(e){console.error("webSocket.onerror",e),n(e)},s.onclose=function(n){e.webSocketClosedByUser||e.callbacks.connectionClosed&&e.callbacks.connectionClosed("websocket",n)}}(s)},e.stopStreaming=function(){e.webSocketClosedByUser=!0,d(),s()},e.remove=function(){e.webSocketClosedByUser=!0,d(),s(),e.inputStream&&(e.inputStream.getTracks().forEach((n=>{n.stop(),e.inputStream.removeTrack(n)})),e.videoElement&&(e.videoElement.srcObject=null),e.inputStream=null,delete e.inputStream),console.info(i,"Removed")}}o.getVersion=function(){return"1.1.0"},o.create=function(e){console.info(i,"Create WebRTC Input 1.1.0");let n={webSocketClosedByUser:!1};return function(e,n){e.inputStream=null,e.webSocket=null,e.peerConnection=null,e.connectionConfig={},e.videoElement=null,e.connectionUrl=null,n&&n.callbacks?e.callbacks=n.callbacks:e.callbacks={}}(n,e),d(n),n},o.getDevices=async function(){try{await s("both")}catch(e){console.warn(t,"Can not find Video and Audio devices",e);let n=null,o=null;try{n=await s("video")}catch(e){console.warn(t,"Can not find Video devices",e)}try{o=await s("audio")}catch(e){console.warn(t,"Can not find Audio devices",e)}if(!n&&!o)throw new Error("No input devices were found.")}return function(e){let n={audioinput:[],audiooutput:[],videoinput:[],other:[]};for(let o=0;o!==e.length;++o){const t=e[o];let i={};i.deviceId=t.deviceId,"audioinput"===t.kind?(i.label=t.label||`microphone ${n.audioinput.length+1}`,n.audioinput.push(i)):"audiooutput"===t.kind?(i.label=t.label||`speaker ${n.audiooutput.length+1}`,n.audiooutput.push(i)):"videoinput"===t.kind?(i.label=t.label||`camera ${n.videoinput.length+1}`,n.videoinput.push(i)):(i.label=t.label||`other ${n.other.length+1}`,n.other.push(i))}return n}(await async function(){return await navigator.mediaDevices.enumerateDevices()}())};const u=o;return n.default})()}));
|
|
2
2
|
//# sourceMappingURL=OvenLiveKit.min.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OvenLiveKit.min.js","mappings":"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","sources":["webpack://OvenLiveKit/webpack/universalModuleDefinition","webpack://OvenLiveKit/webpack/bootstrap","webpack://OvenLiveKit/webpack/runtime/define property getters","webpack://OvenLiveKit/webpack/runtime/hasOwnProperty shorthand","webpack://OvenLiveKit/./src/OvenLiveKit.js"],"sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"OvenLiveKit\"] = factory();\n\telse\n\t\troot[\"OvenLiveKit\"] = factory();\n})(self, function() {\nreturn ","// The require scope\nvar __webpack_require__ = {};\n\n","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","const OvenLiveKit = {};\r\n\r\nconst version = '1.1.0';\r\nconst logHeader = 'OvenLiveKit.js :';\r\nconst logEventHeader = 'OvenLiveKit.js ====';\r\n\r\n// private methods\r\nfunction sendMessage(webSocket, message) {\r\n\r\n if (webSocket) {\r\n webSocket.send(JSON.stringify(message));\r\n }\r\n}\r\n\r\nfunction generateDomainFromUrl(url) {\r\n let result = '';\r\n let match;\r\n if (match = url.match(/^(?:wss?:\\/\\/)?(?:[^@\\n]+@)?(?:www\\.)?([^:\\/\\n\\?\\=]+)/im)) {\r\n result = match[1];\r\n }\r\n\r\n return result;\r\n}\r\n\r\nfunction findIp(string) {\r\n\r\n let result = '';\r\n let match;\r\n\r\n if (match = string.match(new RegExp('\\\\b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\\\b', 'gi'))) {\r\n result = match[0];\r\n }\r\n\r\n return result;\r\n}\r\n\r\nfunction getFormatNumber(sdp, format) {\r\n\r\n const lines = sdp.split('\\r\\n');\r\n let formatNumber = -1;\r\n\r\n for (let i = 0; i < lines.length - 1; i++) {\r\n\r\n lines[i] = lines[i].toLowerCase();\r\n\r\n if (lines[i].indexOf('a=rtpmap') === 0 && lines[i].indexOf(format.toLowerCase()) > -1) {\r\n // parsing \"a=rtpmap:100 H264/90000\" line\r\n // a=rtpmap:<payload type> <encoding name>/<clock rate>[/<encoding parameters >]\r\n formatNumber = lines[i].split(' ')[0].split(':')[1];\r\n break;\r\n }\r\n }\r\n\r\n return formatNumber;\r\n}\r\n\r\nfunction setPreferredVideoFormat(sdp, formatName) {\r\n\r\n const formatNumber = getFormatNumber(sdp, formatName);\r\n\r\n if (formatNumber === -1) {\r\n return sdp;\r\n }\r\n\r\n let newLines = [];\r\n const lines = sdp.split('\\r\\n');\r\n\r\n for (let i = 0; i < lines.length - 1; i++) {\r\n\r\n const line = lines[i];\r\n\r\n if (line.indexOf('m=video') === 0) {\r\n\r\n // m=<media> <port>/<number of ports> <transport> <fmt list>\r\n const others = line.split(' ').slice(0, 3);\r\n const formats = line.split(' ').slice(3);\r\n formats.sort(function (x, y) { return x == formatNumber ? -1 : y == formatNumber ? 1 : 0; });\r\n newLines.push(others.concat(formats).join(' '));\r\n } else {\r\n newLines.push(line);\r\n }\r\n\r\n }\r\n\r\n return newLines.join('\\r\\n') + '\\r\\n';\r\n}\r\n\r\nfunction removeFormat(sdp, formatNumber) {\r\n let newLines = [];\r\n let lines = sdp.split('\\r\\n');\r\n\r\n for (let i = 0; i < lines.length; i++) {\r\n\r\n if (lines[i].indexOf('m=video') === 0) {\r\n newLines.push(lines[i].replace(' ' + formatNumber + '', ''));\r\n } else if (lines[i].indexOf(formatNumber + '') > -1) {\r\n\r\n } else {\r\n newLines.push(lines[i]);\r\n }\r\n }\r\n\r\n return newLines.join('\\r\\n')\r\n}\r\n\r\nasync function getStreamForDeviceCheck(type) {\r\n\r\n // High resolution video constraints makes browser to get maximum resolution of video device.\r\n const constraints = {\r\n };\r\n\r\n if (type === 'both') {\r\n constraints.audio = true;\r\n constraints.video = true;\r\n } else if (type === 'audio') {\r\n constraints.audio = true;\r\n } else if (type === 'video') {\r\n constraints.video = true;\r\n }\r\n\r\n return await navigator.mediaDevices.getUserMedia(constraints);\r\n}\r\n\r\nasync function getDevices() {\r\n\r\n return await navigator.mediaDevices.enumerateDevices();\r\n}\r\n\r\nfunction gotDevices(deviceInfos) {\r\n\r\n let devices = {\r\n 'audioinput': [],\r\n 'audiooutput': [],\r\n 'videoinput': [],\r\n 'other': [],\r\n };\r\n\r\n for (let i = 0; i !== deviceInfos.length; ++i) {\r\n\r\n const deviceInfo = deviceInfos[i];\r\n\r\n let info = {};\r\n\r\n info.deviceId = deviceInfo.deviceId;\r\n\r\n if (deviceInfo.kind === 'audioinput') {\r\n\r\n info.label = deviceInfo.label || `microphone ${devices.audioinput.length + 1}`;\r\n devices.audioinput.push(info);\r\n } else if (deviceInfo.kind === 'audiooutput') {\r\n\r\n info.label = deviceInfo.label || `speaker ${devices.audiooutput.length + 1}`;\r\n devices.audiooutput.push(info);\r\n } else if (deviceInfo.kind === 'videoinput') {\r\n\r\n info.label = deviceInfo.label || `camera ${devices.videoinput.length + 1}`;\r\n devices.videoinput.push(info);\r\n } else {\r\n\r\n info.label = deviceInfo.label || `other ${devices.other.length + 1}`;\r\n devices.other.push(info);\r\n }\r\n }\r\n\r\n return devices;\r\n}\r\n\r\nfunction initConfig(instance, options) {\r\n\r\n instance.inputStream = null;\r\n instance.webSocket = null;\r\n instance.peerConnection = null;\r\n instance.connectionConfig = {};\r\n\r\n instance.videoElement = null;\r\n instance.connectionUrl = null;\r\n\r\n if (options && options.callbacks) {\r\n\r\n instance.callbacks = options.callbacks;\r\n } else {\r\n instance.callbacks = {};\r\n }\r\n}\r\n\r\nfunction addMethod(instance) {\r\n\r\n function errorHandler(error) {\r\n\r\n if (instance.callbacks.error) {\r\n\r\n instance.callbacks.error(error);\r\n }\r\n }\r\n\r\n function getUserMedia(constraints) {\r\n\r\n if (!constraints) {\r\n\r\n constraints = {\r\n video: {\r\n deviceId: undefined\r\n },\r\n audio: {\r\n deviceId: undefined\r\n }\r\n };\r\n }\r\n\r\n console.info(logHeader, 'Request Stream To Input Devices With Constraints', constraints);\r\n\r\n return navigator.mediaDevices.getUserMedia(constraints)\r\n .then(function (stream) {\r\n\r\n console.info(logHeader, 'Received Media Stream From Input Device', stream);\r\n\r\n instance.inputStream = stream;\r\n\r\n let elem = instance.videoElement;\r\n\r\n // Attach stream to video element when video element is provided.\r\n if (elem) {\r\n\r\n elem.srcObject = stream;\r\n\r\n elem.onloadedmetadata = function (e) {\r\n\r\n elem.play();\r\n };\r\n }\r\n\r\n return new Promise(function (resolve) {\r\n\r\n resolve(stream);\r\n });\r\n })\r\n .catch(function (error) {\r\n\r\n console.error(logHeader, 'Can\\'t Get Media Stream From Input Device', error);\r\n errorHandler(error);\r\n\r\n return new Promise(function (resolve, reject) {\r\n reject(error);\r\n });\r\n });\r\n }\r\n\r\n function getDisplayMedia(constraints) {\r\n\r\n if (!constraints) {\r\n constraints = {};\r\n }\r\n\r\n console.info(logHeader, 'Request Stream To Display With Constraints', constraints);\r\n\r\n return navigator.mediaDevices.getDisplayMedia(constraints)\r\n .then(function (stream) {\r\n\r\n console.info(logHeader, 'Received Media Stream From Display', stream);\r\n\r\n instance.inputStream = stream;\r\n\r\n let elem = instance.videoElement;\r\n\r\n // Attach stream to video element when video element is provided.\r\n if (elem) {\r\n\r\n elem.srcObject = stream;\r\n\r\n elem.onloadedmetadata = function (e) {\r\n\r\n elem.play();\r\n };\r\n }\r\n\r\n return new Promise(function (resolve) {\r\n\r\n resolve(stream);\r\n });\r\n })\r\n .catch(function (error) {\r\n\r\n console.error(logHeader, 'Can\\'t Get Media Stream From Display', error);\r\n errorHandler(error);\r\n\r\n return new Promise(function (resolve, reject) {\r\n reject(error);\r\n });\r\n });\r\n }\r\n\r\n // From https://webrtchacks.com/limit-webrtc-bandwidth-sdp/\r\n function setBitrateLimit(sdp, media, bitrate) {\r\n\r\n let lines = sdp.split('\\r\\n');\r\n let line = -1;\r\n\r\n for (let i = 0; i < lines.length; i++) {\r\n if (lines[i].indexOf('m=' + media) === 0) {\r\n line = i;\r\n break;\r\n }\r\n }\r\n if (line === -1) {\r\n // Could not find the m line for media\r\n return sdp;\r\n }\r\n\r\n // Pass the m line\r\n line++;\r\n\r\n // Skip i and c lines\r\n while (lines[line].indexOf('i=') === 0 || lines[line].indexOf('c=') === 0) {\r\n\r\n line++;\r\n }\r\n\r\n // If we're on a b line, replace it\r\n if (lines[line].indexOf('b') === 0) {\r\n\r\n lines[line] = 'b=AS:' + bitrate;\r\n\r\n return lines.join('\\r\\n');\r\n }\r\n\r\n // Add a new b line\r\n let newLines = lines.slice(0, line)\r\n\r\n newLines.push('b=AS:' + bitrate)\r\n newLines = newLines.concat(lines.slice(line, lines.length))\r\n\r\n return newLines.join('\\r\\n')\r\n }\r\n\r\n function initWebSocket(connectionUrl) {\r\n\r\n if (!connectionUrl) {\r\n errorHandler('connectionUrl is required');\r\n return;\r\n }\r\n\r\n instance.connectionUrl = connectionUrl;\r\n\r\n let webSocket = null;\r\n\r\n try {\r\n\r\n webSocket = new WebSocket(connectionUrl);\r\n } catch (error) {\r\n\r\n errorHandler(error);\r\n }\r\n\r\n\r\n instance.webSocket = webSocket;\r\n\r\n webSocket.onopen = function () {\r\n\r\n // Request offer at the first time.\r\n sendMessage(webSocket, {\r\n command: 'request_offer'\r\n });\r\n };\r\n\r\n webSocket.onmessage = function (e) {\r\n\r\n let message = JSON.parse(e.data);\r\n\r\n if (message.error) {\r\n console.error('webSocket.onmessage', message.error);\r\n errorHandler(message.error);\r\n }\r\n\r\n if (message.command === 'offer') {\r\n\r\n // OME returns offer. Start create peer connection.\r\n createPeerConnection(\r\n message.id,\r\n message.peer_id,\r\n message.sdp,\r\n message.candidates,\r\n message.ice_servers\r\n );\r\n }\r\n };\r\n\r\n webSocket.onerror = function (error) {\r\n\r\n console.error('webSocket.onerror', error);\r\n errorHandler(error);\r\n };\r\n\r\n webSocket.onclose = function (e) {\r\n\r\n if (!instance.webSocketClosedByUser) {\r\n\r\n if (instance.callbacks.connectionClosed) {\r\n instance.callbacks.connectionClosed('websocket', e);\r\n }\r\n }\r\n };\r\n\r\n }\r\n\r\n function appendFmtp(sdp) {\r\n\r\n const fmtpStr = instance.connectionConfig.sdp.appendFmtp;\r\n\r\n const lines = sdp.split('\\r\\n');\r\n const payloads = [];\r\n\r\n for (let i = 0; i < lines.length; i++) {\r\n\r\n if (lines[i].indexOf('m=video') === 0) {\r\n\r\n let tokens = lines[i].split(' ')\r\n\r\n for (let j = 3; j < tokens.length; j++) {\r\n\r\n payloads.push(tokens[j]);\r\n }\r\n\r\n break;\r\n }\r\n }\r\n\r\n for (let i = 0; i < payloads.length; i++) {\r\n\r\n let fmtpLineFound = false;\r\n\r\n for (let j = 0; j < lines.length; j++) {\r\n\r\n if (lines[j].indexOf('a=fmtp:' + payloads[i]) === 0) {\r\n fmtpLineFound = true;\r\n lines[j] += ';' + fmtpStr;\r\n }\r\n }\r\n\r\n if (!fmtpLineFound) {\r\n\r\n for (let j = 0; j < lines.length; j++) {\r\n\r\n if (lines[j].indexOf('a=rtpmap:' + payloads[i]) === 0) {\r\n\r\n lines[j] += '\\r\\na=fmtp:' + payloads[i] + ' ' + fmtpStr;\r\n }\r\n }\r\n }\r\n }\r\n\r\n return lines.join('\\r\\n')\r\n }\r\n\r\n function appendOrientation(sdp) {\r\n\r\n const lines = sdp.split('\\r\\n');\r\n const payloads = [];\r\n\r\n for (let i = 0; i < lines.length; i++) {\r\n\r\n if (lines[i].indexOf('m=video') === 0) {\r\n\r\n let tokens = lines[i].split(' ')\r\n\r\n for (let j = 3; j < tokens.length; j++) {\r\n\r\n payloads.push(tokens[j]);\r\n }\r\n\r\n break;\r\n }\r\n }\r\n\r\n for (let i = 0; i < payloads.length; i++) {\r\n\r\n for (let j = 0; j < lines.length; j++) {\r\n\r\n if (lines[j].indexOf('a=rtpmap:' + payloads[i]) === 0) {\r\n\r\n lines[j] += '\\r\\na=extmap:' + payloads[i] + ' urn:3gpp:video-orientation';\r\n }\r\n }\r\n }\r\n\r\n return lines.join('\\r\\n')\r\n }\r\n\r\n function createPeerConnection(id, peerId, offer, candidates, iceServers) {\r\n\r\n let peerConnectionConfig = {};\r\n\r\n if (instance.connectionConfig.iceServers) {\r\n\r\n // first priority using ice servers from local config.\r\n peerConnectionConfig.iceServers = instance.connectionConfig.iceServers;\r\n\r\n if (instance.connectionConfig.iceTransportPolicy) {\r\n\r\n peerConnectionConfig.iceTransportPolicy = instance.connectionConfig.iceTransportPolicy;\r\n }\r\n } else if (iceServers) {\r\n\r\n // second priority using ice servers from ome and force using TCP\r\n peerConnectionConfig.iceServers = [];\r\n\r\n for (let i = 0; i < iceServers.length; i++) {\r\n\r\n let iceServer = iceServers[i];\r\n\r\n let regIceServer = {};\r\n\r\n regIceServer.urls = iceServer.urls;\r\n\r\n let hasWebSocketUrl = false;\r\n let webSocketUrl = generateDomainFromUrl(instance.connectionUrl);\r\n\r\n for (let j = 0; j < regIceServer.urls.length; j++) {\r\n\r\n let serverUrl = regIceServer.urls[j];\r\n\r\n if (serverUrl.indexOf(webSocketUrl) > -1) {\r\n hasWebSocketUrl = true;\r\n break;\r\n }\r\n }\r\n\r\n if (!hasWebSocketUrl) {\r\n\r\n if (regIceServer.urls.length > 0) {\r\n\r\n let cloneIceServer = regIceServer.urls[0];\r\n let ip = findIp(cloneIceServer);\r\n\r\n if (webSocketUrl && ip) {\r\n regIceServer.urls.push(cloneIceServer.replace(ip, webSocketUrl));\r\n }\r\n }\r\n }\r\n\r\n regIceServer.username = iceServer.user_name;\r\n regIceServer.credential = iceServer.credential;\r\n\r\n peerConnectionConfig.iceServers.push(regIceServer);\r\n }\r\n\r\n peerConnectionConfig.iceTransportPolicy = 'relay';\r\n } else {\r\n // last priority using default ice servers.\r\n\r\n if (instance.iceTransportPolicy) {\r\n\r\n peerConnectionConfig.iceTransportPolicy = instance.iceTransportPolicy;\r\n }\r\n }\r\n\r\n let advancedSetting = {\r\n optional: [\r\n {\r\n googHighStartBitrate: {\r\n exact: !0\r\n }\r\n },\r\n {\r\n googPayloadPadding: {\r\n exact: !0\r\n }\r\n },\r\n {\r\n googScreencastMinBitrate: {\r\n exact: 500\r\n }\r\n },\r\n {\r\n enableDscp: {\r\n exact: true\r\n }\r\n }\r\n ]\r\n };\r\n\r\n console.info(logHeader, 'Create Peer Connection With Config', peerConnectionConfig);\r\n\r\n let peerConnection = new RTCPeerConnection(peerConnectionConfig);\r\n\r\n instance.peerConnection = peerConnection;\r\n\r\n // set local stream\r\n instance.inputStream.getTracks().forEach(function (track) {\r\n\r\n console.info(logHeader, 'Add Track To Peer Connection', track);\r\n peerConnection.addTrack(track, instance.inputStream);\r\n });\r\n\r\n if (instance.connectionConfig.maxVideoBitrate) {\r\n\r\n // if bandwith limit is set. modify sdp from ome to limit acceptable bandwidth of ome\r\n offer.sdp = setBitrateLimit(offer.sdp, 'video', instance.connectionConfig.maxVideoBitrate);\r\n }\r\n\r\n if (instance.connectionConfig.sdp && instance.connectionConfig.sdp.appendFmtp) {\r\n\r\n offer.sdp = appendFmtp(offer.sdp);\r\n }\r\n\r\n if (instance.connectionConfig.preferredVideoFormat) {\r\n offer.sdp = setPreferredVideoFormat(offer.sdp, instance.connectionConfig.preferredVideoFormat)\r\n }\r\n\r\n\r\n // offer.sdp = appendOrientation(offer.sdp);\r\n console.info(logHeader, 'Modified offer sdp\\n\\n' + offer.sdp);\r\n\r\n peerConnection.setRemoteDescription(new RTCSessionDescription(offer))\r\n .then(function () {\r\n\r\n peerConnection.createAnswer()\r\n .then(function (answer) {\r\n\r\n if (instance.connectionConfig.sdp && instance.connectionConfig.sdp.appendFmtp) {\r\n\r\n answer.sdp = appendFmtp(answer.sdp);\r\n }\r\n\r\n if (instance.connectionConfig.preferredVideoFormat) {\r\n answer.sdp = setPreferredVideoFormat(answer.sdp, instance.connectionConfig.preferredVideoFormat)\r\n }\r\n\r\n console.info(logHeader, 'Modified answer sdp\\n\\n' + answer.sdp);\r\n\r\n peerConnection.setLocalDescription(answer)\r\n .then(function () {\r\n\r\n sendMessage(instance.webSocket, {\r\n id: id,\r\n peer_id: peerId,\r\n command: 'answer',\r\n sdp: answer\r\n });\r\n })\r\n .catch(function (error) {\r\n\r\n console.error('peerConnection.setLocalDescription', error);\r\n errorHandler(error);\r\n });\r\n })\r\n .catch(function (error) {\r\n\r\n console.error('peerConnection.createAnswer', error);\r\n errorHandler(error);\r\n });\r\n })\r\n .catch(function (error) {\r\n\r\n console.error('peerConnection.setRemoteDescription', error);\r\n errorHandler(error);\r\n });\r\n\r\n if (candidates) {\r\n\r\n addIceCandidate(peerConnection, candidates);\r\n }\r\n\r\n peerConnection.onicecandidate = function (e) {\r\n\r\n if (e.candidate && e.candidate.candidate) {\r\n\r\n sendMessage(instance.webSocket, {\r\n id: id,\r\n peer_id: peerId,\r\n command: 'candidate',\r\n candidates: [e.candidate]\r\n });\r\n }\r\n };\r\n\r\n peerConnection.oniceconnectionstatechange = function (e) {\r\n\r\n let state = peerConnection.iceConnectionState;\r\n\r\n if (instance.callbacks.iceStateChange) {\r\n\r\n console.info(logHeader, 'ICE State', '[' + state + ']');\r\n instance.callbacks.iceStateChange(state);\r\n }\r\n\r\n if (state === 'connected') {\r\n\r\n if (instance.callbacks.connected) {\r\n instance.callbacks.connected(e);\r\n }\r\n }\r\n\r\n if (state === 'failed' || state === 'disconnected' || state === 'closed') {\r\n\r\n if (instance.callbacks.connectionClosed) {\r\n console.error(logHeader, 'Iceconnection Closed', e);\r\n instance.callbacks.connectionClosed('ice', e);\r\n }\r\n }\r\n }\r\n }\r\n\r\n function addIceCandidate(peerConnection, candidates) {\r\n\r\n for (let i = 0; i < candidates.length; i++) {\r\n\r\n if (candidates[i] && candidates[i].candidate) {\r\n\r\n let basicCandidate = candidates[i];\r\n\r\n peerConnection.addIceCandidate(new RTCIceCandidate(basicCandidate))\r\n .then(function () {\r\n\r\n })\r\n .catch(function (error) {\r\n\r\n console.error('peerConnection.addIceCandidate', error);\r\n errorHandler(error);\r\n });\r\n }\r\n }\r\n }\r\n\r\n function closePeerConnection() {\r\n if (instance.peerConnection) {\r\n\r\n // remove tracks from peer connection\r\n instance.peerConnection.getSenders().forEach(function (sender) {\r\n instance.peerConnection.removeTrack(sender);\r\n });\r\n\r\n instance.peerConnection.close();\r\n instance.peerConnection = null;\r\n delete instance.peerConnection;\r\n }\r\n }\r\n\r\n function closeWebSocket() {\r\n\r\n if (instance.webSocket) {\r\n\r\n instance.webSocket.close();\r\n instance.webSocket = null;\r\n delete instance.webSocket;\r\n }\r\n }\r\n\r\n function closeInputStream() {\r\n // release video, audio stream\r\n if (instance.inputStream) {\r\n\r\n instance.inputStream.getTracks().forEach(track => {\r\n\r\n track.stop();\r\n instance.inputStream.removeTrack(track);\r\n });\r\n\r\n if (instance.videoElement) {\r\n instance.videoElement.srcObject = null;\r\n }\r\n\r\n instance.inputStream = null;\r\n delete instance.inputStream;\r\n }\r\n }\r\n\r\n // instance methods\r\n instance.attachMedia = function (videoElement) {\r\n\r\n instance.videoElement = videoElement;\r\n };\r\n\r\n instance.getUserMedia = function (constraints) {\r\n\r\n return getUserMedia(constraints);\r\n };\r\n\r\n instance.getDisplayMedia = function (constraints) {\r\n\r\n return getDisplayMedia(constraints);\r\n };\r\n\r\n instance.startStreaming = function (connectionUrl, connectionConfig) {\r\n\r\n console.info(logEventHeader, 'Start Streaming with connectionConfig', connectionConfig);\r\n\r\n if (connectionConfig) {\r\n\r\n instance.connectionConfig = connectionConfig;\r\n }\r\n\r\n initWebSocket(connectionUrl);\r\n };\r\n\r\n instance.stopStreaming = function () {\r\n\r\n instance.webSocketClosedByUser = true;\r\n\r\n closeWebSocket();\r\n closePeerConnection();\r\n };\r\n\r\n instance.remove = function () {\r\n\r\n instance.webSocketClosedByUser = true;\r\n\r\n closeWebSocket();\r\n closePeerConnection();\r\n closeInputStream();\r\n\r\n console.info(logEventHeader, 'Removed');\r\n\r\n };\r\n}\r\n\r\nOvenLiveKit.getVersion = function () {\r\n return version;\r\n}\r\n\r\n// static methods\r\nOvenLiveKit.create = function (options) {\r\n\r\n console.info(logEventHeader, 'Create WebRTC Input ' + version);\r\n\r\n let instance = {};\r\n\r\n instance.webSocketClosedByUser = false;\r\n\r\n initConfig(instance, options);\r\n addMethod(instance);\r\n\r\n return instance;\r\n};\r\n\r\nOvenLiveKit.getDevices = async function () {\r\n\r\n try {\r\n // First check both audio and video sources are available.\r\n await getStreamForDeviceCheck('both');\r\n } catch (e) {\r\n\r\n console.warn(logHeader, 'Can not find Video and Audio devices', e);\r\n\r\n let videoFound = null;\r\n let audioFound = null;\r\n\r\n try {\r\n videoFound = await getStreamForDeviceCheck('video');\r\n } catch (e) {\r\n console.warn(logHeader, 'Can not find Video devices', e);\r\n }\r\n\r\n try {\r\n audioFound = await getStreamForDeviceCheck('audio');\r\n } catch (e) {\r\n console.warn(logHeader, 'Can not find Audio devices', e);\r\n }\r\n\r\n if (!videoFound && !audioFound) {\r\n throw new Error('No input devices were found.');\r\n }\r\n }\r\n\r\n const deviceInfos = await getDevices();\r\n return gotDevices(deviceInfos)\r\n};\r\n\r\nexport default OvenLiveKit;"],"names":["root","factory","exports","module","define","amd","self","__webpack_require__","definition","key","o","Object","defineProperty","enumerable","get","obj","prop","prototype","hasOwnProperty","call","OvenLiveKit","logHeader","logEventHeader","sendMessage","webSocket","message","send","JSON","stringify","generateDomainFromUrl","url","match","result","findIp","string","RegExp","setPreferredVideoFormat","sdp","formatName","formatNumber","format","lines","split","i","length","toLowerCase","indexOf","getFormatNumber","newLines","line","others","slice","formats","sort","x","y","push","concat","join","async","getStreamForDeviceCheck","type","constraints","audio","video","navigator","mediaDevices","getUserMedia","addMethod","instance","errorHandler","error","callbacks","appendFmtp","fmtpStr","connectionConfig","payloads","tokens","j","fmtpLineFound","closePeerConnection","peerConnection","getSenders","forEach","sender","removeTrack","close","closeWebSocket","attachMedia","videoElement","deviceId","undefined","console","info","then","stream","inputStream","elem","srcObject","onloadedmetadata","e","play","Promise","resolve","catch","reject","getDisplayMedia","startStreaming","connectionUrl","WebSocket","onopen","command","onmessage","parse","data","id","peerId","offer","candidates","iceServers","peerConnectionConfig","iceTransportPolicy","iceServer","regIceServer","urls","hasWebSocketUrl","webSocketUrl","cloneIceServer","ip","replace","username","user_name","credential","RTCPeerConnection","getTracks","track","addTrack","maxVideoBitrate","media","bitrate","setBitrateLimit","preferredVideoFormat","setRemoteDescription","RTCSessionDescription","createAnswer","answer","setLocalDescription","peer_id","candidate","basicCandidate","addIceCandidate","RTCIceCandidate","onicecandidate","oniceconnectionstatechange","state","iceConnectionState","iceStateChange","connected","connectionClosed","createPeerConnection","ice_servers","onerror","onclose","webSocketClosedByUser","initWebSocket","stopStreaming","remove","stop","getVersion","create","options","initConfig","getDevices","warn","videoFound","audioFound","Error","deviceInfos","devices","deviceInfo","kind","label","audioinput","audiooutput","videoinput","other","gotDevices","enumerateDevices"],"sourceRoot":""}
|
|
1
|
+
{"version":3,"file":"OvenLiveKit.min.js","mappings":"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","sources":["webpack://OvenLiveKit/webpack/universalModuleDefinition","webpack://OvenLiveKit/webpack/bootstrap","webpack://OvenLiveKit/webpack/runtime/define property getters","webpack://OvenLiveKit/webpack/runtime/hasOwnProperty shorthand","webpack://OvenLiveKit/./src/OvenLiveKit.js"],"sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"OvenLiveKit\"] = factory();\n\telse\n\t\troot[\"OvenLiveKit\"] = factory();\n})(self, function() {\nreturn ","// The require scope\nvar __webpack_require__ = {};\n\n","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","const OvenLiveKit = {};\r\n\r\nconst version = '1.1.0';\r\nconst logHeader = 'OvenLiveKit.js :';\r\nconst logEventHeader = 'OvenLiveKit.js ====';\r\n\r\n// private methods\r\nfunction sendMessage(webSocket, message) {\r\n\r\n if (webSocket) {\r\n webSocket.send(JSON.stringify(message));\r\n }\r\n}\r\n\r\nfunction generateDomainFromUrl(url) {\r\n let result = '';\r\n let match;\r\n if (match = url.match(/^(?:wss?:\\/\\/)?(?:[^@\\n]+@)?(?:www\\.)?([^:\\/\\n\\?\\=]+)/im)) {\r\n result = match[1];\r\n }\r\n\r\n return result;\r\n}\r\n\r\nfunction findIp(string) {\r\n\r\n let result = '';\r\n let match;\r\n\r\n if (match = string.match(new RegExp('\\\\b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\\\b', 'gi'))) {\r\n result = match[0];\r\n }\r\n\r\n return result;\r\n}\r\n\r\nfunction getFormatNumber(sdp, format) {\r\n\r\n const lines = sdp.split('\\r\\n');\r\n let formatNumber = -1;\r\n\r\n for (let i = 0; i < lines.length - 1; i++) {\r\n\r\n lines[i] = lines[i].toLowerCase();\r\n\r\n if (lines[i].indexOf('a=rtpmap') === 0 && lines[i].indexOf(format.toLowerCase()) > -1) {\r\n // parsing \"a=rtpmap:100 H264/90000\" line\r\n // a=rtpmap:<payload type> <encoding name>/<clock rate>[/<encoding parameters >]\r\n formatNumber = lines[i].split(' ')[0].split(':')[1];\r\n break;\r\n }\r\n }\r\n\r\n return formatNumber;\r\n}\r\n\r\nfunction setPreferredVideoFormat(sdp, formatName) {\r\n\r\n const formatNumber = getFormatNumber(sdp, formatName);\r\n\r\n if (formatNumber === -1) {\r\n return sdp;\r\n }\r\n\r\n let newLines = [];\r\n const lines = sdp.split('\\r\\n');\r\n\r\n for (let i = 0; i < lines.length - 1; i++) {\r\n\r\n const line = lines[i];\r\n\r\n if (line.indexOf('m=video') === 0) {\r\n\r\n // m=<media> <port>/<number of ports> <transport> <fmt list>\r\n const others = line.split(' ').slice(0, 3);\r\n const formats = line.split(' ').slice(3);\r\n formats.sort(function (x, y) { return x == formatNumber ? -1 : y == formatNumber ? 1 : 0; });\r\n newLines.push(others.concat(formats).join(' '));\r\n } else {\r\n newLines.push(line);\r\n }\r\n\r\n }\r\n\r\n return newLines.join('\\r\\n') + '\\r\\n';\r\n}\r\n\r\nfunction removeFormat(sdp, formatNumber) {\r\n let newLines = [];\r\n let lines = sdp.split('\\r\\n');\r\n\r\n for (let i = 0; i < lines.length; i++) {\r\n\r\n if (lines[i].indexOf('m=video') === 0) {\r\n newLines.push(lines[i].replace(' ' + formatNumber + '', ''));\r\n } else if (lines[i].indexOf(formatNumber + '') > -1) {\r\n\r\n } else {\r\n newLines.push(lines[i]);\r\n }\r\n }\r\n\r\n return newLines.join('\\r\\n')\r\n}\r\n\r\nasync function getStreamForDeviceCheck(type) {\r\n\r\n // High resolution video constraints makes browser to get maximum resolution of video device.\r\n const constraints = {\r\n };\r\n\r\n if (type === 'both') {\r\n constraints.audio = true;\r\n constraints.video = true;\r\n } else if (type === 'audio') {\r\n constraints.audio = true;\r\n } else if (type === 'video') {\r\n constraints.video = true;\r\n }\r\n\r\n return await navigator.mediaDevices.getUserMedia(constraints);\r\n}\r\n\r\nasync function getDevices() {\r\n\r\n return await navigator.mediaDevices.enumerateDevices();\r\n}\r\n\r\nfunction gotDevices(deviceInfos) {\r\n\r\n let devices = {\r\n 'audioinput': [],\r\n 'audiooutput': [],\r\n 'videoinput': [],\r\n 'other': [],\r\n };\r\n\r\n for (let i = 0; i !== deviceInfos.length; ++i) {\r\n\r\n const deviceInfo = deviceInfos[i];\r\n\r\n let info = {};\r\n\r\n info.deviceId = deviceInfo.deviceId;\r\n\r\n if (deviceInfo.kind === 'audioinput') {\r\n\r\n info.label = deviceInfo.label || `microphone ${devices.audioinput.length + 1}`;\r\n devices.audioinput.push(info);\r\n } else if (deviceInfo.kind === 'audiooutput') {\r\n\r\n info.label = deviceInfo.label || `speaker ${devices.audiooutput.length + 1}`;\r\n devices.audiooutput.push(info);\r\n } else if (deviceInfo.kind === 'videoinput') {\r\n\r\n info.label = deviceInfo.label || `camera ${devices.videoinput.length + 1}`;\r\n devices.videoinput.push(info);\r\n } else {\r\n\r\n info.label = deviceInfo.label || `other ${devices.other.length + 1}`;\r\n devices.other.push(info);\r\n }\r\n }\r\n\r\n return devices;\r\n}\r\n\r\nfunction initConfig(instance, options) {\r\n\r\n instance.inputStream = null;\r\n instance.webSocket = null;\r\n instance.peerConnection = null;\r\n instance.connectionConfig = {};\r\n\r\n instance.videoElement = null;\r\n instance.connectionUrl = null;\r\n\r\n if (options && options.callbacks) {\r\n\r\n instance.callbacks = options.callbacks;\r\n } else {\r\n instance.callbacks = {};\r\n }\r\n}\r\n\r\nfunction addMethod(instance) {\r\n\r\n function errorHandler(error) {\r\n\r\n if (instance.callbacks.error) {\r\n\r\n instance.callbacks.error(error);\r\n }\r\n }\r\n\r\n function getUserMedia(constraints) {\r\n\r\n if (!constraints) {\r\n\r\n constraints = {\r\n video: {\r\n deviceId: undefined\r\n },\r\n audio: {\r\n deviceId: undefined\r\n }\r\n };\r\n }\r\n\r\n console.info(logHeader, 'Request Stream To Input Devices With Constraints', constraints);\r\n\r\n return navigator.mediaDevices.getUserMedia(constraints)\r\n .then(function (stream) {\r\n\r\n console.info(logHeader, 'Received Media Stream From Input Device', stream);\r\n\r\n instance.inputStream = stream;\r\n\r\n let elem = instance.videoElement;\r\n\r\n // Attach stream to video element when video element is provided.\r\n if (elem) {\r\n\r\n elem.srcObject = stream;\r\n\r\n elem.onloadedmetadata = function (e) {\r\n\r\n elem.play();\r\n };\r\n }\r\n\r\n return new Promise(function (resolve) {\r\n\r\n resolve(stream);\r\n });\r\n })\r\n .catch(function (error) {\r\n\r\n console.error(logHeader, 'Can\\'t Get Media Stream From Input Device', error);\r\n errorHandler(error);\r\n\r\n return new Promise(function (resolve, reject) {\r\n reject(error);\r\n });\r\n });\r\n }\r\n\r\n function getDisplayMedia(constraints) {\r\n\r\n if (!constraints) {\r\n constraints = {};\r\n }\r\n\r\n console.info(logHeader, 'Request Stream To Display With Constraints', constraints);\r\n\r\n return navigator.mediaDevices.getDisplayMedia(constraints)\r\n .then(function (stream) {\r\n\r\n console.info(logHeader, 'Received Media Stream From Display', stream);\r\n\r\n instance.inputStream = stream;\r\n\r\n let elem = instance.videoElement;\r\n\r\n // Attach stream to video element when video element is provided.\r\n if (elem) {\r\n\r\n elem.srcObject = stream;\r\n\r\n elem.onloadedmetadata = function (e) {\r\n\r\n elem.play();\r\n };\r\n }\r\n\r\n return new Promise(function (resolve) {\r\n\r\n resolve(stream);\r\n });\r\n })\r\n .catch(function (error) {\r\n\r\n console.error(logHeader, 'Can\\'t Get Media Stream From Display', error);\r\n errorHandler(error);\r\n\r\n return new Promise(function (resolve, reject) {\r\n reject(error);\r\n });\r\n });\r\n }\r\n\r\n function setMediaStream(stream) {\r\n // Check if a valid stream is provided\r\n if (!stream || !(stream instanceof MediaStream)) {\r\n \r\n const error = new Error(\"Invalid MediaStream provided\");\r\n console.error(logHeader, 'Invalid MediaStream', error);\r\n errorHandler(error);\r\n \r\n return new Promise(function (resolve, reject) {\r\n reject(error);\r\n });\r\n }\r\n \r\n console.info(logHeader, 'Received Media Stream', stream);\r\n \r\n instance.inputStream = stream;\r\n \r\n let elem = instance.videoElement;\r\n \r\n // Attach stream to video element when video element is provided.\r\n if (elem) {\r\n elem.srcObject = stream;\r\n \r\n elem.onloadedmetadata = function (e) {\r\n elem.play();\r\n };\r\n }\r\n \r\n return new Promise(function (resolve) {\r\n resolve(stream);\r\n });\r\n }\r\n\r\n // From https://webrtchacks.com/limit-webrtc-bandwidth-sdp/\r\n function setBitrateLimit(sdp, media, bitrate) {\r\n\r\n let lines = sdp.split('\\r\\n');\r\n let line = -1;\r\n\r\n for (let i = 0; i < lines.length; i++) {\r\n if (lines[i].indexOf('m=' + media) === 0) {\r\n line = i;\r\n break;\r\n }\r\n }\r\n if (line === -1) {\r\n // Could not find the m line for media\r\n return sdp;\r\n }\r\n\r\n // Pass the m line\r\n line++;\r\n\r\n // Skip i and c lines\r\n while (lines[line].indexOf('i=') === 0 || lines[line].indexOf('c=') === 0) {\r\n\r\n line++;\r\n }\r\n\r\n // If we're on a b line, replace it\r\n if (lines[line].indexOf('b') === 0) {\r\n\r\n lines[line] = 'b=AS:' + bitrate;\r\n\r\n return lines.join('\\r\\n');\r\n }\r\n\r\n // Add a new b line\r\n let newLines = lines.slice(0, line)\r\n\r\n newLines.push('b=AS:' + bitrate)\r\n newLines = newLines.concat(lines.slice(line, lines.length))\r\n\r\n return newLines.join('\\r\\n')\r\n }\r\n\r\n function initWebSocket(connectionUrl) {\r\n\r\n if (!connectionUrl) {\r\n errorHandler('connectionUrl is required');\r\n return;\r\n }\r\n\r\n instance.connectionUrl = connectionUrl;\r\n\r\n let webSocket = null;\r\n\r\n try {\r\n\r\n webSocket = new WebSocket(connectionUrl);\r\n } catch (error) {\r\n\r\n errorHandler(error);\r\n }\r\n\r\n\r\n instance.webSocket = webSocket;\r\n\r\n webSocket.onopen = function () {\r\n\r\n // Request offer at the first time.\r\n sendMessage(webSocket, {\r\n command: 'request_offer'\r\n });\r\n };\r\n\r\n webSocket.onmessage = function (e) {\r\n\r\n let message = JSON.parse(e.data);\r\n\r\n if (message.error) {\r\n console.error('webSocket.onmessage', message.error);\r\n errorHandler(message.error);\r\n }\r\n\r\n if (message.command === 'offer') {\r\n\r\n // OME returns offer. Start create peer connection.\r\n createPeerConnection(\r\n message.id,\r\n message.peer_id,\r\n message.sdp,\r\n message.candidates,\r\n message.ice_servers\r\n );\r\n }\r\n };\r\n\r\n webSocket.onerror = function (error) {\r\n\r\n console.error('webSocket.onerror', error);\r\n errorHandler(error);\r\n };\r\n\r\n webSocket.onclose = function (e) {\r\n\r\n if (!instance.webSocketClosedByUser) {\r\n\r\n if (instance.callbacks.connectionClosed) {\r\n instance.callbacks.connectionClosed('websocket', e);\r\n }\r\n }\r\n };\r\n\r\n }\r\n\r\n function appendFmtp(sdp) {\r\n\r\n const fmtpStr = instance.connectionConfig.sdp.appendFmtp;\r\n\r\n const lines = sdp.split('\\r\\n');\r\n const payloads = [];\r\n\r\n for (let i = 0; i < lines.length; i++) {\r\n\r\n if (lines[i].indexOf('m=video') === 0) {\r\n\r\n let tokens = lines[i].split(' ')\r\n\r\n for (let j = 3; j < tokens.length; j++) {\r\n\r\n payloads.push(tokens[j]);\r\n }\r\n\r\n break;\r\n }\r\n }\r\n\r\n for (let i = 0; i < payloads.length; i++) {\r\n\r\n let fmtpLineFound = false;\r\n\r\n for (let j = 0; j < lines.length; j++) {\r\n\r\n if (lines[j].indexOf('a=fmtp:' + payloads[i]) === 0) {\r\n fmtpLineFound = true;\r\n lines[j] += ';' + fmtpStr;\r\n }\r\n }\r\n\r\n if (!fmtpLineFound) {\r\n\r\n for (let j = 0; j < lines.length; j++) {\r\n\r\n if (lines[j].indexOf('a=rtpmap:' + payloads[i]) === 0) {\r\n\r\n lines[j] += '\\r\\na=fmtp:' + payloads[i] + ' ' + fmtpStr;\r\n }\r\n }\r\n }\r\n }\r\n\r\n return lines.join('\\r\\n')\r\n }\r\n\r\n function appendOrientation(sdp) {\r\n\r\n const lines = sdp.split('\\r\\n');\r\n const payloads = [];\r\n\r\n for (let i = 0; i < lines.length; i++) {\r\n\r\n if (lines[i].indexOf('m=video') === 0) {\r\n\r\n let tokens = lines[i].split(' ')\r\n\r\n for (let j = 3; j < tokens.length; j++) {\r\n\r\n payloads.push(tokens[j]);\r\n }\r\n\r\n break;\r\n }\r\n }\r\n\r\n for (let i = 0; i < payloads.length; i++) {\r\n\r\n for (let j = 0; j < lines.length; j++) {\r\n\r\n if (lines[j].indexOf('a=rtpmap:' + payloads[i]) === 0) {\r\n\r\n lines[j] += '\\r\\na=extmap:' + payloads[i] + ' urn:3gpp:video-orientation';\r\n }\r\n }\r\n }\r\n\r\n return lines.join('\\r\\n')\r\n }\r\n\r\n function createPeerConnection(id, peerId, offer, candidates, iceServers) {\r\n\r\n let peerConnectionConfig = {};\r\n\r\n if (instance.connectionConfig.iceServers) {\r\n\r\n // first priority using ice servers from local config.\r\n peerConnectionConfig.iceServers = instance.connectionConfig.iceServers;\r\n\r\n if (instance.connectionConfig.iceTransportPolicy) {\r\n\r\n peerConnectionConfig.iceTransportPolicy = instance.connectionConfig.iceTransportPolicy;\r\n }\r\n } else if (iceServers) {\r\n\r\n // second priority using ice servers from ome and force using TCP\r\n peerConnectionConfig.iceServers = [];\r\n\r\n for (let i = 0; i < iceServers.length; i++) {\r\n\r\n let iceServer = iceServers[i];\r\n\r\n let regIceServer = {};\r\n\r\n regIceServer.urls = iceServer.urls;\r\n\r\n let hasWebSocketUrl = false;\r\n let webSocketUrl = generateDomainFromUrl(instance.connectionUrl);\r\n\r\n for (let j = 0; j < regIceServer.urls.length; j++) {\r\n\r\n let serverUrl = regIceServer.urls[j];\r\n\r\n if (serverUrl.indexOf(webSocketUrl) > -1) {\r\n hasWebSocketUrl = true;\r\n break;\r\n }\r\n }\r\n\r\n if (!hasWebSocketUrl) {\r\n\r\n if (regIceServer.urls.length > 0) {\r\n\r\n let cloneIceServer = regIceServer.urls[0];\r\n let ip = findIp(cloneIceServer);\r\n\r\n if (webSocketUrl && ip) {\r\n regIceServer.urls.push(cloneIceServer.replace(ip, webSocketUrl));\r\n }\r\n }\r\n }\r\n\r\n regIceServer.username = iceServer.user_name;\r\n regIceServer.credential = iceServer.credential;\r\n\r\n peerConnectionConfig.iceServers.push(regIceServer);\r\n }\r\n\r\n peerConnectionConfig.iceTransportPolicy = 'relay';\r\n } else {\r\n // last priority using default ice servers.\r\n\r\n if (instance.iceTransportPolicy) {\r\n\r\n peerConnectionConfig.iceTransportPolicy = instance.iceTransportPolicy;\r\n }\r\n }\r\n\r\n let advancedSetting = {\r\n optional: [\r\n {\r\n googHighStartBitrate: {\r\n exact: !0\r\n }\r\n },\r\n {\r\n googPayloadPadding: {\r\n exact: !0\r\n }\r\n },\r\n {\r\n googScreencastMinBitrate: {\r\n exact: 500\r\n }\r\n },\r\n {\r\n enableDscp: {\r\n exact: true\r\n }\r\n }\r\n ]\r\n };\r\n\r\n console.info(logHeader, 'Create Peer Connection With Config', peerConnectionConfig);\r\n\r\n let peerConnection = new RTCPeerConnection(peerConnectionConfig);\r\n\r\n instance.peerConnection = peerConnection;\r\n\r\n // set local stream\r\n instance.inputStream.getTracks().forEach(function (track) {\r\n\r\n console.info(logHeader, 'Add Track To Peer Connection', track);\r\n peerConnection.addTrack(track, instance.inputStream);\r\n });\r\n\r\n if (instance.connectionConfig.maxVideoBitrate) {\r\n\r\n // if bandwith limit is set. modify sdp from ome to limit acceptable bandwidth of ome\r\n offer.sdp = setBitrateLimit(offer.sdp, 'video', instance.connectionConfig.maxVideoBitrate);\r\n }\r\n\r\n if (instance.connectionConfig.sdp && instance.connectionConfig.sdp.appendFmtp) {\r\n\r\n offer.sdp = appendFmtp(offer.sdp);\r\n }\r\n\r\n if (instance.connectionConfig.preferredVideoFormat) {\r\n offer.sdp = setPreferredVideoFormat(offer.sdp, instance.connectionConfig.preferredVideoFormat)\r\n }\r\n\r\n\r\n // offer.sdp = appendOrientation(offer.sdp);\r\n console.info(logHeader, 'Modified offer sdp\\n\\n' + offer.sdp);\r\n\r\n peerConnection.setRemoteDescription(new RTCSessionDescription(offer))\r\n .then(function () {\r\n\r\n peerConnection.createAnswer()\r\n .then(function (answer) {\r\n\r\n if (instance.connectionConfig.sdp && instance.connectionConfig.sdp.appendFmtp) {\r\n\r\n answer.sdp = appendFmtp(answer.sdp);\r\n }\r\n\r\n if (instance.connectionConfig.preferredVideoFormat) {\r\n answer.sdp = setPreferredVideoFormat(answer.sdp, instance.connectionConfig.preferredVideoFormat)\r\n }\r\n\r\n console.info(logHeader, 'Modified answer sdp\\n\\n' + answer.sdp);\r\n\r\n peerConnection.setLocalDescription(answer)\r\n .then(function () {\r\n\r\n sendMessage(instance.webSocket, {\r\n id: id,\r\n peer_id: peerId,\r\n command: 'answer',\r\n sdp: answer\r\n });\r\n })\r\n .catch(function (error) {\r\n\r\n console.error('peerConnection.setLocalDescription', error);\r\n errorHandler(error);\r\n });\r\n })\r\n .catch(function (error) {\r\n\r\n console.error('peerConnection.createAnswer', error);\r\n errorHandler(error);\r\n });\r\n })\r\n .catch(function (error) {\r\n\r\n console.error('peerConnection.setRemoteDescription', error);\r\n errorHandler(error);\r\n });\r\n\r\n if (candidates) {\r\n\r\n addIceCandidate(peerConnection, candidates);\r\n }\r\n\r\n peerConnection.onicecandidate = function (e) {\r\n\r\n if (e.candidate && e.candidate.candidate) {\r\n\r\n sendMessage(instance.webSocket, {\r\n id: id,\r\n peer_id: peerId,\r\n command: 'candidate',\r\n candidates: [e.candidate]\r\n });\r\n }\r\n };\r\n\r\n peerConnection.oniceconnectionstatechange = function (e) {\r\n\r\n let state = peerConnection.iceConnectionState;\r\n\r\n if (instance.callbacks.iceStateChange) {\r\n\r\n console.info(logHeader, 'ICE State', '[' + state + ']');\r\n instance.callbacks.iceStateChange(state);\r\n }\r\n\r\n if (state === 'connected') {\r\n\r\n if (instance.callbacks.connected) {\r\n instance.callbacks.connected(e);\r\n }\r\n }\r\n\r\n if (state === 'failed' || state === 'disconnected' || state === 'closed') {\r\n\r\n if (instance.callbacks.connectionClosed) {\r\n console.error(logHeader, 'Iceconnection Closed', e);\r\n instance.callbacks.connectionClosed('ice', e);\r\n }\r\n }\r\n }\r\n }\r\n\r\n function addIceCandidate(peerConnection, candidates) {\r\n\r\n for (let i = 0; i < candidates.length; i++) {\r\n\r\n if (candidates[i] && candidates[i].candidate) {\r\n\r\n let basicCandidate = candidates[i];\r\n\r\n peerConnection.addIceCandidate(new RTCIceCandidate(basicCandidate))\r\n .then(function () {\r\n\r\n })\r\n .catch(function (error) {\r\n\r\n console.error('peerConnection.addIceCandidate', error);\r\n errorHandler(error);\r\n });\r\n }\r\n }\r\n }\r\n\r\n function closePeerConnection() {\r\n if (instance.peerConnection) {\r\n\r\n // remove tracks from peer connection\r\n instance.peerConnection.getSenders().forEach(function (sender) {\r\n instance.peerConnection.removeTrack(sender);\r\n });\r\n\r\n instance.peerConnection.close();\r\n instance.peerConnection = null;\r\n delete instance.peerConnection;\r\n }\r\n }\r\n\r\n function closeWebSocket() {\r\n\r\n if (instance.webSocket) {\r\n\r\n instance.webSocket.close();\r\n instance.webSocket = null;\r\n delete instance.webSocket;\r\n }\r\n }\r\n\r\n function closeInputStream() {\r\n // release video, audio stream\r\n if (instance.inputStream) {\r\n\r\n instance.inputStream.getTracks().forEach(track => {\r\n\r\n track.stop();\r\n instance.inputStream.removeTrack(track);\r\n });\r\n\r\n if (instance.videoElement) {\r\n instance.videoElement.srcObject = null;\r\n }\r\n\r\n instance.inputStream = null;\r\n delete instance.inputStream;\r\n }\r\n }\r\n\r\n // instance methods\r\n instance.attachMedia = function (videoElement) {\r\n\r\n instance.videoElement = videoElement;\r\n };\r\n\r\n instance.getUserMedia = function (constraints) {\r\n\r\n return getUserMedia(constraints);\r\n };\r\n\r\n instance.getDisplayMedia = function (constraints) {\r\n\r\n return getDisplayMedia(constraints);\r\n };\r\n\r\n instance.setMediaStream = function (stream) {\r\n\r\n return setMediaStream(stream);\r\n };\r\n\r\n instance.startStreaming = function (connectionUrl, connectionConfig) {\r\n\r\n console.info(logEventHeader, 'Start Streaming with connectionConfig', connectionConfig);\r\n\r\n if (connectionConfig) {\r\n\r\n instance.connectionConfig = connectionConfig;\r\n }\r\n\r\n initWebSocket(connectionUrl);\r\n };\r\n\r\n instance.stopStreaming = function () {\r\n\r\n instance.webSocketClosedByUser = true;\r\n\r\n closeWebSocket();\r\n closePeerConnection();\r\n };\r\n\r\n instance.remove = function () {\r\n\r\n instance.webSocketClosedByUser = true;\r\n\r\n closeWebSocket();\r\n closePeerConnection();\r\n closeInputStream();\r\n\r\n console.info(logEventHeader, 'Removed');\r\n\r\n };\r\n}\r\n\r\nOvenLiveKit.getVersion = function () {\r\n return version;\r\n}\r\n\r\n// static methods\r\nOvenLiveKit.create = function (options) {\r\n\r\n console.info(logEventHeader, 'Create WebRTC Input ' + version);\r\n\r\n let instance = {};\r\n\r\n instance.webSocketClosedByUser = false;\r\n\r\n initConfig(instance, options);\r\n addMethod(instance);\r\n\r\n return instance;\r\n};\r\n\r\nOvenLiveKit.getDevices = async function () {\r\n\r\n try {\r\n // First check both audio and video sources are available.\r\n await getStreamForDeviceCheck('both');\r\n } catch (e) {\r\n\r\n console.warn(logHeader, 'Can not find Video and Audio devices', e);\r\n\r\n let videoFound = null;\r\n let audioFound = null;\r\n\r\n try {\r\n videoFound = await getStreamForDeviceCheck('video');\r\n } catch (e) {\r\n console.warn(logHeader, 'Can not find Video devices', e);\r\n }\r\n\r\n try {\r\n audioFound = await getStreamForDeviceCheck('audio');\r\n } catch (e) {\r\n console.warn(logHeader, 'Can not find Audio devices', e);\r\n }\r\n\r\n if (!videoFound && !audioFound) {\r\n throw new Error('No input devices were found.');\r\n }\r\n }\r\n\r\n const deviceInfos = await getDevices();\r\n return gotDevices(deviceInfos)\r\n};\r\n\r\nexport default OvenLiveKit;"],"names":["root","factory","exports","module","define","amd","self","__webpack_require__","definition","key","o","Object","defineProperty","enumerable","get","obj","prop","prototype","hasOwnProperty","call","OvenLiveKit","logHeader","logEventHeader","sendMessage","webSocket","message","send","JSON","stringify","generateDomainFromUrl","url","match","result","findIp","string","RegExp","setPreferredVideoFormat","sdp","formatName","formatNumber","format","lines","split","i","length","toLowerCase","indexOf","getFormatNumber","newLines","line","others","slice","formats","sort","x","y","push","concat","join","async","getStreamForDeviceCheck","type","constraints","audio","video","navigator","mediaDevices","getUserMedia","addMethod","instance","errorHandler","error","callbacks","appendFmtp","fmtpStr","connectionConfig","payloads","tokens","j","fmtpLineFound","closePeerConnection","peerConnection","getSenders","forEach","sender","removeTrack","close","closeWebSocket","attachMedia","videoElement","deviceId","undefined","console","info","then","stream","inputStream","elem","srcObject","onloadedmetadata","e","play","Promise","resolve","catch","reject","getDisplayMedia","setMediaStream","MediaStream","Error","startStreaming","connectionUrl","WebSocket","onopen","command","onmessage","parse","data","id","peerId","offer","candidates","iceServers","peerConnectionConfig","iceTransportPolicy","iceServer","regIceServer","urls","hasWebSocketUrl","webSocketUrl","cloneIceServer","ip","replace","username","user_name","credential","RTCPeerConnection","getTracks","track","addTrack","maxVideoBitrate","media","bitrate","setBitrateLimit","preferredVideoFormat","setRemoteDescription","RTCSessionDescription","createAnswer","answer","setLocalDescription","peer_id","candidate","basicCandidate","addIceCandidate","RTCIceCandidate","onicecandidate","oniceconnectionstatechange","state","iceConnectionState","iceStateChange","connected","connectionClosed","createPeerConnection","ice_servers","onerror","onclose","webSocketClosedByUser","initWebSocket","stopStreaming","remove","stop","getVersion","create","options","initConfig","getDevices","warn","videoFound","audioFound","deviceInfos","devices","deviceInfo","kind","label","audioinput","audiooutput","videoinput","other","gotDevices","enumerateDevices"],"sourceRoot":""}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ovenlivekit",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"description": "OvenLiveKit for Web is an open source JavaScript SDK suite for live streaming from web browsers to OvenMediaEngine.",
|
|
5
5
|
"main": "dist/OvenLiveKit.min.js",
|
|
6
6
|
"scripts": {
|
|
@@ -25,8 +25,8 @@
|
|
|
25
25
|
},
|
|
26
26
|
"homepage": "https://github.com/AirenSoft/OvenLiveKit-Web#readme",
|
|
27
27
|
"devDependencies": {
|
|
28
|
-
"webpack": "^5.
|
|
29
|
-
"webpack-cli": "^
|
|
30
|
-
"webpack-dev-server": "^
|
|
28
|
+
"webpack": "^5.90.3",
|
|
29
|
+
"webpack-cli": "^5.1.4",
|
|
30
|
+
"webpack-dev-server": "^5.0.2"
|
|
31
31
|
}
|
|
32
32
|
}
|
package/src/OvenLiveKit.js
CHANGED
|
@@ -289,6 +289,39 @@ function addMethod(instance) {
|
|
|
289
289
|
});
|
|
290
290
|
}
|
|
291
291
|
|
|
292
|
+
function setMediaStream(stream) {
|
|
293
|
+
// Check if a valid stream is provided
|
|
294
|
+
if (!stream || !(stream instanceof MediaStream)) {
|
|
295
|
+
|
|
296
|
+
const error = new Error("Invalid MediaStream provided");
|
|
297
|
+
console.error(logHeader, 'Invalid MediaStream', error);
|
|
298
|
+
errorHandler(error);
|
|
299
|
+
|
|
300
|
+
return new Promise(function (resolve, reject) {
|
|
301
|
+
reject(error);
|
|
302
|
+
});
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
console.info(logHeader, 'Received Media Stream', stream);
|
|
306
|
+
|
|
307
|
+
instance.inputStream = stream;
|
|
308
|
+
|
|
309
|
+
let elem = instance.videoElement;
|
|
310
|
+
|
|
311
|
+
// Attach stream to video element when video element is provided.
|
|
312
|
+
if (elem) {
|
|
313
|
+
elem.srcObject = stream;
|
|
314
|
+
|
|
315
|
+
elem.onloadedmetadata = function (e) {
|
|
316
|
+
elem.play();
|
|
317
|
+
};
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
return new Promise(function (resolve) {
|
|
321
|
+
resolve(stream);
|
|
322
|
+
});
|
|
323
|
+
}
|
|
324
|
+
|
|
292
325
|
// From https://webrtchacks.com/limit-webrtc-bandwidth-sdp/
|
|
293
326
|
function setBitrateLimit(sdp, media, bitrate) {
|
|
294
327
|
|
|
@@ -780,6 +813,11 @@ function addMethod(instance) {
|
|
|
780
813
|
return getDisplayMedia(constraints);
|
|
781
814
|
};
|
|
782
815
|
|
|
816
|
+
instance.setMediaStream = function (stream) {
|
|
817
|
+
|
|
818
|
+
return setMediaStream(stream);
|
|
819
|
+
};
|
|
820
|
+
|
|
783
821
|
instance.startStreaming = function (connectionUrl, connectionConfig) {
|
|
784
822
|
|
|
785
823
|
console.info(logEventHeader, 'Start Streaming with connectionConfig', connectionConfig);
|