@antmedia/videojs-webrtc-plugin
Advanced tools
Comparing version 1.0.0 to 1.1.0
@@ -1,16 +0,14 @@ | ||
/*! @name @antmedia/videojs-webrtc-plugin @version 1.0.0 @license MIT */ | ||
/*! @name @antmedia/videojs-webrtc-plugin @version 1.1.0 @license MIT */ | ||
'use strict'; | ||
var _inheritsLoose = require('@babel/runtime/helpers/inheritsLoose'); | ||
var videojs = require('video.js'); | ||
var _assertThisInitialized = require('@babel/runtime/helpers/assertThisInitialized'); | ||
var _inheritsLoose = require('@babel/runtime/helpers/inheritsLoose'); | ||
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; } | ||
var _inheritsLoose__default = /*#__PURE__*/_interopDefaultLegacy(_inheritsLoose); | ||
var videojs__default = /*#__PURE__*/_interopDefaultLegacy(videojs); | ||
var _assertThisInitialized__default = /*#__PURE__*/_interopDefaultLegacy(_assertThisInitialized); | ||
var _inheritsLoose__default = /*#__PURE__*/_interopDefaultLegacy(_inheritsLoose); | ||
var version = "1.0.0"; | ||
var COMMANDS = { | ||
@@ -249,5 +247,2 @@ TAKE_CANDIDATE: 'takeCandidate', | ||
// so that the stream can be played (stream cannot be played without source) | ||
var DEFAULT_VIDEO_FALLBACK = 'http://vjs.zencdn.net/v/oceans.mp4'; | ||
/** | ||
@@ -351,6 +346,2 @@ * Adaptor for WebRTC methods | ||
if (this.remoteVideo) { | ||
this.remoteVideo.src({ | ||
type: 'video/mp4', | ||
src: DEFAULT_VIDEO_FALLBACK | ||
}); | ||
var vid = this.remoteVideo.tech().el(); | ||
@@ -661,7 +652,7 @@ | ||
var MenuItem = videojs__default["default"].getComponent('MenuItem'); | ||
var Component = videojs__default["default"].getComponent('Component'); | ||
var MenuItem = videojs__default['default'].getComponent('MenuItem'); | ||
var Component = videojs__default['default'].getComponent('Component'); | ||
var ResolutionMenuItem = /*#__PURE__*/function (_MenuItem) { | ||
_inheritsLoose__default["default"](ResolutionMenuItem, _MenuItem); | ||
_inheritsLoose__default['default'](ResolutionMenuItem, _MenuItem); | ||
@@ -685,6 +676,6 @@ function ResolutionMenuItem(player, options) { | ||
var MenuButton = videojs__default["default"].getComponent('MenuButton'); | ||
var MenuButton = videojs__default['default'].getComponent('MenuButton'); | ||
var ResolutionMenuButton = /*#__PURE__*/function (_MenuButton) { | ||
_inheritsLoose__default["default"](ResolutionMenuButton, _MenuButton); | ||
_inheritsLoose__default['default'](ResolutionMenuButton, _MenuButton); | ||
@@ -695,3 +686,3 @@ function ResolutionMenuButton(player, options) { | ||
_this = _MenuButton.call(this, player, options) || this; | ||
MenuButton.apply(_assertThisInitialized__default["default"](_this), arguments); | ||
MenuButton.apply(_assertThisInitialized__default['default'](_this), arguments); | ||
return _this; | ||
@@ -703,3 +694,3 @@ } | ||
_proto.createEl = function createEl() { | ||
return videojs__default["default"].dom.createEl('div', { | ||
return videojs__default['default'].dom.createEl('div', { | ||
className: 'vjs-http-source-selector vjs-menu-button vjs-menu-button-popup vjs-control vjs-button' | ||
@@ -740,4 +731,2 @@ }); | ||
var Plugin = videojs__default["default"].getPlugin('plugin'); // Default options for the plugin. | ||
var defaults = { | ||
@@ -757,30 +746,25 @@ sdpConstraints: { | ||
var AntmediaWebrtc = /*#__PURE__*/function (_Plugin) { | ||
_inheritsLoose__default["default"](AntmediaWebrtc, _Plugin); | ||
var WebRTCHandler = /*#__PURE__*/function () { | ||
/** | ||
* Create a AntmediaWebrtc plugin instance. | ||
* Create a WebRTC source handler instance. | ||
* | ||
* @param {Player} player | ||
* A Video.js Player instance. | ||
* @param {Object} source | ||
* Source object that is given in the DOM, includes the stream URL | ||
* | ||
* @param {Object} [options] | ||
* An optional options object. | ||
* | ||
* While not a core part of the Video.js plugin architecture, a | ||
* second argument of options is a convenient way to accept inputs | ||
* from your plugin's caller. | ||
* Options include: | ||
* ICE Server | ||
* Tokens | ||
* Subscriber ID | ||
* Subscriber code | ||
*/ | ||
function AntmediaWebrtc(player, options) { | ||
var _this; | ||
function WebRTCHandler(source, tech, options) { | ||
var _this = this; | ||
_this = _Plugin.call(this, player) || this; | ||
_this.initiateWebRTCAdaptor(options); | ||
_this.player.ready(function () { | ||
this.player = videojs__default['default'](options.playerId); | ||
this.initiateWebRTCAdaptor(source, options); | ||
this.player.ready(function () { | ||
_this.player.addClass('videojs-webrtc-plugin'); | ||
}); | ||
_this.player.on('playing', function () { | ||
this.player.on('playing', function () { | ||
if (_this.player.el().getElementsByClassName('vjs-custom-spinner').length) { | ||
@@ -790,6 +774,4 @@ _this.player.el().removeChild(_this.player.spinner); | ||
}); | ||
videojs__default["default"].registerComponent('ResolutionMenuButton', ResolutionMenuButton); | ||
videojs__default["default"].registerComponent('ResolutionMenuItem', ResolutionMenuItem); | ||
return _this; | ||
videojs__default['default'].registerComponent('ResolutionMenuButton', ResolutionMenuButton); | ||
videojs__default['default'].registerComponent('ResolutionMenuItem', ResolutionMenuItem); | ||
} | ||
@@ -805,21 +787,22 @@ /** | ||
var _proto = AntmediaWebrtc.prototype; | ||
var _proto = WebRTCHandler.prototype; | ||
_proto.initiateWebRTCAdaptor = function initiateWebRTCAdaptor(options) { | ||
_proto.initiateWebRTCAdaptor = function initiateWebRTCAdaptor(source, options) { | ||
var _this2 = this; | ||
this.options = videojs__default["default"].mergeOptions(defaults, options); | ||
this.options.pcConfig = { | ||
iceServers: JSON.parse(options.iceServers) | ||
this.options = videojs__default['default'].mergeOptions(defaults, options); | ||
this.source = source; | ||
this.source.pcConfig = { | ||
iceServers: JSON.parse(source.iceservers) | ||
}; | ||
this.options.mediaServerUrl = options.streamUrl.split('?')[0]; | ||
this.options.streamName = this.getUrlParameter('streamId'); | ||
this.options.token = this.getUrlParameter('token'); | ||
this.options.subscriberId = this.getUrlParameter('subscriberId'); | ||
this.options.subscriberCode = this.getUrlParameter('subscriberCode'); | ||
this.source.mediaServerUrl = source.src.split('/').slice(0, 4).join('/') + "/websocket"; | ||
this.source.streamName = source.src.split('/')[4].split('.webrtc')[0]; | ||
this.source.token = this.getUrlParameter('token'); | ||
this.source.subscriberId = this.getUrlParameter('subscriberId'); | ||
this.source.subscriberCode = this.getUrlParameter('subscriberCode'); | ||
this.webRTCAdaptor = new WebRTCAdaptor({ | ||
websocketUrl: this.options.mediaServerUrl, | ||
mediaConstraints: this.options.mediaConstraints, | ||
pcConfig: this.options.pcConfig, | ||
sdpConstraints: this.options.sdpConstraints, | ||
websocketUrl: this.source.mediaServerUrl, | ||
mediaConstraints: this.source.mediaConstraints, | ||
pcConfig: this.source.pcConfig, | ||
sdpConstraints: this.source.sdpConstraints, | ||
player: this.player, | ||
@@ -874,3 +857,3 @@ callback: function callback(info, obj) { | ||
// some of the possible errors, NotFoundError, SecurityError,PermissionDeniedError | ||
var ModalDialog = videojs__default["default"].getComponent('ModalDialog'); | ||
var ModalDialog = videojs__default['default'].getComponent('ModalDialog'); | ||
@@ -895,2 +878,6 @@ if (_this2.errorModal) { | ||
}, 3000); | ||
_this2.player.trigger('webrtc-error', { | ||
error: error | ||
}); | ||
} | ||
@@ -905,3 +892,3 @@ }); | ||
_proto.initializedHandler = function initializedHandler() { | ||
this.webRTCAdaptor.play(this.options.streamName, this.options.token, this.options.subscriberId, this.options.subscriberCode); | ||
this.webRTCAdaptor.play(this.source.streamName, this.source.token, this.source.subscriberId, this.source.subscriberCode); | ||
} | ||
@@ -916,3 +903,3 @@ /** | ||
_proto.joinStreamHandler = function joinStreamHandler(obj) { | ||
this.webRTCAdaptor.getStreamInfo(this.options.streamName); | ||
this.webRTCAdaptor.getStreamInfo(this.source.streamName); | ||
} | ||
@@ -962,3 +949,3 @@ /** | ||
plugin: this, | ||
streamName: this.options.streamName | ||
streamName: this.source.streamName | ||
}).el(), fullscreenToggle); | ||
@@ -1001,3 +988,3 @@ } | ||
_proto.changeStreamQuality = function changeStreamQuality(value) { | ||
this.webRTCAdaptor.forceStreamQuality(this.options.streamName, value); | ||
this.webRTCAdaptor.forceStreamQuality(this.source.streamName, value); | ||
this.player.selectedResolution = value; | ||
@@ -1014,20 +1001,60 @@ this.player.controlBar.getChild('ResolutionMenuButton').update(); | ||
_proto.getUrlParameter = function getUrlParameter(param) { | ||
var urlParams = this.options.streamUrl.split('?')[1].split('&').reduce(function (p, e) { | ||
var a = e.split('='); | ||
p[decodeURIComponent(a[0])] = decodeURIComponent(a[1]); | ||
return p; | ||
}, {}); | ||
return urlParams[param]; | ||
if (this.source.src.includes('?')) { | ||
var urlParams = this.source.src.split('?')[1].split('&').reduce(function (p, e) { | ||
var a = e.split('='); | ||
p[decodeURIComponent(a[0])] = decodeURIComponent(a[1]); | ||
return p; | ||
}, {}) || {}; | ||
return urlParams[param]; | ||
} | ||
return null; | ||
}; | ||
return AntmediaWebrtc; | ||
}(Plugin); // Define default values for the plugin's `state` object here. | ||
return WebRTCHandler; | ||
}(); | ||
var webRTCSourceHandler = { | ||
name: 'videojs-webrtc-plugin', | ||
VERSION: '1.1', | ||
canHandleSource: function canHandleSource(srcObj, options) { | ||
if (options === void 0) { | ||
options = {}; | ||
} | ||
AntmediaWebrtc.defaultState = {}; // Include the version number. | ||
var localOptions = videojs__default['default'].mergeOptions(videojs__default['default'].options, options); | ||
localOptions.source = srcObj.src; | ||
return webRTCSourceHandler.canPlayType(srcObj.type, localOptions); | ||
}, | ||
handleSource: function handleSource(source, tech, options) { | ||
if (options === void 0) { | ||
options = {}; | ||
} | ||
AntmediaWebrtc.VERSION = version; // Register the plugin with video.js. | ||
var localOptions = videojs__default['default'].mergeOptions(videojs__default['default'].options, options); // Register the plugin to source handler tech | ||
videojs__default["default"].registerPlugin('antmediaWebrtc', AntmediaWebrtc); | ||
tech.webrtc = new WebRTCHandler(source, tech, localOptions); | ||
return tech.webrtc; | ||
}, | ||
canPlayType: function canPlayType(type, options) { | ||
if (options === void 0) { | ||
options = {}; | ||
} | ||
module.exports = AntmediaWebrtc; | ||
var mediaUrl = options.source; | ||
if (mediaUrl.split('/')[4].includes('.webrtc')) { | ||
return 'maybe'; | ||
} | ||
return ''; | ||
} | ||
}; // register source handlers with the appropriate techs | ||
videojs__default['default'].getTech('Html5').registerSourceHandler(webRTCSourceHandler, 0); | ||
var plugin = { | ||
WebRTCHandler: WebRTCHandler, | ||
webRTCSourceHandler: webRTCSourceHandler | ||
}; | ||
module.exports = plugin; |
@@ -1,8 +0,6 @@ | ||
/*! @name @antmedia/videojs-webrtc-plugin @version 1.0.0 @license MIT */ | ||
import _inheritsLoose from '@babel/runtime/helpers/inheritsLoose'; | ||
/*! @name @antmedia/videojs-webrtc-plugin @version 1.1.0 @license MIT */ | ||
import videojs from 'video.js'; | ||
import _assertThisInitialized from '@babel/runtime/helpers/assertThisInitialized'; | ||
import _inheritsLoose from '@babel/runtime/helpers/inheritsLoose'; | ||
var version = "1.0.0"; | ||
var COMMANDS = { | ||
@@ -241,5 +239,2 @@ TAKE_CANDIDATE: 'takeCandidate', | ||
// so that the stream can be played (stream cannot be played without source) | ||
var DEFAULT_VIDEO_FALLBACK = 'http://vjs.zencdn.net/v/oceans.mp4'; | ||
/** | ||
@@ -343,6 +338,2 @@ * Adaptor for WebRTC methods | ||
if (this.remoteVideo) { | ||
this.remoteVideo.src({ | ||
type: 'video/mp4', | ||
src: DEFAULT_VIDEO_FALLBACK | ||
}); | ||
var vid = this.remoteVideo.tech().el(); | ||
@@ -728,4 +719,2 @@ | ||
var Plugin = videojs.getPlugin('plugin'); // Default options for the plugin. | ||
var defaults = { | ||
@@ -745,30 +734,25 @@ sdpConstraints: { | ||
var AntmediaWebrtc = /*#__PURE__*/function (_Plugin) { | ||
_inheritsLoose(AntmediaWebrtc, _Plugin); | ||
var WebRTCHandler = /*#__PURE__*/function () { | ||
/** | ||
* Create a AntmediaWebrtc plugin instance. | ||
* Create a WebRTC source handler instance. | ||
* | ||
* @param {Player} player | ||
* A Video.js Player instance. | ||
* @param {Object} source | ||
* Source object that is given in the DOM, includes the stream URL | ||
* | ||
* @param {Object} [options] | ||
* An optional options object. | ||
* | ||
* While not a core part of the Video.js plugin architecture, a | ||
* second argument of options is a convenient way to accept inputs | ||
* from your plugin's caller. | ||
* Options include: | ||
* ICE Server | ||
* Tokens | ||
* Subscriber ID | ||
* Subscriber code | ||
*/ | ||
function AntmediaWebrtc(player, options) { | ||
var _this; | ||
function WebRTCHandler(source, tech, options) { | ||
var _this = this; | ||
_this = _Plugin.call(this, player) || this; | ||
_this.initiateWebRTCAdaptor(options); | ||
_this.player.ready(function () { | ||
this.player = videojs(options.playerId); | ||
this.initiateWebRTCAdaptor(source, options); | ||
this.player.ready(function () { | ||
_this.player.addClass('videojs-webrtc-plugin'); | ||
}); | ||
_this.player.on('playing', function () { | ||
this.player.on('playing', function () { | ||
if (_this.player.el().getElementsByClassName('vjs-custom-spinner').length) { | ||
@@ -778,6 +762,4 @@ _this.player.el().removeChild(_this.player.spinner); | ||
}); | ||
videojs.registerComponent('ResolutionMenuButton', ResolutionMenuButton); | ||
videojs.registerComponent('ResolutionMenuItem', ResolutionMenuItem); | ||
return _this; | ||
} | ||
@@ -793,21 +775,22 @@ /** | ||
var _proto = AntmediaWebrtc.prototype; | ||
var _proto = WebRTCHandler.prototype; | ||
_proto.initiateWebRTCAdaptor = function initiateWebRTCAdaptor(options) { | ||
_proto.initiateWebRTCAdaptor = function initiateWebRTCAdaptor(source, options) { | ||
var _this2 = this; | ||
this.options = videojs.mergeOptions(defaults, options); | ||
this.options.pcConfig = { | ||
iceServers: JSON.parse(options.iceServers) | ||
this.source = source; | ||
this.source.pcConfig = { | ||
iceServers: JSON.parse(source.iceservers) | ||
}; | ||
this.options.mediaServerUrl = options.streamUrl.split('?')[0]; | ||
this.options.streamName = this.getUrlParameter('streamId'); | ||
this.options.token = this.getUrlParameter('token'); | ||
this.options.subscriberId = this.getUrlParameter('subscriberId'); | ||
this.options.subscriberCode = this.getUrlParameter('subscriberCode'); | ||
this.source.mediaServerUrl = source.src.split('/').slice(0, 4).join('/') + "/websocket"; | ||
this.source.streamName = source.src.split('/')[4].split('.webrtc')[0]; | ||
this.source.token = this.getUrlParameter('token'); | ||
this.source.subscriberId = this.getUrlParameter('subscriberId'); | ||
this.source.subscriberCode = this.getUrlParameter('subscriberCode'); | ||
this.webRTCAdaptor = new WebRTCAdaptor({ | ||
websocketUrl: this.options.mediaServerUrl, | ||
mediaConstraints: this.options.mediaConstraints, | ||
pcConfig: this.options.pcConfig, | ||
sdpConstraints: this.options.sdpConstraints, | ||
websocketUrl: this.source.mediaServerUrl, | ||
mediaConstraints: this.source.mediaConstraints, | ||
pcConfig: this.source.pcConfig, | ||
sdpConstraints: this.source.sdpConstraints, | ||
player: this.player, | ||
@@ -882,2 +865,6 @@ callback: function callback(info, obj) { | ||
}, 3000); | ||
_this2.player.trigger('webrtc-error', { | ||
error: error | ||
}); | ||
} | ||
@@ -892,3 +879,3 @@ }); | ||
_proto.initializedHandler = function initializedHandler() { | ||
this.webRTCAdaptor.play(this.options.streamName, this.options.token, this.options.subscriberId, this.options.subscriberCode); | ||
this.webRTCAdaptor.play(this.source.streamName, this.source.token, this.source.subscriberId, this.source.subscriberCode); | ||
} | ||
@@ -903,3 +890,3 @@ /** | ||
_proto.joinStreamHandler = function joinStreamHandler(obj) { | ||
this.webRTCAdaptor.getStreamInfo(this.options.streamName); | ||
this.webRTCAdaptor.getStreamInfo(this.source.streamName); | ||
} | ||
@@ -949,3 +936,3 @@ /** | ||
plugin: this, | ||
streamName: this.options.streamName | ||
streamName: this.source.streamName | ||
}).el(), fullscreenToggle); | ||
@@ -988,3 +975,3 @@ } | ||
_proto.changeStreamQuality = function changeStreamQuality(value) { | ||
this.webRTCAdaptor.forceStreamQuality(this.options.streamName, value); | ||
this.webRTCAdaptor.forceStreamQuality(this.source.streamName, value); | ||
this.player.selectedResolution = value; | ||
@@ -1001,20 +988,60 @@ this.player.controlBar.getChild('ResolutionMenuButton').update(); | ||
_proto.getUrlParameter = function getUrlParameter(param) { | ||
var urlParams = this.options.streamUrl.split('?')[1].split('&').reduce(function (p, e) { | ||
var a = e.split('='); | ||
p[decodeURIComponent(a[0])] = decodeURIComponent(a[1]); | ||
return p; | ||
}, {}); | ||
return urlParams[param]; | ||
if (this.source.src.includes('?')) { | ||
var urlParams = this.source.src.split('?')[1].split('&').reduce(function (p, e) { | ||
var a = e.split('='); | ||
p[decodeURIComponent(a[0])] = decodeURIComponent(a[1]); | ||
return p; | ||
}, {}) || {}; | ||
return urlParams[param]; | ||
} | ||
return null; | ||
}; | ||
return AntmediaWebrtc; | ||
}(Plugin); // Define default values for the plugin's `state` object here. | ||
return WebRTCHandler; | ||
}(); | ||
var webRTCSourceHandler = { | ||
name: 'videojs-webrtc-plugin', | ||
VERSION: '1.1', | ||
canHandleSource: function canHandleSource(srcObj, options) { | ||
if (options === void 0) { | ||
options = {}; | ||
} | ||
AntmediaWebrtc.defaultState = {}; // Include the version number. | ||
var localOptions = videojs.mergeOptions(videojs.options, options); | ||
localOptions.source = srcObj.src; | ||
return webRTCSourceHandler.canPlayType(srcObj.type, localOptions); | ||
}, | ||
handleSource: function handleSource(source, tech, options) { | ||
if (options === void 0) { | ||
options = {}; | ||
} | ||
AntmediaWebrtc.VERSION = version; // Register the plugin with video.js. | ||
var localOptions = videojs.mergeOptions(videojs.options, options); // Register the plugin to source handler tech | ||
videojs.registerPlugin('antmediaWebrtc', AntmediaWebrtc); | ||
tech.webrtc = new WebRTCHandler(source, tech, localOptions); | ||
return tech.webrtc; | ||
}, | ||
canPlayType: function canPlayType(type, options) { | ||
if (options === void 0) { | ||
options = {}; | ||
} | ||
export { AntmediaWebrtc as default }; | ||
var mediaUrl = options.source; | ||
if (mediaUrl.split('/')[4].includes('.webrtc')) { | ||
return 'maybe'; | ||
} | ||
return ''; | ||
} | ||
}; // register source handlers with the appropriate techs | ||
videojs.getTech('Html5').registerSourceHandler(webRTCSourceHandler, 0); | ||
var plugin = { | ||
WebRTCHandler: WebRTCHandler, | ||
webRTCSourceHandler: webRTCSourceHandler | ||
}; | ||
export default plugin; |
@@ -1,1064 +0,1096 @@ | ||
/*! @name @antmedia/videojs-webrtc-plugin @version 1.0.0 @license MIT */ | ||
/*! @name @antmedia/videojs-webrtc-plugin @version 1.1.0 @license MIT */ | ||
(function (global, factory) { | ||
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('video.js')) : | ||
typeof define === 'function' && define.amd ? define(['video.js'], factory) : | ||
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.videojsWebrtcPlugin = factory(global.videojs)); | ||
})(this, (function (videojs) { 'use strict'; | ||
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('video.js')) : | ||
typeof define === 'function' && define.amd ? define(['video.js'], factory) : | ||
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.videojsWebrtcPlugin = factory(global.videojs)); | ||
}(this, (function (videojs) { 'use strict'; | ||
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; } | ||
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; } | ||
var videojs__default = /*#__PURE__*/_interopDefaultLegacy(videojs); | ||
var videojs__default = /*#__PURE__*/_interopDefaultLegacy(videojs); | ||
function createCommonjsModule(fn, basedir, module) { | ||
return module = { | ||
path: basedir, | ||
exports: {}, | ||
require: function (path, base) { | ||
return commonjsRequire(path, (base === undefined || base === null) ? module.path : base); | ||
} | ||
}, fn(module, module.exports), module.exports; | ||
} | ||
var COMMANDS = { | ||
TAKE_CANDIDATE: 'takeCandidate', | ||
TAKE_CONFIGURATION: 'takeConfiguration', | ||
PLAY: 'play', | ||
STOP: 'stop', | ||
GET_STREAM_INFO: 'getStreamInfo', | ||
PEER_MESSAGE_COMMAND: 'peerMessageCommand', | ||
FORCE_STREAM_QUALITY: 'forceStreamQuality', | ||
ERROR: 'error', | ||
NOTIFICATION: 'notification', | ||
STREAM_INFORMATION: 'streamInformation', | ||
PING: 'ping', | ||
PONG: 'pong', | ||
TRACK_LIST: 'trackList' | ||
}; | ||
function commonjsRequire () { | ||
throw new Error('Dynamic requires are not currently supported by @rollup/plugin-commonjs'); | ||
} | ||
/** | ||
* WebSocketAdaptor for communication via webSocket | ||
*/ | ||
var WebSocketAdaptor = /*#__PURE__*/function () { | ||
/** | ||
* Create a WebSocketAdaptor instance for communication via webSocket. | ||
* | ||
* @param {Object} [initialValues] | ||
* An initialValues object. | ||
* | ||
*/ | ||
function WebSocketAdaptor(initialValues) { | ||
for (var key in initialValues) { | ||
if (initialValues.hasOwnProperty(key)) { | ||
this[key] = initialValues[key]; | ||
} | ||
} | ||
var setPrototypeOf = createCommonjsModule(function (module) { | ||
function _setPrototypeOf(o, p) { | ||
module.exports = _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { | ||
o.__proto__ = p; | ||
return o; | ||
}, module.exports.__esModule = true, module.exports["default"] = module.exports; | ||
return _setPrototypeOf(o, p); | ||
} | ||
this.initWebSocketConnection(); | ||
} | ||
/** | ||
* Initiate websocket connection. | ||
* | ||
* @param {function} callbackConnected callback if connected | ||
*/ | ||
module.exports = _setPrototypeOf, module.exports.__esModule = true, module.exports["default"] = module.exports; | ||
}); | ||
var inheritsLoose = createCommonjsModule(function (module) { | ||
function _inheritsLoose(subClass, superClass) { | ||
subClass.prototype = Object.create(superClass.prototype); | ||
subClass.prototype.constructor = subClass; | ||
setPrototypeOf(subClass, superClass); | ||
} | ||
var _proto = WebSocketAdaptor.prototype; | ||
module.exports = _inheritsLoose, module.exports.__esModule = true, module.exports["default"] = module.exports; | ||
}); | ||
_proto.initWebSocketConnection = function initWebSocketConnection(callbackConnected) { | ||
var _this = this; | ||
var version = "1.0.0"; | ||
this.connecting = true; | ||
this.connected = false; | ||
this.pingTimerId = -1; // eslint-disable-next-line no-undef | ||
var COMMANDS = { | ||
TAKE_CANDIDATE: 'takeCandidate', | ||
TAKE_CONFIGURATION: 'takeConfiguration', | ||
PLAY: 'play', | ||
STOP: 'stop', | ||
GET_STREAM_INFO: 'getStreamInfo', | ||
PEER_MESSAGE_COMMAND: 'peerMessageCommand', | ||
FORCE_STREAM_QUALITY: 'forceStreamQuality', | ||
ERROR: 'error', | ||
NOTIFICATION: 'notification', | ||
STREAM_INFORMATION: 'streamInformation', | ||
PING: 'ping', | ||
PONG: 'pong', | ||
TRACK_LIST: 'trackList' | ||
}; | ||
this.wsConn = new WebSocket(this.websocketUrl); | ||
/** | ||
* WebSocketAdaptor for communication via webSocket | ||
*/ | ||
var WebSocketAdaptor = /*#__PURE__*/function () { | ||
/** | ||
* Create a WebSocketAdaptor instance for communication via webSocket. | ||
* | ||
* @param {Object} [initialValues] | ||
* An initialValues object. | ||
* | ||
*/ | ||
function WebSocketAdaptor(initialValues) { | ||
for (var key in initialValues) { | ||
if (initialValues.hasOwnProperty(key)) { | ||
this[key] = initialValues[key]; | ||
} | ||
} | ||
this.wsConn.onopen = function () { | ||
_this.pingTimerId = setInterval(function () { | ||
_this.sendPing(); | ||
}, 3000); | ||
_this.connected = true; | ||
_this.connecting = false; | ||
this.initWebSocketConnection(); | ||
} | ||
/** | ||
* Initiate websocket connection. | ||
* | ||
* @param {function} callbackConnected callback if connected | ||
*/ | ||
_this.callback('initialized'); | ||
if (typeof callbackConnected !== 'undefined') { | ||
callbackConnected(); | ||
} | ||
}; | ||
var _proto = WebSocketAdaptor.prototype; | ||
this.wsConn.onmessage = function (event) { | ||
var obj = JSON.parse(event.data); | ||
_proto.initWebSocketConnection = function initWebSocketConnection(callbackConnected) { | ||
var _this = this; | ||
switch (obj.command) { | ||
case COMMANDS.TAKE_CANDIDATE: | ||
{ | ||
_this.webrtcadaptor.takeCandidate(obj.streamId, obj.label, obj.candidate); | ||
this.connecting = true; | ||
this.connected = false; | ||
this.pingTimerId = -1; // eslint-disable-next-line no-undef | ||
break; | ||
} | ||
this.wsConn = new WebSocket(this.websocketUrl); | ||
case COMMANDS.TAKE_CONFIGURATION: | ||
{ | ||
_this.webrtcadaptor.takeConfiguration(obj.streamId, obj.sdp, obj.type, obj.idMapping); | ||
this.wsConn.onopen = function () { | ||
_this.pingTimerId = setInterval(function () { | ||
_this.sendPing(); | ||
}, 3000); | ||
_this.connected = true; | ||
_this.connecting = false; | ||
break; | ||
} | ||
_this.callback('initialized'); | ||
case COMMANDS.STOP: | ||
{ | ||
_this.webrtcadaptor.closePeerConnection(obj.streamId); | ||
if (typeof callbackConnected !== 'undefined') { | ||
callbackConnected(); | ||
} | ||
}; | ||
break; | ||
} | ||
this.wsConn.onmessage = function (event) { | ||
var obj = JSON.parse(event.data); | ||
case COMMANDS.ERROR: | ||
{ | ||
_this.callbackError(obj.definition); | ||
switch (obj.command) { | ||
case COMMANDS.TAKE_CANDIDATE: | ||
{ | ||
_this.webrtcadaptor.takeCandidate(obj.streamId, obj.label, obj.candidate); | ||
break; | ||
} | ||
break; | ||
} | ||
case COMMANDS.NOTIFICATION: | ||
{ | ||
_this.callback(obj.definition, obj); | ||
case COMMANDS.TAKE_CONFIGURATION: | ||
{ | ||
_this.webrtcadaptor.takeConfiguration(obj.streamId, obj.sdp, obj.type, obj.idMapping); | ||
if (obj.definition === 'play_finished' || obj.definition === 'publish_finished') { | ||
_this.webrtcadaptor.closePeerConnection(obj.streamId); | ||
} | ||
break; | ||
} | ||
break; | ||
} | ||
case COMMANDS.STOP: | ||
{ | ||
_this.webrtcadaptor.closePeerConnection(obj.streamId); | ||
case COMMANDS.STREAM_INFORMATION: | ||
{ | ||
_this.callback(obj.command, obj); | ||
break; | ||
} | ||
break; | ||
} | ||
case COMMANDS.ERROR: | ||
{ | ||
_this.callbackError(obj.definition); | ||
case COMMANDS.PONG: | ||
{ | ||
_this.callback(obj.command); | ||
break; | ||
} | ||
break; | ||
} | ||
case COMMANDS.NOTIFICATION: | ||
{ | ||
_this.callback(obj.definition, obj); | ||
case COMMANDS.TRACK_LIST: | ||
{ | ||
_this.callback(obj.command, obj); | ||
if (obj.definition === 'play_finished' || obj.definition === 'publish_finished') { | ||
_this.webrtcadaptor.closePeerConnection(obj.streamId); | ||
} | ||
break; | ||
} | ||
break; | ||
} | ||
case COMMANDS.PEER_MESSAGE_COMMAND: | ||
{ | ||
_this.callback(obj.command, obj); | ||
case COMMANDS.STREAM_INFORMATION: | ||
{ | ||
_this.callback(obj.command, obj); | ||
break; | ||
} | ||
} | ||
}; | ||
break; | ||
} | ||
this.wsConn.onerror = function (error) { | ||
_this.connecting = false; | ||
_this.connected = false; | ||
case COMMANDS.PONG: | ||
{ | ||
_this.callback(obj.command); | ||
_this.clearPingTimer(); | ||
break; | ||
} | ||
_this.callbackError('WebSocketNotConnected', error); | ||
}; | ||
case COMMANDS.TRACK_LIST: | ||
{ | ||
_this.callback(obj.command, obj); | ||
this.wsConn.onclose = function (event) { | ||
_this.connecting = false; | ||
_this.connected = false; | ||
break; | ||
} | ||
_this.clearPingTimer(); | ||
case COMMANDS.PEER_MESSAGE_COMMAND: | ||
{ | ||
_this.callback(obj.command, obj); | ||
_this.callback('closed', event); | ||
}; | ||
} | ||
/** | ||
* Clear websocket ping timer. | ||
*/ | ||
; | ||
break; | ||
} | ||
} | ||
}; | ||
_proto.clearPingTimer = function clearPingTimer() { | ||
if (this.pingTimerId !== -1) { | ||
clearInterval(this.pingTimerId); | ||
this.pingTimerId = -1; | ||
} | ||
} | ||
/** | ||
* send Websocket ping message. | ||
*/ | ||
; | ||
this.wsConn.onerror = function (error) { | ||
_this.connecting = false; | ||
_this.connected = false; | ||
_proto.sendPing = function sendPing() { | ||
var jsCmd = { | ||
command: COMMANDS.PING | ||
}; | ||
this.wsConn.send(JSON.stringify(jsCmd)); | ||
} | ||
/** | ||
* close Websocket connection. | ||
*/ | ||
; | ||
_this.clearPingTimer(); | ||
_proto.close = function close() { | ||
this.wsConn.close(); | ||
} | ||
/** | ||
* send Websocket message method. | ||
* | ||
* @param {string} text message | ||
*/ | ||
; | ||
_this.callbackError('WebSocketNotConnected', error); | ||
}; | ||
_proto.send = function send(text) { | ||
var _this2 = this; | ||
this.wsConn.onclose = function (event) { | ||
_this.connecting = false; | ||
_this.connected = false; | ||
if (!this.connecting && !this.connected) { | ||
// try to reconnect | ||
this.initWebSocketConnection(function () { | ||
_this2.send(text); | ||
}); | ||
return; | ||
} | ||
_this.clearPingTimer(); | ||
this.wsConn.send(text); | ||
} | ||
/** | ||
* check Websocket connection. | ||
* | ||
* @return {boolean} status of websocket connection. | ||
*/ | ||
; | ||
_this.callback('closed', event); | ||
}; | ||
} | ||
/** | ||
* Clear websocket ping timer. | ||
*/ | ||
; | ||
_proto.isConnected = function isConnected() { | ||
return this.connected; | ||
} | ||
/** | ||
* check Websocket connecting. | ||
* | ||
* @return {boolean} status of websocket connecting. | ||
*/ | ||
; | ||
_proto.clearPingTimer = function clearPingTimer() { | ||
if (this.pingTimerId !== -1) { | ||
clearInterval(this.pingTimerId); | ||
this.pingTimerId = -1; | ||
} | ||
} | ||
/** | ||
* send Websocket ping message. | ||
*/ | ||
; | ||
_proto.isConnecting = function isConnecting() { | ||
return this.connecting; | ||
}; | ||
_proto.sendPing = function sendPing() { | ||
var jsCmd = { | ||
command: COMMANDS.PING | ||
}; | ||
this.wsConn.send(JSON.stringify(jsCmd)); | ||
} | ||
/** | ||
* close Websocket connection. | ||
*/ | ||
; | ||
return WebSocketAdaptor; | ||
}(); | ||
_proto.close = function close() { | ||
this.wsConn.close(); | ||
} | ||
/** | ||
* send Websocket message method. | ||
* | ||
* @param {string} text message | ||
*/ | ||
; | ||
/** | ||
* Adaptor for WebRTC methods | ||
*/ | ||
_proto.send = function send(text) { | ||
var _this2 = this; | ||
var WebRTCAdaptor = /*#__PURE__*/function () { | ||
/** | ||
* Create a WebRTCAdaptor instance. | ||
* | ||
* @param {Object} initialValues | ||
* A WebRTCAdaptor initial values. | ||
* | ||
*/ | ||
function WebRTCAdaptor(initialValues) { | ||
this.pcConfig = null; | ||
this.websocketUrl = null; | ||
this.sdpConstraints = null; | ||
this.remotePeerConnection = []; | ||
this.remoteDescriptionSet = []; | ||
this.iceCandidateList = []; | ||
this.playStreamId = []; | ||
this.player = null; | ||
this.webSocketAdaptor = null; | ||
this.viewerInfo = ''; | ||
this.idMapping = []; | ||
this.candidateTypes = ['udp', 'tcp']; | ||
if (!this.connecting && !this.connected) { | ||
// try to reconnect | ||
this.initWebSocketConnection(function () { | ||
_this2.send(text); | ||
}); | ||
return; | ||
} | ||
for (var key in initialValues) { | ||
if (initialValues.hasOwnProperty(key)) { | ||
this[key] = initialValues[key]; | ||
} | ||
} | ||
this.wsConn.send(text); | ||
} | ||
/** | ||
* check Websocket connection. | ||
* | ||
* @return {boolean} status of websocket connection. | ||
*/ | ||
; | ||
this.remoteVideo = this.player; | ||
this.checkWebSocketConnection(); | ||
} | ||
/** | ||
* play WebRTC stream. | ||
* | ||
* @param {string} streamId stream Id | ||
* @param {string} token stream token (opt) | ||
* @param {string} subscriberId subscriberId (opt) | ||
* @param {string} subscriberCode subscriberCode (opt) | ||
*/ | ||
_proto.isConnected = function isConnected() { | ||
return this.connected; | ||
} | ||
/** | ||
* check Websocket connecting. | ||
* | ||
* @return {boolean} status of websocket connecting. | ||
*/ | ||
; | ||
_proto.isConnecting = function isConnecting() { | ||
return this.connecting; | ||
}; | ||
var _proto = WebRTCAdaptor.prototype; | ||
return WebSocketAdaptor; | ||
}(); | ||
_proto.play = function play(streamId, token, subscriberId, subscriberCode) { | ||
this.playStreamId.push(streamId); | ||
var jsCmd = { | ||
command: COMMANDS.PLAY, | ||
streamId: streamId, | ||
token: token, | ||
subscriberId: subscriberId ? subscriberId : '', | ||
subscriberCode: subscriberCode ? subscriberCode : '', | ||
viewerInfo: this.viewerInfo | ||
}; | ||
this.webSocketAdaptor.send(JSON.stringify(jsCmd)); | ||
} | ||
/** | ||
* stop playing WebRTC stream. | ||
* | ||
* @param {string} streamId stream Id | ||
*/ | ||
; | ||
// so that the stream can be played (stream cannot be played without source) | ||
_proto.stop = function stop(streamId) { | ||
this.closePeerConnection(streamId); | ||
var jsCmd = { | ||
command: COMMANDS.STOP, | ||
streamId: streamId | ||
}; | ||
this.webSocketAdaptor.send(JSON.stringify(jsCmd)); | ||
} | ||
/** | ||
* get info about WebRTC stream. | ||
* | ||
* @param {string} streamId stream Id | ||
*/ | ||
; | ||
var DEFAULT_VIDEO_FALLBACK = 'http://vjs.zencdn.net/v/oceans.mp4'; | ||
/** | ||
* Adaptor for WebRTC methods | ||
*/ | ||
_proto.getStreamInfo = function getStreamInfo(streamId) { | ||
var jsCmd = { | ||
command: COMMANDS.GET_STREAM_INFO, | ||
streamId: streamId | ||
}; | ||
this.webSocketAdaptor.send(JSON.stringify(jsCmd)); | ||
} | ||
/** | ||
* WebRTC onTrack event. | ||
* | ||
* @param {Object} event event object | ||
* @param {string} streamId stream Id | ||
*/ | ||
; | ||
var WebRTCAdaptor = /*#__PURE__*/function () { | ||
/** | ||
* Create a WebRTCAdaptor instance. | ||
* | ||
* @param {Object} initialValues | ||
* A WebRTCAdaptor initial values. | ||
* | ||
*/ | ||
function WebRTCAdaptor(initialValues) { | ||
this.pcConfig = null; | ||
this.websocketUrl = null; | ||
this.sdpConstraints = null; | ||
this.remotePeerConnection = []; | ||
this.remoteDescriptionSet = []; | ||
this.iceCandidateList = []; | ||
this.playStreamId = []; | ||
this.player = null; | ||
this.webSocketAdaptor = null; | ||
this.viewerInfo = ''; | ||
this.idMapping = []; | ||
this.candidateTypes = ['udp', 'tcp']; | ||
_proto.onTrack = function onTrack(event, streamId) { | ||
if (this.remoteVideo) { | ||
var vid = this.remoteVideo.tech().el(); | ||
for (var key in initialValues) { | ||
if (initialValues.hasOwnProperty(key)) { | ||
this[key] = initialValues[key]; | ||
} | ||
} | ||
if (vid.srcObject !== event.streams[0]) { | ||
vid.srcObject = event.streams[0]; | ||
} | ||
} | ||
} | ||
/** | ||
* Receive iceCandidate handler. | ||
* | ||
* @param {Object} event event object | ||
* @param {string} streamId stream Id | ||
*/ | ||
; | ||
this.remoteVideo = this.player; | ||
this.checkWebSocketConnection(); | ||
} | ||
/** | ||
* play WebRTC stream. | ||
* | ||
* @param {string} streamId stream Id | ||
* @param {string} token stream token (opt) | ||
* @param {string} subscriberId subscriberId (opt) | ||
* @param {string} subscriberCode subscriberCode (opt) | ||
*/ | ||
_proto.iceCandidateReceived = function iceCandidateReceived(event, streamId) { | ||
if (event.candidate) { | ||
var protocolSupported = false; | ||
if (event.candidate.candidate === '') { | ||
// event candidate can be received and its value can be "". | ||
// don't compare the protocols | ||
protocolSupported = true; | ||
} else if (typeof event.candidate.protocol === 'undefined') { | ||
this.candidateTypes.forEach(function (element) { | ||
if (event.candidate.candidate.toLowerCase().includes(element)) { | ||
protocolSupported = true; | ||
} | ||
}); | ||
} else { | ||
protocolSupported = this.candidateTypes.includes(event.candidate.protocol.toLowerCase()); | ||
} | ||
var _proto = WebRTCAdaptor.prototype; | ||
if (protocolSupported) { | ||
var jsCmd = { | ||
command: COMMANDS.TAKE_CANDIDATE, | ||
streamId: streamId, | ||
label: event.candidate.sdpMLineIndex, | ||
id: event.candidate.sdpMid, | ||
candidate: event.candidate.candidate | ||
}; | ||
this.webSocketAdaptor.send(JSON.stringify(jsCmd)); | ||
} else if (event.candidate.candidate !== '') { | ||
this.callbackError('protocol_not_supported', 'Support protocols: ' + this.candidateTypes.toString() + ' candidate: ' + event.candidate.candidate); | ||
} | ||
} | ||
} | ||
/** | ||
* Initiate WebRtc PeerConnection. | ||
* | ||
* @param {string} streamId stream Id | ||
*/ | ||
; | ||
_proto.play = function play(streamId, token, subscriberId, subscriberCode) { | ||
this.playStreamId.push(streamId); | ||
var jsCmd = { | ||
command: COMMANDS.PLAY, | ||
streamId: streamId, | ||
token: token, | ||
subscriberId: subscriberId ? subscriberId : '', | ||
subscriberCode: subscriberCode ? subscriberCode : '', | ||
viewerInfo: this.viewerInfo | ||
}; | ||
this.webSocketAdaptor.send(JSON.stringify(jsCmd)); | ||
} | ||
/** | ||
* stop playing WebRTC stream. | ||
* | ||
* @param {string} streamId stream Id | ||
*/ | ||
; | ||
_proto.initPeerConnection = function initPeerConnection(streamId) { | ||
var _this = this; | ||
_proto.stop = function stop(streamId) { | ||
this.closePeerConnection(streamId); | ||
var jsCmd = { | ||
command: COMMANDS.STOP, | ||
streamId: streamId | ||
}; | ||
this.webSocketAdaptor.send(JSON.stringify(jsCmd)); | ||
} | ||
/** | ||
* get info about WebRTC stream. | ||
* | ||
* @param {string} streamId stream Id | ||
*/ | ||
; | ||
if (!this.remotePeerConnection[streamId]) { | ||
var closedStreamId = streamId; // eslint-disable-next-line no-undef | ||
_proto.getStreamInfo = function getStreamInfo(streamId) { | ||
var jsCmd = { | ||
command: COMMANDS.GET_STREAM_INFO, | ||
streamId: streamId | ||
}; | ||
this.webSocketAdaptor.send(JSON.stringify(jsCmd)); | ||
} | ||
/** | ||
* WebRTC onTrack event. | ||
* | ||
* @param {Object} event event object | ||
* @param {string} streamId stream Id | ||
*/ | ||
; | ||
this.remotePeerConnection[streamId] = new RTCPeerConnection(this.pcConfig); | ||
this.remoteDescriptionSet[streamId] = false; | ||
this.iceCandidateList[streamId] = []; | ||
_proto.onTrack = function onTrack(event, streamId) { | ||
if (this.remoteVideo) { | ||
this.remoteVideo.src({ | ||
type: 'video/mp4', | ||
src: DEFAULT_VIDEO_FALLBACK | ||
}); | ||
var vid = this.remoteVideo.tech().el(); | ||
this.remotePeerConnection[streamId].onicecandidate = function (event) { | ||
_this.iceCandidateReceived(event, closedStreamId); | ||
}; | ||
if (vid.srcObject !== event.streams[0]) { | ||
vid.srcObject = event.streams[0]; | ||
} | ||
} | ||
} | ||
/** | ||
* Receive iceCandidate handler. | ||
* | ||
* @param {Object} event event object | ||
* @param {string} streamId stream Id | ||
*/ | ||
; | ||
this.remotePeerConnection[streamId].ontrack = function (event) { | ||
_this.onTrack(event, closedStreamId); | ||
}; | ||
_proto.iceCandidateReceived = function iceCandidateReceived(event, streamId) { | ||
if (event.candidate) { | ||
var protocolSupported = false; | ||
this.remotePeerConnection[streamId].oniceconnectionstatechange = function () { | ||
var obj = { | ||
state: _this.remotePeerConnection[streamId].iceConnectionState, | ||
streamId: streamId | ||
}; | ||
if (event.candidate.candidate === '') { | ||
// event candidate can be received and its value can be "". | ||
// don't compare the protocols | ||
protocolSupported = true; | ||
} else if (typeof event.candidate.protocol === 'undefined') { | ||
this.candidateTypes.forEach(function (element) { | ||
if (event.candidate.candidate.toLowerCase().includes(element)) { | ||
protocolSupported = true; | ||
} | ||
}); | ||
} else { | ||
protocolSupported = this.candidateTypes.includes(event.candidate.protocol.toLowerCase()); | ||
} | ||
_this.callback('ice_connection_state_changed', obj); | ||
}; | ||
} | ||
} | ||
/** | ||
* Close WebRtc PeerConnection. | ||
* | ||
* @param {string} streamId stream Id | ||
*/ | ||
; | ||
if (protocolSupported) { | ||
var jsCmd = { | ||
command: COMMANDS.TAKE_CANDIDATE, | ||
streamId: streamId, | ||
label: event.candidate.sdpMLineIndex, | ||
id: event.candidate.sdpMid, | ||
candidate: event.candidate.candidate | ||
}; | ||
this.webSocketAdaptor.send(JSON.stringify(jsCmd)); | ||
} else if (event.candidate.candidate !== '') { | ||
this.callbackError('protocol_not_supported', 'Support protocols: ' + this.candidateTypes.toString() + ' candidate: ' + event.candidate.candidate); | ||
} | ||
} | ||
} | ||
/** | ||
* Initiate WebRtc PeerConnection. | ||
* | ||
* @param {string} streamId stream Id | ||
*/ | ||
; | ||
_proto.closePeerConnection = function closePeerConnection(streamId) { | ||
if (this.remotePeerConnection[streamId]) { | ||
if (this.remotePeerConnection[streamId].signalingState !== 'closed') { | ||
this.remotePeerConnection[streamId].close(); | ||
this.remotePeerConnection[streamId] = null; | ||
delete this.remotePeerConnection[streamId]; | ||
this.playStreamId = this.playStreamId.filter(function (item) { | ||
return item !== streamId; | ||
}); | ||
} | ||
} | ||
} | ||
/** | ||
* Got the SDP. | ||
* | ||
* @param {RTCSessionDescriptionInit} configuration sdp | ||
* @param {string} streamId stream Id | ||
*/ | ||
; | ||
_proto.initPeerConnection = function initPeerConnection(streamId) { | ||
var _this = this; | ||
_proto.gotDescription = function gotDescription(configuration, streamId) { | ||
var _this2 = this; | ||
if (!this.remotePeerConnection[streamId]) { | ||
var closedStreamId = streamId; // eslint-disable-next-line no-undef | ||
this.remotePeerConnection[streamId].setLocalDescription(configuration).then(function () { | ||
var jsCmd = { | ||
command: COMMANDS.TAKE_CONFIGURATION, | ||
streamId: streamId, | ||
type: configuration.type, | ||
sdp: configuration.sdp | ||
}; | ||
this.remotePeerConnection[streamId] = new RTCPeerConnection(this.pcConfig); | ||
this.remoteDescriptionSet[streamId] = false; | ||
this.iceCandidateList[streamId] = []; | ||
_this2.webSocketAdaptor.send(JSON.stringify(jsCmd)); | ||
}); | ||
} | ||
/** | ||
* take the SDP. | ||
* | ||
* @param {string} idOfStream id of stream | ||
* @param {RTCSessionDescriptionInit} configuration sdp | ||
* @param {string} typeOfConfiguration stream Id | ||
* @param {Object} idMapping track Ids | ||
*/ | ||
; | ||
this.remotePeerConnection[streamId].onicecandidate = function (event) { | ||
_this.iceCandidateReceived(event, closedStreamId); | ||
}; | ||
_proto.takeConfiguration = function takeConfiguration(idOfStream, configuration, typeOfConfiguration, idMapping) { | ||
var _this3 = this; | ||
this.remotePeerConnection[streamId].ontrack = function (event) { | ||
_this.onTrack(event, closedStreamId); | ||
}; | ||
var streamId = idOfStream; | ||
this.idMapping[streamId] = idMapping; | ||
this.initPeerConnection(streamId); // eslint-disable-next-line no-undef | ||
this.remotePeerConnection[streamId].oniceconnectionstatechange = function () { | ||
var obj = { | ||
state: _this.remotePeerConnection[streamId].iceConnectionState, | ||
streamId: streamId | ||
}; | ||
this.remotePeerConnection[streamId].setRemoteDescription({ | ||
sdp: configuration, | ||
type: typeOfConfiguration | ||
}).then(function () { | ||
_this3.remoteDescriptionSet[streamId] = true; | ||
var length = _this3.iceCandidateList[streamId].length; | ||
_this.callback('ice_connection_state_changed', obj); | ||
}; | ||
} | ||
} | ||
/** | ||
* Close WebRtc PeerConnection. | ||
* | ||
* @param {string} streamId stream Id | ||
*/ | ||
; | ||
for (var i = 0; i < length; i++) { | ||
_this3.addIceCandidate(streamId, _this3.iceCandidateList[streamId][i]); | ||
} | ||
_proto.closePeerConnection = function closePeerConnection(streamId) { | ||
if (this.remotePeerConnection[streamId]) { | ||
if (this.remotePeerConnection[streamId].signalingState !== 'closed') { | ||
this.remotePeerConnection[streamId].close(); | ||
this.remotePeerConnection[streamId] = null; | ||
delete this.remotePeerConnection[streamId]; | ||
this.playStreamId = this.playStreamId.filter(function (item) { | ||
return item !== streamId; | ||
}); | ||
} | ||
} | ||
} | ||
/** | ||
* Got the SDP. | ||
* | ||
* @param {RTCSessionDescriptionInit} configuration sdp | ||
* @param {string} streamId stream Id | ||
*/ | ||
; | ||
_this3.iceCandidateList[streamId] = []; | ||
_proto.gotDescription = function gotDescription(configuration, streamId) { | ||
var _this2 = this; | ||
if (typeOfConfiguration === 'offer') { | ||
_this3.remotePeerConnection[streamId].createAnswer(_this3.sdpConstraints).then(function (config) { | ||
// support for stereo | ||
config.sdp = config.sdp.replace('useinbandfec=1', 'useinbandfec=1; stereo=1'); | ||
this.remotePeerConnection[streamId].setLocalDescription(configuration).then(function () { | ||
var jsCmd = { | ||
command: COMMANDS.TAKE_CONFIGURATION, | ||
streamId: streamId, | ||
type: configuration.type, | ||
sdp: configuration.sdp | ||
}; | ||
_this3.gotDescription(config, streamId); | ||
}); | ||
} | ||
}).catch(function (error) { | ||
if (error.toString().includes('InvalidAccessError') || error.toString().includes('setRemoteDescription')) { | ||
/** | ||
* This error generally occurs in codec incompatibility. | ||
* AMS for a now supports H.264 codec. This error happens when some browsers try to open it from VP8. | ||
*/ | ||
_this3.callbackError('notSetRemoteDescription'); | ||
} | ||
}); | ||
} | ||
/** | ||
* take the Ice Candidate. | ||
* | ||
* @param {string} idOfTheStream id of stream | ||
* @param {string} label sdpMLineIndex | ||
* @param {Object} takingCandidate candidate | ||
*/ | ||
; | ||
_this2.webSocketAdaptor.send(JSON.stringify(jsCmd)); | ||
}); | ||
} | ||
/** | ||
* take the SDP. | ||
* | ||
* @param {string} idOfStream id of stream | ||
* @param {RTCSessionDescriptionInit} configuration sdp | ||
* @param {string} typeOfConfiguration stream Id | ||
* @param {Object} idMapping track Ids | ||
*/ | ||
; | ||
_proto.takeCandidate = function takeCandidate(idOfTheStream, label, takingCandidate) { | ||
var streamId = idOfTheStream; // eslint-disable-next-line no-undef | ||
_proto.takeConfiguration = function takeConfiguration(idOfStream, configuration, typeOfConfiguration, idMapping) { | ||
var _this3 = this; | ||
var candidate = new RTCIceCandidate({ | ||
sdpMLineIndex: label, | ||
candidate: takingCandidate | ||
}); | ||
this.initPeerConnection(streamId); | ||
var streamId = idOfStream; | ||
this.idMapping[streamId] = idMapping; | ||
this.initPeerConnection(streamId); // eslint-disable-next-line no-undef | ||
if (this.remoteDescriptionSet[streamId] === true) { | ||
this.addIceCandidate(streamId, candidate); | ||
} else { | ||
this.iceCandidateList[streamId].push(candidate); | ||
} | ||
} | ||
/** | ||
* take the Ice Candidate. | ||
* | ||
* @param {string} streamId id of stream | ||
* @param {Object} candidate candidate | ||
*/ | ||
; | ||
this.remotePeerConnection[streamId].setRemoteDescription({ | ||
sdp: configuration, | ||
type: typeOfConfiguration | ||
}).then(function () { | ||
_this3.remoteDescriptionSet[streamId] = true; | ||
var length = _this3.iceCandidateList[streamId].length; | ||
_proto.addIceCandidate = function addIceCandidate(streamId, candidate) { | ||
var protocolSupported = false; | ||
for (var i = 0; i < length; i++) { | ||
_this3.addIceCandidate(streamId, _this3.iceCandidateList[streamId][i]); | ||
} | ||
if (candidate.candidate === '') { | ||
protocolSupported = true; | ||
} else if (typeof candidate.protocol === 'undefined') { | ||
this.candidateTypes.forEach(function (element) { | ||
if (candidate.candidate.toLowerCase().includes(element)) { | ||
protocolSupported = true; | ||
} | ||
}); | ||
} else { | ||
protocolSupported = this.candidateTypes.includes(candidate.protocol.toLowerCase()); | ||
} | ||
_this3.iceCandidateList[streamId] = []; | ||
if (protocolSupported) { | ||
this.remotePeerConnection[streamId].addIceCandidate(candidate); | ||
} | ||
} | ||
/** | ||
* closing WebSocket connection. | ||
*/ | ||
; | ||
if (typeOfConfiguration === 'offer') { | ||
_this3.remotePeerConnection[streamId].createAnswer(_this3.sdpConstraints).then(function (config) { | ||
// support for stereo | ||
config.sdp = config.sdp.replace('useinbandfec=1', 'useinbandfec=1; stereo=1'); | ||
_proto.closeWebSocket = function closeWebSocket() { | ||
for (var key in this.remotePeerConnection) { | ||
this.remotePeerConnection[key].close(); | ||
} // free the remote peer connection by initializing again | ||
_this3.gotDescription(config, streamId); | ||
}); | ||
} | ||
}).catch(function (error) { | ||
if (error.toString().includes('InvalidAccessError') || error.toString().includes('setRemoteDescription')) { | ||
/** | ||
* This error generally occurs in codec incompatibility. | ||
* AMS for a now supports H.264 codec. This error happens when some browsers try to open it from VP8. | ||
*/ | ||
_this3.callbackError('notSetRemoteDescription'); | ||
} | ||
}); | ||
} | ||
/** | ||
* take the Ice Candidate. | ||
* | ||
* @param {string} idOfTheStream id of stream | ||
* @param {string} label sdpMLineIndex | ||
* @param {Object} takingCandidate candidate | ||
*/ | ||
; | ||
_proto.takeCandidate = function takeCandidate(idOfTheStream, label, takingCandidate) { | ||
var streamId = idOfTheStream; // eslint-disable-next-line no-undef | ||
this.remotePeerConnection = []; | ||
this.webSocketAdaptor.close(); | ||
} | ||
/** | ||
* check WebSocket connection. | ||
*/ | ||
; | ||
var candidate = new RTCIceCandidate({ | ||
sdpMLineIndex: label, | ||
candidate: takingCandidate | ||
}); | ||
this.initPeerConnection(streamId); | ||
_proto.checkWebSocketConnection = function checkWebSocketConnection() { | ||
var isWebSocketAvailable = this.webSocketAdaptor; | ||
var isWebSocketConnected = isWebSocketAvailable && this.webSocketAdaptor.isConnected() && this.webSocketAdaptor.isConnecting(); | ||
if (this.remoteDescriptionSet[streamId] === true) { | ||
this.addIceCandidate(streamId, candidate); | ||
} else { | ||
this.iceCandidateList[streamId].push(candidate); | ||
} | ||
} | ||
/** | ||
* take the Ice Candidate. | ||
* | ||
* @param {string} streamId id of stream | ||
* @param {Object} candidate candidate | ||
*/ | ||
; | ||
if (!isWebSocketAvailable || !isWebSocketConnected) { | ||
try { | ||
this.webSocketAdaptor = new WebSocketAdaptor({ | ||
websocketUrl: this.websocketUrl, | ||
webrtcadaptor: this, | ||
callback: this.callback, | ||
callbackError: this.callbackError | ||
}); | ||
} catch (e) { | ||
this.player.createModal('WebSocket connect error'); | ||
} | ||
} | ||
} | ||
/** | ||
* send peer message | ||
* | ||
* @param {string} streamId id of stream | ||
* @param {string} definition message definition | ||
* @param {string} data message data | ||
*/ | ||
; | ||
_proto.addIceCandidate = function addIceCandidate(streamId, candidate) { | ||
var protocolSupported = false; | ||
_proto.peerMessage = function peerMessage(streamId, definition, data) { | ||
var jsCmd = { | ||
command: COMMANDS.PEER_MESSAGE_COMMAND, | ||
streamId: streamId, | ||
definition: definition, | ||
data: data | ||
}; | ||
this.webSocketAdaptor.send(JSON.stringify(jsCmd)); | ||
} | ||
/** | ||
* force stream quality | ||
* | ||
* @param {string} streamId id of stream | ||
* @param {string} resolution stream resolution | ||
*/ | ||
; | ||
if (candidate.candidate === '') { | ||
protocolSupported = true; | ||
} else if (typeof candidate.protocol === 'undefined') { | ||
this.candidateTypes.forEach(function (element) { | ||
if (candidate.candidate.toLowerCase().includes(element)) { | ||
protocolSupported = true; | ||
} | ||
}); | ||
} else { | ||
protocolSupported = this.candidateTypes.includes(candidate.protocol.toLowerCase()); | ||
} | ||
_proto.forceStreamQuality = function forceStreamQuality(streamId, resolution) { | ||
var jsCmd = { | ||
command: COMMANDS.FORCE_STREAM_QUALITY, | ||
streamId: streamId, | ||
streamHeight: resolution | ||
}; | ||
this.webSocketAdaptor.send(JSON.stringify(jsCmd)); | ||
}; | ||
if (protocolSupported) { | ||
this.remotePeerConnection[streamId].addIceCandidate(candidate); | ||
} | ||
} | ||
/** | ||
* closing WebSocket connection. | ||
*/ | ||
; | ||
return WebRTCAdaptor; | ||
}(); | ||
_proto.closeWebSocket = function closeWebSocket() { | ||
for (var key in this.remotePeerConnection) { | ||
this.remotePeerConnection[key].close(); | ||
} // free the remote peer connection by initializing again | ||
var ANT_CALLBACKS = { | ||
INITIALIZED: 'initialized', | ||
PLAY_STARTED: 'play_started', | ||
PLAY_FINISHED: 'play_finished', | ||
CLOSED: 'closed', | ||
STREAM_INFORMATION: 'streamInformation', | ||
RESOLUTION_CHANGE_INFO: 'resolutionChangeInfo' | ||
}; | ||
function createCommonjsModule(fn, basedir, module) { | ||
return module = { | ||
path: basedir, | ||
exports: {}, | ||
require: function (path, base) { | ||
return commonjsRequire(path, (base === undefined || base === null) ? module.path : base); | ||
} | ||
}, fn(module, module.exports), module.exports; | ||
} | ||
this.remotePeerConnection = []; | ||
this.webSocketAdaptor.close(); | ||
} | ||
/** | ||
* check WebSocket connection. | ||
*/ | ||
; | ||
function commonjsRequire () { | ||
throw new Error('Dynamic requires are not currently supported by @rollup/plugin-commonjs'); | ||
} | ||
_proto.checkWebSocketConnection = function checkWebSocketConnection() { | ||
var isWebSocketAvailable = this.webSocketAdaptor; | ||
var isWebSocketConnected = isWebSocketAvailable && this.webSocketAdaptor.isConnected() && this.webSocketAdaptor.isConnecting(); | ||
var assertThisInitialized = createCommonjsModule(function (module) { | ||
function _assertThisInitialized(self) { | ||
if (self === void 0) { | ||
throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); | ||
} | ||
if (!isWebSocketAvailable || !isWebSocketConnected) { | ||
try { | ||
this.webSocketAdaptor = new WebSocketAdaptor({ | ||
websocketUrl: this.websocketUrl, | ||
webrtcadaptor: this, | ||
callback: this.callback, | ||
callbackError: this.callbackError | ||
}); | ||
} catch (e) { | ||
this.player.createModal('WebSocket connect error'); | ||
} | ||
} | ||
} | ||
/** | ||
* send peer message | ||
* | ||
* @param {string} streamId id of stream | ||
* @param {string} definition message definition | ||
* @param {string} data message data | ||
*/ | ||
; | ||
return self; | ||
} | ||
_proto.peerMessage = function peerMessage(streamId, definition, data) { | ||
var jsCmd = { | ||
command: COMMANDS.PEER_MESSAGE_COMMAND, | ||
streamId: streamId, | ||
definition: definition, | ||
data: data | ||
}; | ||
this.webSocketAdaptor.send(JSON.stringify(jsCmd)); | ||
} | ||
/** | ||
* force stream quality | ||
* | ||
* @param {string} streamId id of stream | ||
* @param {string} resolution stream resolution | ||
*/ | ||
; | ||
module.exports = _assertThisInitialized; | ||
module.exports["default"] = module.exports, module.exports.__esModule = true; | ||
}); | ||
_proto.forceStreamQuality = function forceStreamQuality(streamId, resolution) { | ||
var jsCmd = { | ||
command: COMMANDS.FORCE_STREAM_QUALITY, | ||
streamId: streamId, | ||
streamHeight: resolution | ||
}; | ||
this.webSocketAdaptor.send(JSON.stringify(jsCmd)); | ||
}; | ||
var setPrototypeOf = createCommonjsModule(function (module) { | ||
function _setPrototypeOf(o, p) { | ||
module.exports = _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { | ||
o.__proto__ = p; | ||
return o; | ||
}; | ||
return WebRTCAdaptor; | ||
}(); | ||
module.exports["default"] = module.exports, module.exports.__esModule = true; | ||
return _setPrototypeOf(o, p); | ||
} | ||
var ANT_CALLBACKS = { | ||
INITIALIZED: 'initialized', | ||
PLAY_STARTED: 'play_started', | ||
PLAY_FINISHED: 'play_finished', | ||
CLOSED: 'closed', | ||
STREAM_INFORMATION: 'streamInformation', | ||
RESOLUTION_CHANGE_INFO: 'resolutionChangeInfo' | ||
}; | ||
module.exports = _setPrototypeOf; | ||
module.exports["default"] = module.exports, module.exports.__esModule = true; | ||
}); | ||
var assertThisInitialized = createCommonjsModule(function (module) { | ||
function _assertThisInitialized(self) { | ||
if (self === void 0) { | ||
throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); | ||
} | ||
var inheritsLoose = createCommonjsModule(function (module) { | ||
function _inheritsLoose(subClass, superClass) { | ||
subClass.prototype = Object.create(superClass.prototype); | ||
subClass.prototype.constructor = subClass; | ||
setPrototypeOf(subClass, superClass); | ||
} | ||
return self; | ||
} | ||
module.exports = _inheritsLoose; | ||
module.exports["default"] = module.exports, module.exports.__esModule = true; | ||
}); | ||
module.exports = _assertThisInitialized, module.exports.__esModule = true, module.exports["default"] = module.exports; | ||
}); | ||
var MenuItem = videojs__default['default'].getComponent('MenuItem'); | ||
var Component = videojs__default['default'].getComponent('Component'); | ||
var MenuItem = videojs__default["default"].getComponent('MenuItem'); | ||
var Component = videojs__default["default"].getComponent('Component'); | ||
var ResolutionMenuItem = /*#__PURE__*/function (_MenuItem) { | ||
inheritsLoose(ResolutionMenuItem, _MenuItem); | ||
var ResolutionMenuItem = /*#__PURE__*/function (_MenuItem) { | ||
inheritsLoose(ResolutionMenuItem, _MenuItem); | ||
function ResolutionMenuItem(player, options) { | ||
options.selectable = true; | ||
options.multiSelectable = false; | ||
return _MenuItem.call(this, player, options) || this; | ||
} | ||
function ResolutionMenuItem(player, options) { | ||
options.selectable = true; | ||
options.multiSelectable = false; | ||
return _MenuItem.call(this, player, options) || this; | ||
} | ||
var _proto = ResolutionMenuItem.prototype; | ||
var _proto = ResolutionMenuItem.prototype; | ||
_proto.handleClick = function handleClick() { | ||
this.options().plugin.changeStreamQuality(this.options().value); | ||
}; | ||
_proto.handleClick = function handleClick() { | ||
this.options().plugin.changeStreamQuality(this.options().value); | ||
}; | ||
return ResolutionMenuItem; | ||
}(MenuItem); | ||
return ResolutionMenuItem; | ||
}(MenuItem); | ||
Component.registerComponent('ResolutionMenuItem', ResolutionMenuItem); | ||
Component.registerComponent('ResolutionMenuItem', ResolutionMenuItem); | ||
var MenuButton = videojs__default['default'].getComponent('MenuButton'); | ||
var MenuButton = videojs__default["default"].getComponent('MenuButton'); | ||
var ResolutionMenuButton = /*#__PURE__*/function (_MenuButton) { | ||
inheritsLoose(ResolutionMenuButton, _MenuButton); | ||
var ResolutionMenuButton = /*#__PURE__*/function (_MenuButton) { | ||
inheritsLoose(ResolutionMenuButton, _MenuButton); | ||
function ResolutionMenuButton(player, options) { | ||
var _this; | ||
function ResolutionMenuButton(player, options) { | ||
var _this; | ||
_this = _MenuButton.call(this, player, options) || this; | ||
MenuButton.apply(assertThisInitialized(_this), arguments); | ||
return _this; | ||
} | ||
_this = _MenuButton.call(this, player, options) || this; | ||
MenuButton.apply(assertThisInitialized(_this), arguments); | ||
return _this; | ||
} | ||
var _proto = ResolutionMenuButton.prototype; | ||
var _proto = ResolutionMenuButton.prototype; | ||
_proto.createEl = function createEl() { | ||
return videojs__default['default'].dom.createEl('div', { | ||
className: 'vjs-http-source-selector vjs-menu-button vjs-menu-button-popup vjs-control vjs-button' | ||
}); | ||
}; | ||
_proto.createEl = function createEl() { | ||
return videojs__default["default"].dom.createEl('div', { | ||
className: 'vjs-http-source-selector vjs-menu-button vjs-menu-button-popup vjs-control vjs-button' | ||
}); | ||
}; | ||
_proto.buildCSSClass = function buildCSSClass() { | ||
return MenuButton.prototype.buildCSSClass.call(this) + ' vjs-icon-cog'; | ||
}; | ||
_proto.buildCSSClass = function buildCSSClass() { | ||
return MenuButton.prototype.buildCSSClass.call(this) + ' vjs-icon-cog'; | ||
}; | ||
_proto.update = function update() { | ||
return MenuButton.prototype.update.call(this); | ||
}; | ||
_proto.update = function update() { | ||
return MenuButton.prototype.update.call(this); | ||
}; | ||
_proto.createItems = function createItems() { | ||
var menuItems = []; | ||
var levels = [{ | ||
label: 'auto', | ||
value: 0 | ||
}].concat(this.player().resolutions); | ||
_proto.createItems = function createItems() { | ||
var menuItems = []; | ||
var levels = [{ | ||
label: 'auto', | ||
value: 0 | ||
}].concat(this.player().resolutions); | ||
for (var i = 0; i < levels.length; i++) { | ||
menuItems.push(new ResolutionMenuItem(this.player_, { | ||
label: levels[i].label, | ||
value: levels[i].value, | ||
selected: levels[i].value === this.player().selectedResolution, | ||
plugin: this.options().plugin, | ||
streamName: this.options().streamName | ||
})); | ||
} | ||
for (var i = 0; i < levels.length; i++) { | ||
menuItems.push(new ResolutionMenuItem(this.player_, { | ||
label: levels[i].label, | ||
value: levels[i].value, | ||
selected: levels[i].value === this.player().selectedResolution, | ||
plugin: this.options().plugin, | ||
streamName: this.options().streamName | ||
})); | ||
} | ||
return menuItems; | ||
}; | ||
return menuItems; | ||
}; | ||
return ResolutionMenuButton; | ||
}(MenuButton); | ||
return ResolutionMenuButton; | ||
}(MenuButton); | ||
var defaults = { | ||
sdpConstraints: { | ||
OfferToReceiveAudio: true, | ||
OfferToReceiveVideo: true | ||
}, | ||
mediaConstraints: { | ||
video: false, | ||
audio: false | ||
} | ||
}; | ||
/** | ||
* An advanced Video.js plugin for playing WebRTC stream from Ant-mediaserver | ||
*/ | ||
var Plugin = videojs__default["default"].getPlugin('plugin'); // Default options for the plugin. | ||
var WebRTCHandler = /*#__PURE__*/function () { | ||
/** | ||
* Create a WebRTC source handler instance. | ||
* | ||
* @param {Object} source | ||
* Source object that is given in the DOM, includes the stream URL | ||
* | ||
* @param {Object} [options] | ||
* Options include: | ||
* ICE Server | ||
* Tokens | ||
* Subscriber ID | ||
* Subscriber code | ||
*/ | ||
function WebRTCHandler(source, tech, options) { | ||
var _this = this; | ||
var defaults = { | ||
sdpConstraints: { | ||
OfferToReceiveAudio: true, | ||
OfferToReceiveVideo: true | ||
}, | ||
mediaConstraints: { | ||
video: false, | ||
audio: false | ||
} | ||
}; | ||
/** | ||
* An advanced Video.js plugin for playing WebRTC stream from Ant-mediaserver | ||
*/ | ||
this.player = videojs__default['default'](options.playerId); | ||
this.initiateWebRTCAdaptor(source, options); | ||
this.player.ready(function () { | ||
_this.player.addClass('videojs-webrtc-plugin'); | ||
}); | ||
this.player.on('playing', function () { | ||
if (_this.player.el().getElementsByClassName('vjs-custom-spinner').length) { | ||
_this.player.el().removeChild(_this.player.spinner); | ||
} | ||
}); | ||
videojs__default['default'].registerComponent('ResolutionMenuButton', ResolutionMenuButton); | ||
videojs__default['default'].registerComponent('ResolutionMenuItem', ResolutionMenuItem); | ||
} | ||
/** | ||
* Initiate WebRTCAdaptor. | ||
* | ||
* @param {Object} [options] | ||
* An optional options object. | ||
* | ||
*/ | ||
var AntmediaWebrtc = /*#__PURE__*/function (_Plugin) { | ||
inheritsLoose(AntmediaWebrtc, _Plugin); | ||
/** | ||
* Create a AntmediaWebrtc plugin instance. | ||
* | ||
* @param {Player} player | ||
* A Video.js Player instance. | ||
* | ||
* @param {Object} [options] | ||
* An optional options object. | ||
* | ||
* While not a core part of the Video.js plugin architecture, a | ||
* second argument of options is a convenient way to accept inputs | ||
* from your plugin's caller. | ||
*/ | ||
function AntmediaWebrtc(player, options) { | ||
var _this; | ||
var _proto = WebRTCHandler.prototype; | ||
_this = _Plugin.call(this, player) || this; | ||
_proto.initiateWebRTCAdaptor = function initiateWebRTCAdaptor(source, options) { | ||
var _this2 = this; | ||
_this.initiateWebRTCAdaptor(options); | ||
this.options = videojs__default['default'].mergeOptions(defaults, options); | ||
this.source = source; | ||
this.source.pcConfig = { | ||
iceServers: JSON.parse(source.iceservers) | ||
}; | ||
this.source.mediaServerUrl = source.src.split('/').slice(0, 4).join('/') + "/websocket"; | ||
this.source.streamName = source.src.split('/')[4].split('.webrtc')[0]; | ||
this.source.token = this.getUrlParameter('token'); | ||
this.source.subscriberId = this.getUrlParameter('subscriberId'); | ||
this.source.subscriberCode = this.getUrlParameter('subscriberCode'); | ||
this.webRTCAdaptor = new WebRTCAdaptor({ | ||
websocketUrl: this.source.mediaServerUrl, | ||
mediaConstraints: this.source.mediaConstraints, | ||
pcConfig: this.source.pcConfig, | ||
sdpConstraints: this.source.sdpConstraints, | ||
player: this.player, | ||
callback: function callback(info, obj) { | ||
switch (info) { | ||
case ANT_CALLBACKS.INITIALIZED: | ||
{ | ||
_this2.initializedHandler(); | ||
_this.player.ready(function () { | ||
_this.player.addClass('videojs-webrtc-plugin'); | ||
}); | ||
break; | ||
} | ||
_this.player.on('playing', function () { | ||
if (_this.player.el().getElementsByClassName('vjs-custom-spinner').length) { | ||
_this.player.el().removeChild(_this.player.spinner); | ||
} | ||
}); | ||
case ANT_CALLBACKS.PLAY_STARTED: | ||
{ | ||
_this2.joinStreamHandler(obj); | ||
videojs__default["default"].registerComponent('ResolutionMenuButton', ResolutionMenuButton); | ||
videojs__default["default"].registerComponent('ResolutionMenuItem', ResolutionMenuItem); | ||
return _this; | ||
} | ||
/** | ||
* Initiate WebRTCAdaptor. | ||
* | ||
* @param {Object} [options] | ||
* An optional options object. | ||
* | ||
*/ | ||
break; | ||
} | ||
case ANT_CALLBACKS.PLAY_FINISHED: | ||
{ | ||
_this2.leaveStreamHandler(obj); | ||
var _proto = AntmediaWebrtc.prototype; | ||
break; | ||
} | ||
_proto.initiateWebRTCAdaptor = function initiateWebRTCAdaptor(options) { | ||
var _this2 = this; | ||
case ANT_CALLBACKS.STREAM_INFORMATION: | ||
{ | ||
_this2.streamInformationHandler(obj); | ||
this.options = videojs__default["default"].mergeOptions(defaults, options); | ||
this.options.pcConfig = { | ||
iceServers: JSON.parse(options.iceServers) | ||
}; | ||
this.options.mediaServerUrl = options.streamUrl.split('?')[0]; | ||
this.options.streamName = this.getUrlParameter('streamId'); | ||
this.options.token = this.getUrlParameter('token'); | ||
this.options.subscriberId = this.getUrlParameter('subscriberId'); | ||
this.options.subscriberCode = this.getUrlParameter('subscriberCode'); | ||
this.webRTCAdaptor = new WebRTCAdaptor({ | ||
websocketUrl: this.options.mediaServerUrl, | ||
mediaConstraints: this.options.mediaConstraints, | ||
pcConfig: this.options.pcConfig, | ||
sdpConstraints: this.options.sdpConstraints, | ||
player: this.player, | ||
callback: function callback(info, obj) { | ||
switch (info) { | ||
case ANT_CALLBACKS.INITIALIZED: | ||
{ | ||
_this2.initializedHandler(); | ||
break; | ||
} | ||
break; | ||
} | ||
case ANT_CALLBACKS.RESOLUTION_CHANGE_INFO: | ||
{ | ||
_this2.resolutionChangeHandler(obj); | ||
case ANT_CALLBACKS.PLAY_STARTED: | ||
{ | ||
_this2.joinStreamHandler(obj); | ||
break; | ||
} | ||
break; | ||
} | ||
default: | ||
{ | ||
_this2.defaultHandler(info); | ||
case ANT_CALLBACKS.PLAY_FINISHED: | ||
{ | ||
_this2.leaveStreamHandler(obj); | ||
break; | ||
} | ||
} | ||
}, | ||
callbackError: function callbackError(error) { | ||
// add error handler | ||
// some of the possible errors, NotFoundError, SecurityError,PermissionDeniedError | ||
var ModalDialog = videojs__default['default'].getComponent('ModalDialog'); | ||
break; | ||
} | ||
if (_this2.errorModal) { | ||
_this2.errorModal.close(); | ||
} | ||
case ANT_CALLBACKS.STREAM_INFORMATION: | ||
{ | ||
_this2.streamInformationHandler(obj); | ||
_this2.errorModal = new ModalDialog(_this2.player, { | ||
content: "ERROR: " + JSON.stringify(error), | ||
temporary: true, | ||
pauseOnOpen: false, | ||
uncloseable: true | ||
}); | ||
break; | ||
} | ||
_this2.player.addChild(_this2.errorModal); | ||
case ANT_CALLBACKS.RESOLUTION_CHANGE_INFO: | ||
{ | ||
_this2.resolutionChangeHandler(obj); | ||
_this2.errorModal.open(); | ||
break; | ||
} | ||
_this2.errorModal.setTimeout(function () { | ||
return _this2.errorModal.close(); | ||
}, 3000); | ||
default: | ||
{ | ||
_this2.defaultHandler(info); | ||
_this2.player.trigger('webrtc-error', { | ||
error: error | ||
}); | ||
} | ||
}); | ||
} | ||
/** | ||
* after websocket success connection. | ||
*/ | ||
; | ||
break; | ||
} | ||
} | ||
}, | ||
callbackError: function callbackError(error) { | ||
// add error handler | ||
// some of the possible errors, NotFoundError, SecurityError,PermissionDeniedError | ||
var ModalDialog = videojs__default["default"].getComponent('ModalDialog'); | ||
_proto.initializedHandler = function initializedHandler() { | ||
this.webRTCAdaptor.play(this.source.streamName, this.source.token, this.source.subscriberId, this.source.subscriberCode); | ||
} | ||
/** | ||
* after joined stream handler | ||
* | ||
* @param {Object} obj callback artefacts | ||
*/ | ||
; | ||
if (_this2.errorModal) { | ||
_this2.errorModal.close(); | ||
} | ||
_proto.joinStreamHandler = function joinStreamHandler(obj) { | ||
this.webRTCAdaptor.getStreamInfo(this.source.streamName); | ||
} | ||
/** | ||
* after left stream. | ||
*/ | ||
; | ||
_this2.errorModal = new ModalDialog(_this2.player, { | ||
content: "ERROR: " + JSON.stringify(error), | ||
temporary: true, | ||
pauseOnOpen: false, | ||
uncloseable: true | ||
}); | ||
_proto.leaveStreamHandler = function leaveStreamHandler() { | ||
// reset stream resolutions in dropdown | ||
this.player.resolutions = []; | ||
this.player.controlBar.getChild('ResolutionMenuButton').update(); | ||
} | ||
/** | ||
* stream information handler. | ||
* | ||
* @param {Object} obj callback artefacts | ||
*/ | ||
; | ||
_this2.player.addChild(_this2.errorModal); | ||
_proto.streamInformationHandler = function streamInformationHandler(obj) { | ||
var streamResolutions = obj.streamInfo.reduce(function (unique, item) { | ||
return unique.includes(item.streamHeight) ? unique : [].concat(unique, [item.streamHeight]); | ||
}, []).sort(function (a, b) { | ||
return b - a; | ||
}); | ||
this.player.resolutions = streamResolutions.map(function (resolution) { | ||
return { | ||
label: resolution, | ||
value: resolution | ||
}; | ||
}); | ||
this.player.selectedResolution = 0; | ||
this.addResolutionButton(); | ||
}; | ||
_this2.errorModal.open(); | ||
_proto.addResolutionButton = function addResolutionButton() { | ||
var controlBar = this.player.controlBar; | ||
var fullscreenToggle = controlBar.getChild('fullscreenToggle').el(); | ||
_this2.errorModal.setTimeout(function () { | ||
return _this2.errorModal.close(); | ||
}, 3000); | ||
} | ||
}); | ||
} | ||
/** | ||
* after websocket success connection. | ||
*/ | ||
; | ||
if (controlBar.getChild('ResolutionMenuButton')) { | ||
controlBar.removeChild('ResolutionMenuButton'); | ||
} | ||
_proto.initializedHandler = function initializedHandler() { | ||
this.webRTCAdaptor.play(this.options.streamName, this.options.token, this.options.subscriberId, this.options.subscriberCode); | ||
} | ||
/** | ||
* after joined stream handler | ||
* | ||
* @param {Object} obj callback artefacts | ||
*/ | ||
; | ||
controlBar.el().insertBefore(controlBar.addChild('ResolutionMenuButton', { | ||
plugin: this, | ||
streamName: this.source.streamName | ||
}).el(), fullscreenToggle); | ||
} | ||
/** | ||
* change resolution handler. | ||
* | ||
* @param {Object} obj callback artefacts | ||
*/ | ||
; | ||
_proto.joinStreamHandler = function joinStreamHandler(obj) { | ||
this.webRTCAdaptor.getStreamInfo(this.options.streamName); | ||
} | ||
/** | ||
* after left stream. | ||
*/ | ||
; | ||
_proto.resolutionChangeHandler = function resolutionChangeHandler(obj) { | ||
var _this3 = this; | ||
_proto.leaveStreamHandler = function leaveStreamHandler() { | ||
// reset stream resolutions in dropdown | ||
this.player.resolutions = []; | ||
this.player.controlBar.getChild('ResolutionMenuButton').update(); | ||
} | ||
/** | ||
* stream information handler. | ||
* | ||
* @param {Object} obj callback artefacts | ||
*/ | ||
; | ||
// eslint-disable-next-line no-undef | ||
this.player.spinner = document.createElement('div'); | ||
this.player.spinner.className = 'vjs-custom-spinner'; | ||
this.player.el().appendChild(this.player.spinner); | ||
this.player.pause(); | ||
this.player.setTimeout(function () { | ||
if (_this3.player.el().getElementsByClassName('vjs-custom-spinner').length) { | ||
_this3.player.el().removeChild(_this3.player.spinner); | ||
_proto.streamInformationHandler = function streamInformationHandler(obj) { | ||
var streamResolutions = obj.streamInfo.reduce(function (unique, item) { | ||
return unique.includes(item.streamHeight) ? unique : [].concat(unique, [item.streamHeight]); | ||
}, []).sort(function (a, b) { | ||
return b - a; | ||
}); | ||
this.player.resolutions = streamResolutions.map(function (resolution) { | ||
return { | ||
label: resolution, | ||
value: resolution | ||
}; | ||
}); | ||
this.player.selectedResolution = 0; | ||
this.addResolutionButton(); | ||
}; | ||
_this3.player.play(); | ||
} | ||
}, 2000); | ||
} | ||
/** | ||
* default handler. | ||
* | ||
* @param {string} info callback event info | ||
*/ | ||
; | ||
_proto.addResolutionButton = function addResolutionButton() { | ||
var controlBar = this.player.controlBar; | ||
var fullscreenToggle = controlBar.getChild('fullscreenToggle').el(); | ||
_proto.defaultHandler = function defaultHandler(info) {// eslint-disable-next-line no-console | ||
// console.log(info + ' notification received'); | ||
}; | ||
if (controlBar.getChild('ResolutionMenuButton')) { | ||
controlBar.removeChild('ResolutionMenuButton'); | ||
} | ||
_proto.changeStreamQuality = function changeStreamQuality(value) { | ||
this.webRTCAdaptor.forceStreamQuality(this.source.streamName, value); | ||
this.player.selectedResolution = value; | ||
this.player.controlBar.getChild('ResolutionMenuButton').update(); | ||
} | ||
/** | ||
* get url parameter | ||
* | ||
* @param {string} param callback event info | ||
*/ | ||
; | ||
controlBar.el().insertBefore(controlBar.addChild('ResolutionMenuButton', { | ||
plugin: this, | ||
streamName: this.options.streamName | ||
}).el(), fullscreenToggle); | ||
} | ||
/** | ||
* change resolution handler. | ||
* | ||
* @param {Object} obj callback artefacts | ||
*/ | ||
; | ||
_proto.getUrlParameter = function getUrlParameter(param) { | ||
if (this.source.src.includes('?')) { | ||
var urlParams = this.source.src.split('?')[1].split('&').reduce(function (p, e) { | ||
var a = e.split('='); | ||
p[decodeURIComponent(a[0])] = decodeURIComponent(a[1]); | ||
return p; | ||
}, {}) || {}; | ||
return urlParams[param]; | ||
} | ||
_proto.resolutionChangeHandler = function resolutionChangeHandler(obj) { | ||
var _this3 = this; | ||
return null; | ||
}; | ||
// eslint-disable-next-line no-undef | ||
this.player.spinner = document.createElement('div'); | ||
this.player.spinner.className = 'vjs-custom-spinner'; | ||
this.player.el().appendChild(this.player.spinner); | ||
this.player.pause(); | ||
this.player.setTimeout(function () { | ||
if (_this3.player.el().getElementsByClassName('vjs-custom-spinner').length) { | ||
_this3.player.el().removeChild(_this3.player.spinner); | ||
return WebRTCHandler; | ||
}(); | ||
_this3.player.play(); | ||
} | ||
}, 2000); | ||
} | ||
/** | ||
* default handler. | ||
* | ||
* @param {string} info callback event info | ||
*/ | ||
; | ||
var webRTCSourceHandler = { | ||
name: 'videojs-webrtc-plugin', | ||
VERSION: '1.1', | ||
canHandleSource: function canHandleSource(srcObj, options) { | ||
if (options === void 0) { | ||
options = {}; | ||
} | ||
_proto.defaultHandler = function defaultHandler(info) {// eslint-disable-next-line no-console | ||
// console.log(info + ' notification received'); | ||
}; | ||
var localOptions = videojs__default['default'].mergeOptions(videojs__default['default'].options, options); | ||
localOptions.source = srcObj.src; | ||
return webRTCSourceHandler.canPlayType(srcObj.type, localOptions); | ||
}, | ||
handleSource: function handleSource(source, tech, options) { | ||
if (options === void 0) { | ||
options = {}; | ||
} | ||
_proto.changeStreamQuality = function changeStreamQuality(value) { | ||
this.webRTCAdaptor.forceStreamQuality(this.options.streamName, value); | ||
this.player.selectedResolution = value; | ||
this.player.controlBar.getChild('ResolutionMenuButton').update(); | ||
} | ||
/** | ||
* get url parameter | ||
* | ||
* @param {string} param callback event info | ||
*/ | ||
; | ||
var localOptions = videojs__default['default'].mergeOptions(videojs__default['default'].options, options); // Register the plugin to source handler tech | ||
_proto.getUrlParameter = function getUrlParameter(param) { | ||
var urlParams = this.options.streamUrl.split('?')[1].split('&').reduce(function (p, e) { | ||
var a = e.split('='); | ||
p[decodeURIComponent(a[0])] = decodeURIComponent(a[1]); | ||
return p; | ||
}, {}); | ||
return urlParams[param]; | ||
}; | ||
tech.webrtc = new WebRTCHandler(source, tech, localOptions); | ||
return tech.webrtc; | ||
}, | ||
canPlayType: function canPlayType(type, options) { | ||
if (options === void 0) { | ||
options = {}; | ||
} | ||
return AntmediaWebrtc; | ||
}(Plugin); // Define default values for the plugin's `state` object here. | ||
var mediaUrl = options.source; | ||
if (mediaUrl.split('/')[4].includes('.webrtc')) { | ||
return 'maybe'; | ||
} | ||
AntmediaWebrtc.defaultState = {}; // Include the version number. | ||
return ''; | ||
} | ||
}; // register source handlers with the appropriate techs | ||
AntmediaWebrtc.VERSION = version; // Register the plugin with video.js. | ||
videojs__default['default'].getTech('Html5').registerSourceHandler(webRTCSourceHandler, 0); | ||
var plugin = { | ||
WebRTCHandler: WebRTCHandler, | ||
webRTCSourceHandler: webRTCSourceHandler | ||
}; | ||
videojs__default["default"].registerPlugin('antmediaWebrtc', AntmediaWebrtc); | ||
return plugin; | ||
return AntmediaWebrtc; | ||
})); | ||
}))); |
@@ -1,2 +0,2 @@ | ||
/*! @name @antmedia/videojs-webrtc-plugin @version 1.0.0 @license MIT */ | ||
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t(require("video.js")):"function"==typeof define&&define.amd?define(["video.js"],t):(e="undefined"!=typeof globalThis?globalThis:e||self).videojsWebrtcPlugin=t(e.videojs)}(this,(function(e){"use strict";function t(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var n=t(e);function i(e,t,n){return e(n={path:t,exports:{},require:function(e,t){return function(){throw new Error("Dynamic requires are not currently supported by @rollup/plugin-commonjs")}(null==t&&n.path)}},n.exports),n.exports}var o=i((function(e){function t(n,i){return e.exports=t=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e},e.exports.__esModule=!0,e.exports.default=e.exports,t(n,i)}e.exports=t,e.exports.__esModule=!0,e.exports.default=e.exports})),r=i((function(e){e.exports=function(e,t){e.prototype=Object.create(t.prototype),e.prototype.constructor=e,o(e,t)},e.exports.__esModule=!0,e.exports.default=e.exports})),a="takeCandidate",s="takeConfiguration",c="play",d="stop",l="getStreamInfo",p="peerMessageCommand",u="forceStreamQuality",h="error",f="notification",m="streamInformation",C="ping",b="pong",g="trackList",y=function(){function e(e){for(var t in e)e.hasOwnProperty(t)&&(this[t]=e[t]);this.initWebSocketConnection()}var t=e.prototype;return t.initWebSocketConnection=function(e){var t=this;this.connecting=!0,this.connected=!1,this.pingTimerId=-1,this.wsConn=new WebSocket(this.websocketUrl),this.wsConn.onopen=function(){t.pingTimerId=setInterval((function(){t.sendPing()}),3e3),t.connected=!0,t.connecting=!1,t.callback("initialized"),void 0!==e&&e()},this.wsConn.onmessage=function(e){var n=JSON.parse(e.data);switch(n.command){case a:t.webrtcadaptor.takeCandidate(n.streamId,n.label,n.candidate);break;case s:t.webrtcadaptor.takeConfiguration(n.streamId,n.sdp,n.type,n.idMapping);break;case d:t.webrtcadaptor.closePeerConnection(n.streamId);break;case h:t.callbackError(n.definition);break;case f:t.callback(n.definition,n),"play_finished"!==n.definition&&"publish_finished"!==n.definition||t.webrtcadaptor.closePeerConnection(n.streamId);break;case m:t.callback(n.command,n);break;case b:t.callback(n.command);break;case g:case p:t.callback(n.command,n)}},this.wsConn.onerror=function(e){t.connecting=!1,t.connected=!1,t.clearPingTimer(),t.callbackError("WebSocketNotConnected",e)},this.wsConn.onclose=function(e){t.connecting=!1,t.connected=!1,t.clearPingTimer(),t.callback("closed",e)}},t.clearPingTimer=function(){-1!==this.pingTimerId&&(clearInterval(this.pingTimerId),this.pingTimerId=-1)},t.sendPing=function(){var e={command:C};this.wsConn.send(JSON.stringify(e))},t.close=function(){this.wsConn.close()},t.send=function(e){var t=this;this.connecting||this.connected?this.wsConn.send(e):this.initWebSocketConnection((function(){t.send(e)}))},t.isConnected=function(){return this.connected},t.isConnecting=function(){return this.connecting},e}(),v=function(){function e(e){for(var t in this.pcConfig=null,this.websocketUrl=null,this.sdpConstraints=null,this.remotePeerConnection=[],this.remoteDescriptionSet=[],this.iceCandidateList=[],this.playStreamId=[],this.player=null,this.webSocketAdaptor=null,this.viewerInfo="",this.idMapping=[],this.candidateTypes=["udp","tcp"],e)e.hasOwnProperty(t)&&(this[t]=e[t]);this.remoteVideo=this.player,this.checkWebSocketConnection()}var t=e.prototype;return t.play=function(e,t,n,i){this.playStreamId.push(e);var o={command:c,streamId:e,token:t,subscriberId:n||"",subscriberCode:i||"",viewerInfo:this.viewerInfo};this.webSocketAdaptor.send(JSON.stringify(o))},t.stop=function(e){this.closePeerConnection(e);var t={command:d,streamId:e};this.webSocketAdaptor.send(JSON.stringify(t))},t.getStreamInfo=function(e){var t={command:l,streamId:e};this.webSocketAdaptor.send(JSON.stringify(t))},t.onTrack=function(e,t){if(this.remoteVideo){this.remoteVideo.src({type:"video/mp4",src:"http://vjs.zencdn.net/v/oceans.mp4"});var n=this.remoteVideo.tech().el();n.srcObject!==e.streams[0]&&(n.srcObject=e.streams[0])}},t.iceCandidateReceived=function(e,t){if(e.candidate){var n=!1;if(""===e.candidate.candidate?n=!0:void 0===e.candidate.protocol?this.candidateTypes.forEach((function(t){e.candidate.candidate.toLowerCase().includes(t)&&(n=!0)})):n=this.candidateTypes.includes(e.candidate.protocol.toLowerCase()),n){var i={command:a,streamId:t,label:e.candidate.sdpMLineIndex,id:e.candidate.sdpMid,candidate:e.candidate.candidate};this.webSocketAdaptor.send(JSON.stringify(i))}else""!==e.candidate.candidate&&this.callbackError("protocol_not_supported","Support protocols: "+this.candidateTypes.toString()+" candidate: "+e.candidate.candidate)}},t.initPeerConnection=function(e){var t=this;if(!this.remotePeerConnection[e]){var n=e;this.remotePeerConnection[e]=new RTCPeerConnection(this.pcConfig),this.remoteDescriptionSet[e]=!1,this.iceCandidateList[e]=[],this.remotePeerConnection[e].onicecandidate=function(e){t.iceCandidateReceived(e,n)},this.remotePeerConnection[e].ontrack=function(e){t.onTrack(e,n)},this.remotePeerConnection[e].oniceconnectionstatechange=function(){var n={state:t.remotePeerConnection[e].iceConnectionState,streamId:e};t.callback("ice_connection_state_changed",n)}}},t.closePeerConnection=function(e){this.remotePeerConnection[e]&&"closed"!==this.remotePeerConnection[e].signalingState&&(this.remotePeerConnection[e].close(),this.remotePeerConnection[e]=null,delete this.remotePeerConnection[e],this.playStreamId=this.playStreamId.filter((function(t){return t!==e})))},t.gotDescription=function(e,t){var n=this;this.remotePeerConnection[t].setLocalDescription(e).then((function(){var i={command:s,streamId:t,type:e.type,sdp:e.sdp};n.webSocketAdaptor.send(JSON.stringify(i))}))},t.takeConfiguration=function(e,t,n,i){var o=this,r=e;this.idMapping[r]=i,this.initPeerConnection(r),this.remotePeerConnection[r].setRemoteDescription({sdp:t,type:n}).then((function(){o.remoteDescriptionSet[r]=!0;for(var e=o.iceCandidateList[r].length,t=0;t<e;t++)o.addIceCandidate(r,o.iceCandidateList[r][t]);o.iceCandidateList[r]=[],"offer"===n&&o.remotePeerConnection[r].createAnswer(o.sdpConstraints).then((function(e){e.sdp=e.sdp.replace("useinbandfec=1","useinbandfec=1; stereo=1"),o.gotDescription(e,r)}))})).catch((function(e){(e.toString().includes("InvalidAccessError")||e.toString().includes("setRemoteDescription"))&&o.callbackError("notSetRemoteDescription")}))},t.takeCandidate=function(e,t,n){var i=e,o=new RTCIceCandidate({sdpMLineIndex:t,candidate:n});this.initPeerConnection(i),!0===this.remoteDescriptionSet[i]?this.addIceCandidate(i,o):this.iceCandidateList[i].push(o)},t.addIceCandidate=function(e,t){var n=!1;""===t.candidate?n=!0:void 0===t.protocol?this.candidateTypes.forEach((function(e){t.candidate.toLowerCase().includes(e)&&(n=!0)})):n=this.candidateTypes.includes(t.protocol.toLowerCase()),n&&this.remotePeerConnection[e].addIceCandidate(t)},t.closeWebSocket=function(){for(var e in this.remotePeerConnection)this.remotePeerConnection[e].close();this.remotePeerConnection=[],this.webSocketAdaptor.close()},t.checkWebSocketConnection=function(){var e=this.webSocketAdaptor,t=e&&this.webSocketAdaptor.isConnected()&&this.webSocketAdaptor.isConnecting();if(!e||!t)try{this.webSocketAdaptor=new y({websocketUrl:this.websocketUrl,webrtcadaptor:this,callback:this.callback,callbackError:this.callbackError})}catch(e){this.player.createModal("WebSocket connect error")}},t.peerMessage=function(e,t,n){var i={command:p,streamId:e,definition:t,data:n};this.webSocketAdaptor.send(JSON.stringify(i))},t.forceStreamQuality=function(e,t){var n={command:u,streamId:e,streamHeight:t};this.webSocketAdaptor.send(JSON.stringify(n))},e}(),k="initialized",S="play_started",w="play_finished",I="streamInformation",P="resolutionChangeInfo",R=i((function(e){e.exports=function(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e},e.exports.__esModule=!0,e.exports.default=e.exports})),M=n.default.getComponent("MenuItem"),T=n.default.getComponent("Component"),N=function(e){function t(t,n){return n.selectable=!0,n.multiSelectable=!1,e.call(this,t,n)||this}return r(t,e),t.prototype.handleClick=function(){this.options().plugin.changeStreamQuality(this.options().value)},t}(M);T.registerComponent("ResolutionMenuItem",N);var O=n.default.getComponent("MenuButton"),j=function(e){function t(t,n){var i;return i=e.call(this,t,n)||this,O.apply(R(i),arguments),i}r(t,e);var i=t.prototype;return i.createEl=function(){return n.default.dom.createEl("div",{className:"vjs-http-source-selector vjs-menu-button vjs-menu-button-popup vjs-control vjs-button"})},i.buildCSSClass=function(){return O.prototype.buildCSSClass.call(this)+" vjs-icon-cog"},i.update=function(){return O.prototype.update.call(this)},i.createItems=function(){for(var e=[],t=[{label:"auto",value:0}].concat(this.player().resolutions),n=0;n<t.length;n++)e.push(new N(this.player_,{label:t[n].label,value:t[n].value,selected:t[n].value===this.player().selectedResolution,plugin:this.options().plugin,streamName:this.options().streamName}));return e},t}(O),x=n.default.getPlugin("plugin"),A={sdpConstraints:{OfferToReceiveAudio:!0,OfferToReceiveVideo:!0},mediaConstraints:{video:!1,audio:!1}},_=function(e){function t(t,i){var o;return(o=e.call(this,t)||this).initiateWebRTCAdaptor(i),o.player.ready((function(){o.player.addClass("videojs-webrtc-plugin")})),o.player.on("playing",(function(){o.player.el().getElementsByClassName("vjs-custom-spinner").length&&o.player.el().removeChild(o.player.spinner)})),n.default.registerComponent("ResolutionMenuButton",j),n.default.registerComponent("ResolutionMenuItem",N),o}r(t,e);var i=t.prototype;return i.initiateWebRTCAdaptor=function(e){var t=this;this.options=n.default.mergeOptions(A,e),this.options.pcConfig={iceServers:JSON.parse(e.iceServers)},this.options.mediaServerUrl=e.streamUrl.split("?")[0],this.options.streamName=this.getUrlParameter("streamId"),this.options.token=this.getUrlParameter("token"),this.options.subscriberId=this.getUrlParameter("subscriberId"),this.options.subscriberCode=this.getUrlParameter("subscriberCode"),this.webRTCAdaptor=new v({websocketUrl:this.options.mediaServerUrl,mediaConstraints:this.options.mediaConstraints,pcConfig:this.options.pcConfig,sdpConstraints:this.options.sdpConstraints,player:this.player,callback:function(e,n){switch(e){case k:t.initializedHandler();break;case S:t.joinStreamHandler(n);break;case w:t.leaveStreamHandler(n);break;case I:t.streamInformationHandler(n);break;case P:t.resolutionChangeHandler(n);break;default:t.defaultHandler(e)}},callbackError:function(e){var i=n.default.getComponent("ModalDialog");t.errorModal&&t.errorModal.close(),t.errorModal=new i(t.player,{content:"ERROR: "+JSON.stringify(e),temporary:!0,pauseOnOpen:!1,uncloseable:!0}),t.player.addChild(t.errorModal),t.errorModal.open(),t.errorModal.setTimeout((function(){return t.errorModal.close()}),3e3)}})},i.initializedHandler=function(){this.webRTCAdaptor.play(this.options.streamName,this.options.token,this.options.subscriberId,this.options.subscriberCode)},i.joinStreamHandler=function(e){this.webRTCAdaptor.getStreamInfo(this.options.streamName)},i.leaveStreamHandler=function(){this.player.resolutions=[],this.player.controlBar.getChild("ResolutionMenuButton").update()},i.streamInformationHandler=function(e){var t=e.streamInfo.reduce((function(e,t){return e.includes(t.streamHeight)?e:[].concat(e,[t.streamHeight])}),[]).sort((function(e,t){return t-e}));this.player.resolutions=t.map((function(e){return{label:e,value:e}})),this.player.selectedResolution=0,this.addResolutionButton()},i.addResolutionButton=function(){var e=this.player.controlBar,t=e.getChild("fullscreenToggle").el();e.getChild("ResolutionMenuButton")&&e.removeChild("ResolutionMenuButton"),e.el().insertBefore(e.addChild("ResolutionMenuButton",{plugin:this,streamName:this.options.streamName}).el(),t)},i.resolutionChangeHandler=function(e){var t=this;this.player.spinner=document.createElement("div"),this.player.spinner.className="vjs-custom-spinner",this.player.el().appendChild(this.player.spinner),this.player.pause(),this.player.setTimeout((function(){t.player.el().getElementsByClassName("vjs-custom-spinner").length&&(t.player.el().removeChild(t.player.spinner),t.player.play())}),2e3)},i.defaultHandler=function(e){},i.changeStreamQuality=function(e){this.webRTCAdaptor.forceStreamQuality(this.options.streamName,e),this.player.selectedResolution=e,this.player.controlBar.getChild("ResolutionMenuButton").update()},i.getUrlParameter=function(e){return this.options.streamUrl.split("?")[1].split("&").reduce((function(e,t){var n=t.split("=");return e[decodeURIComponent(n[0])]=decodeURIComponent(n[1]),e}),{})[e]},t}(x);return _.defaultState={},_.VERSION="1.0.0",n.default.registerPlugin("antmediaWebrtc",_),_})); | ||
/*! @name @antmedia/videojs-webrtc-plugin @version 1.1.0 @license MIT */ | ||
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t(require("video.js")):"function"==typeof define&&define.amd?define(["video.js"],t):(e="undefined"!=typeof globalThis?globalThis:e||self).videojsWebrtcPlugin=t(e.videojs)}(this,(function(e){"use strict";function t(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var n=t(e),o="takeCandidate",i="takeConfiguration",r="play",a="stop",s="getStreamInfo",c="peerMessageCommand",d="forceStreamQuality",l="error",u="notification",p="streamInformation",h="ping",f="pong",m="trackList",C=function(){function e(e){for(var t in e)e.hasOwnProperty(t)&&(this[t]=e[t]);this.initWebSocketConnection()}var t=e.prototype;return t.initWebSocketConnection=function(e){var t=this;this.connecting=!0,this.connected=!1,this.pingTimerId=-1,this.wsConn=new WebSocket(this.websocketUrl),this.wsConn.onopen=function(){t.pingTimerId=setInterval((function(){t.sendPing()}),3e3),t.connected=!0,t.connecting=!1,t.callback("initialized"),void 0!==e&&e()},this.wsConn.onmessage=function(e){var n=JSON.parse(e.data);switch(n.command){case o:t.webrtcadaptor.takeCandidate(n.streamId,n.label,n.candidate);break;case i:t.webrtcadaptor.takeConfiguration(n.streamId,n.sdp,n.type,n.idMapping);break;case a:t.webrtcadaptor.closePeerConnection(n.streamId);break;case l:t.callbackError(n.definition);break;case u:t.callback(n.definition,n),"play_finished"!==n.definition&&"publish_finished"!==n.definition||t.webrtcadaptor.closePeerConnection(n.streamId);break;case p:t.callback(n.command,n);break;case f:t.callback(n.command);break;case m:case c:t.callback(n.command,n)}},this.wsConn.onerror=function(e){t.connecting=!1,t.connected=!1,t.clearPingTimer(),t.callbackError("WebSocketNotConnected",e)},this.wsConn.onclose=function(e){t.connecting=!1,t.connected=!1,t.clearPingTimer(),t.callback("closed",e)}},t.clearPingTimer=function(){-1!==this.pingTimerId&&(clearInterval(this.pingTimerId),this.pingTimerId=-1)},t.sendPing=function(){var e={command:h};this.wsConn.send(JSON.stringify(e))},t.close=function(){this.wsConn.close()},t.send=function(e){var t=this;this.connecting||this.connected?this.wsConn.send(e):this.initWebSocketConnection((function(){t.send(e)}))},t.isConnected=function(){return this.connected},t.isConnecting=function(){return this.connecting},e}(),b=function(){function e(e){for(var t in this.pcConfig=null,this.websocketUrl=null,this.sdpConstraints=null,this.remotePeerConnection=[],this.remoteDescriptionSet=[],this.iceCandidateList=[],this.playStreamId=[],this.player=null,this.webSocketAdaptor=null,this.viewerInfo="",this.idMapping=[],this.candidateTypes=["udp","tcp"],e)e.hasOwnProperty(t)&&(this[t]=e[t]);this.remoteVideo=this.player,this.checkWebSocketConnection()}var t=e.prototype;return t.play=function(e,t,n,o){this.playStreamId.push(e);var i={command:r,streamId:e,token:t,subscriberId:n||"",subscriberCode:o||"",viewerInfo:this.viewerInfo};this.webSocketAdaptor.send(JSON.stringify(i))},t.stop=function(e){this.closePeerConnection(e);var t={command:a,streamId:e};this.webSocketAdaptor.send(JSON.stringify(t))},t.getStreamInfo=function(e){var t={command:s,streamId:e};this.webSocketAdaptor.send(JSON.stringify(t))},t.onTrack=function(e,t){if(this.remoteVideo){var n=this.remoteVideo.tech().el();n.srcObject!==e.streams[0]&&(n.srcObject=e.streams[0])}},t.iceCandidateReceived=function(e,t){if(e.candidate){var n=!1;if(""===e.candidate.candidate?n=!0:void 0===e.candidate.protocol?this.candidateTypes.forEach((function(t){e.candidate.candidate.toLowerCase().includes(t)&&(n=!0)})):n=this.candidateTypes.includes(e.candidate.protocol.toLowerCase()),n){var i={command:o,streamId:t,label:e.candidate.sdpMLineIndex,id:e.candidate.sdpMid,candidate:e.candidate.candidate};this.webSocketAdaptor.send(JSON.stringify(i))}else""!==e.candidate.candidate&&this.callbackError("protocol_not_supported","Support protocols: "+this.candidateTypes.toString()+" candidate: "+e.candidate.candidate)}},t.initPeerConnection=function(e){var t=this;if(!this.remotePeerConnection[e]){var n=e;this.remotePeerConnection[e]=new RTCPeerConnection(this.pcConfig),this.remoteDescriptionSet[e]=!1,this.iceCandidateList[e]=[],this.remotePeerConnection[e].onicecandidate=function(e){t.iceCandidateReceived(e,n)},this.remotePeerConnection[e].ontrack=function(e){t.onTrack(e,n)},this.remotePeerConnection[e].oniceconnectionstatechange=function(){var n={state:t.remotePeerConnection[e].iceConnectionState,streamId:e};t.callback("ice_connection_state_changed",n)}}},t.closePeerConnection=function(e){this.remotePeerConnection[e]&&"closed"!==this.remotePeerConnection[e].signalingState&&(this.remotePeerConnection[e].close(),this.remotePeerConnection[e]=null,delete this.remotePeerConnection[e],this.playStreamId=this.playStreamId.filter((function(t){return t!==e})))},t.gotDescription=function(e,t){var n=this;this.remotePeerConnection[t].setLocalDescription(e).then((function(){var o={command:i,streamId:t,type:e.type,sdp:e.sdp};n.webSocketAdaptor.send(JSON.stringify(o))}))},t.takeConfiguration=function(e,t,n,o){var i=this,r=e;this.idMapping[r]=o,this.initPeerConnection(r),this.remotePeerConnection[r].setRemoteDescription({sdp:t,type:n}).then((function(){i.remoteDescriptionSet[r]=!0;for(var e=i.iceCandidateList[r].length,t=0;t<e;t++)i.addIceCandidate(r,i.iceCandidateList[r][t]);i.iceCandidateList[r]=[],"offer"===n&&i.remotePeerConnection[r].createAnswer(i.sdpConstraints).then((function(e){e.sdp=e.sdp.replace("useinbandfec=1","useinbandfec=1; stereo=1"),i.gotDescription(e,r)}))})).catch((function(e){(e.toString().includes("InvalidAccessError")||e.toString().includes("setRemoteDescription"))&&i.callbackError("notSetRemoteDescription")}))},t.takeCandidate=function(e,t,n){var o=e,i=new RTCIceCandidate({sdpMLineIndex:t,candidate:n});this.initPeerConnection(o),!0===this.remoteDescriptionSet[o]?this.addIceCandidate(o,i):this.iceCandidateList[o].push(i)},t.addIceCandidate=function(e,t){var n=!1;""===t.candidate?n=!0:void 0===t.protocol?this.candidateTypes.forEach((function(e){t.candidate.toLowerCase().includes(e)&&(n=!0)})):n=this.candidateTypes.includes(t.protocol.toLowerCase()),n&&this.remotePeerConnection[e].addIceCandidate(t)},t.closeWebSocket=function(){for(var e in this.remotePeerConnection)this.remotePeerConnection[e].close();this.remotePeerConnection=[],this.webSocketAdaptor.close()},t.checkWebSocketConnection=function(){var e=this.webSocketAdaptor,t=e&&this.webSocketAdaptor.isConnected()&&this.webSocketAdaptor.isConnecting();if(!e||!t)try{this.webSocketAdaptor=new C({websocketUrl:this.websocketUrl,webrtcadaptor:this,callback:this.callback,callbackError:this.callbackError})}catch(e){this.player.createModal("WebSocket connect error")}},t.peerMessage=function(e,t,n){var o={command:c,streamId:e,definition:t,data:n};this.webSocketAdaptor.send(JSON.stringify(o))},t.forceStreamQuality=function(e,t){var n={command:d,streamId:e,streamHeight:t};this.webSocketAdaptor.send(JSON.stringify(n))},e}(),g="initialized",y="play_started",v="play_finished",k="streamInformation",S="resolutionChangeInfo";function w(e,t,n){return e(n={path:t,exports:{},require:function(e,t){return function(){throw new Error("Dynamic requires are not currently supported by @rollup/plugin-commonjs")}(null==t&&n.path)}},n.exports),n.exports}var I=w((function(e){e.exports=function(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e},e.exports.default=e.exports,e.exports.__esModule=!0})),P=w((function(e){function t(n,o){return e.exports=t=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e},e.exports.default=e.exports,e.exports.__esModule=!0,t(n,o)}e.exports=t,e.exports.default=e.exports,e.exports.__esModule=!0})),R=w((function(e){e.exports=function(e,t){e.prototype=Object.create(t.prototype),e.prototype.constructor=e,P(e,t)},e.exports.default=e.exports,e.exports.__esModule=!0})),T=n.default.getComponent("MenuItem"),M=n.default.getComponent("Component"),O=function(e){function t(t,n){return n.selectable=!0,n.multiSelectable=!1,e.call(this,t,n)||this}return R(t,e),t.prototype.handleClick=function(){this.options().plugin.changeStreamQuality(this.options().value)},t}(T);M.registerComponent("ResolutionMenuItem",O);var j=n.default.getComponent("MenuButton"),N=function(e){function t(t,n){var o;return o=e.call(this,t,n)||this,j.apply(I(o),arguments),o}R(t,e);var o=t.prototype;return o.createEl=function(){return n.default.dom.createEl("div",{className:"vjs-http-source-selector vjs-menu-button vjs-menu-button-popup vjs-control vjs-button"})},o.buildCSSClass=function(){return j.prototype.buildCSSClass.call(this)+" vjs-icon-cog"},o.update=function(){return j.prototype.update.call(this)},o.createItems=function(){for(var e=[],t=[{label:"auto",value:0}].concat(this.player().resolutions),n=0;n<t.length;n++)e.push(new O(this.player_,{label:t[n].label,value:t[n].value,selected:t[n].value===this.player().selectedResolution,plugin:this.options().plugin,streamName:this.options().streamName}));return e},t}(j),x={sdpConstraints:{OfferToReceiveAudio:!0,OfferToReceiveVideo:!0},mediaConstraints:{video:!1,audio:!1}},A=function(){function e(e,t,o){var i=this;this.player=n.default(o.playerId),this.initiateWebRTCAdaptor(e,o),this.player.ready((function(){i.player.addClass("videojs-webrtc-plugin")})),this.player.on("playing",(function(){i.player.el().getElementsByClassName("vjs-custom-spinner").length&&i.player.el().removeChild(i.player.spinner)})),n.default.registerComponent("ResolutionMenuButton",N),n.default.registerComponent("ResolutionMenuItem",O)}var t=e.prototype;return t.initiateWebRTCAdaptor=function(e,t){var o=this;this.options=n.default.mergeOptions(x,t),this.source=e,this.source.pcConfig={iceServers:JSON.parse(e.iceservers)},this.source.mediaServerUrl=e.src.split("/").slice(0,4).join("/")+"/websocket",this.source.streamName=e.src.split("/")[4].split(".webrtc")[0],this.source.token=this.getUrlParameter("token"),this.source.subscriberId=this.getUrlParameter("subscriberId"),this.source.subscriberCode=this.getUrlParameter("subscriberCode"),this.webRTCAdaptor=new b({websocketUrl:this.source.mediaServerUrl,mediaConstraints:this.source.mediaConstraints,pcConfig:this.source.pcConfig,sdpConstraints:this.source.sdpConstraints,player:this.player,callback:function(e,t){switch(e){case g:o.initializedHandler();break;case y:o.joinStreamHandler(t);break;case v:o.leaveStreamHandler(t);break;case k:o.streamInformationHandler(t);break;case S:o.resolutionChangeHandler(t);break;default:o.defaultHandler(e)}},callbackError:function(e){var t=n.default.getComponent("ModalDialog");o.errorModal&&o.errorModal.close(),o.errorModal=new t(o.player,{content:"ERROR: "+JSON.stringify(e),temporary:!0,pauseOnOpen:!1,uncloseable:!0}),o.player.addChild(o.errorModal),o.errorModal.open(),o.errorModal.setTimeout((function(){return o.errorModal.close()}),3e3),o.player.trigger("webrtc-error",{error:e})}})},t.initializedHandler=function(){this.webRTCAdaptor.play(this.source.streamName,this.source.token,this.source.subscriberId,this.source.subscriberCode)},t.joinStreamHandler=function(e){this.webRTCAdaptor.getStreamInfo(this.source.streamName)},t.leaveStreamHandler=function(){this.player.resolutions=[],this.player.controlBar.getChild("ResolutionMenuButton").update()},t.streamInformationHandler=function(e){var t=e.streamInfo.reduce((function(e,t){return e.includes(t.streamHeight)?e:[].concat(e,[t.streamHeight])}),[]).sort((function(e,t){return t-e}));this.player.resolutions=t.map((function(e){return{label:e,value:e}})),this.player.selectedResolution=0,this.addResolutionButton()},t.addResolutionButton=function(){var e=this.player.controlBar,t=e.getChild("fullscreenToggle").el();e.getChild("ResolutionMenuButton")&&e.removeChild("ResolutionMenuButton"),e.el().insertBefore(e.addChild("ResolutionMenuButton",{plugin:this,streamName:this.source.streamName}).el(),t)},t.resolutionChangeHandler=function(e){var t=this;this.player.spinner=document.createElement("div"),this.player.spinner.className="vjs-custom-spinner",this.player.el().appendChild(this.player.spinner),this.player.pause(),this.player.setTimeout((function(){t.player.el().getElementsByClassName("vjs-custom-spinner").length&&(t.player.el().removeChild(t.player.spinner),t.player.play())}),2e3)},t.defaultHandler=function(e){},t.changeStreamQuality=function(e){this.webRTCAdaptor.forceStreamQuality(this.source.streamName,e),this.player.selectedResolution=e,this.player.controlBar.getChild("ResolutionMenuButton").update()},t.getUrlParameter=function(e){return this.source.src.includes("?")?(this.source.src.split("?")[1].split("&").reduce((function(e,t){var n=t.split("=");return e[decodeURIComponent(n[0])]=decodeURIComponent(n[1]),e}),{})||{})[e]:null},e}(),_={name:"videojs-webrtc-plugin",VERSION:"1.1",canHandleSource:function(e,t){void 0===t&&(t={});var o=n.default.mergeOptions(n.default.options,t);return o.source=e.src,_.canPlayType(e.type,o)},handleSource:function(e,t,o){void 0===o&&(o={});var i=n.default.mergeOptions(n.default.options,o);return t.webrtc=new A(e,t,i),t.webrtc},canPlayType:function(e,t){return void 0===t&&(t={}),t.source.split("/")[4].includes(".webrtc")?"maybe":""}};return n.default.getTech("Html5").registerSourceHandler(_,0),{WebRTCHandler:A,webRTCSourceHandler:_}})); |
{ | ||
"name": "@antmedia/videojs-webrtc-plugin", | ||
"version": "1.0.0", | ||
"version": "1.1.0", | ||
"description": "streaming via WebRTC with Ant-MediaServer", | ||
@@ -36,3 +36,3 @@ "main": "dist/videojs-webrtc-plugin.cjs.js", | ||
"type": "git", | ||
"url": "git+https://github.com/ant-media/videojs-webrtc-plugin.git" | ||
"url": "git+https://github.com/ant-media/videojs-webrtc-plugin" | ||
}, | ||
@@ -51,3 +51,3 @@ "bugs": { | ||
], | ||
"author": "ForaSoft", | ||
"author": "AntMedia", | ||
"license": "MIT", | ||
@@ -101,6 +101,3 @@ "vjsstandard": { | ||
"videojs-standard": "^8.0.4" | ||
}, | ||
"directories": { | ||
"test": "test" | ||
} | ||
} |
@@ -13,3 +13,3 @@ # videojs-webrtc-plugin | ||
- [Usage](#usage) | ||
- [Options Object](#options-object) | ||
- [Source Object](#source-object) | ||
- [**streamUrl**](#streamurl) | ||
@@ -20,2 +20,3 @@ - [**iceServers**](#iceservers) | ||
- [RequireJS/AMD](#requirejsamd) | ||
- [Handling error-callbacks](#handling-error-callbacks) | ||
- [License](#license) | ||
@@ -34,15 +35,14 @@ | ||
### Options Object | ||
### Source Object | ||
#### **streamUrl** | ||
Websocket Ant-MediaServer address format: | ||
Ant-MediaServer stream address format: | ||
```js | ||
ws://[ant-address]/[app]/websocket?streamId=[streamId]&token=[token(opt)]&subscriberId=[subscriberId(opt)]&subscriberCode=[TOTP-code(opt)] | ||
ws://[ant-address]/[app]/[streamId].webrtc?token=[token(opt)]&subscriberId=[subscriberId(opt)]&subscriberCode=[TOTP-code(opt)] | ||
``` | ||
link example: | ||
```js | ||
wss://12.23.322.157:5080/LiveApp/websocket?streamId=test | ||
ws://12.23.322.157:5080/LiveApp/stream1.webrtc | ||
``` | ||
parameters: | ||
- streamId - Id of the stream published on the media server | ||
- token (optional) - a one-time token generated for the stream (in case the stream is protected by the one-time token protection mechanism | ||
@@ -65,9 +65,12 @@ - subscriberId (optional) - subscriber Id. Required if the stream is protected by a TOTP password | ||
<script src="//path/to/videojs-webrtc-plugin.min.js"></script> | ||
<div id="video_container"> | ||
<video id=video-player width=960 height=540 class="video-js vjs-default-skin" controls> | ||
<source | ||
src="ws://localhost:5080/LiveApp/stream1.webrtc" iceServers = '[ { "urls": "stun:stun1.l.google.com:19302" } ]' | ||
> | ||
</video> | ||
</div> | ||
<script> | ||
var player = videojs('my-video'); | ||
player.antmediaWebrtc({ | ||
streamUrl: "ws://[ant-address]/[app]/websocket?streamId=[streamId]", | ||
iceServers: '[ { "urls": "stun:stun1.l.google.com:19302" } ]', | ||
}); | ||
</script> | ||
@@ -90,5 +93,5 @@ ``` | ||
player.antmediaWebrtc({ | ||
streamUrl: "ws://[ant-address]/[app]/websocket?streamId=[streamId]", | ||
iceServers: '[ { "urls": "stun:stun1.l.google.com:19302" } ]', | ||
player.src({ | ||
src: 'ws://localhost:5080/LiveApp/stream1.webrtc', | ||
iceServers: '[ { "urls": "stun:stun1.l.google.com:19302" } ]' | ||
}); | ||
@@ -105,13 +108,34 @@ ``` | ||
player.antmediaWebrtc({ | ||
streamUrl: "ws://[ant-address]/[app]/websocket?streamId=[streamId]", | ||
iceServers: '[ { "urls": "stun:stun1.l.google.com:19302" } ]', | ||
player.src({ | ||
src: 'ws://localhost:5080/LiveApp/stream1.webrtc', | ||
iceServers: '[ { "urls": "stun:stun1.l.google.com:19302" } ]' | ||
}); | ||
}); | ||
``` | ||
### Handling error-callbacks | ||
Ant-MediaServer has functionality to handle errors coming from the backend. | ||
To catch an error, you need to subscribe to the event "ant-error": | ||
```js | ||
<script src="//path/to/video.min.js"></script> | ||
<script src="//path/to/videojs-webrtc-plugin.min.js"></script> | ||
<script> | ||
var player = videojs('my-video'); | ||
player.src({ | ||
src: 'ws://localhost:5080/LiveApp/stream1.webrtc', | ||
iceServers: '[ { "urls": "stun:stun1.l.google.com:19302" } ]' | ||
}); | ||
player.on('ant-error', function(event, errors) { | ||
console.log(errors); | ||
}); | ||
</script> | ||
``` | ||
## License | ||
MIT. Copyright (c) ForaSoft | ||
MIT. Copyright (c) Ant Media | ||
[videojs]: http://videojs.com/ |
import videojs from 'video.js'; | ||
import {version as VERSION} from '../package.json'; | ||
import {WebRTCAdaptor} from './webrtc_adaptor'; | ||
@@ -8,4 +7,2 @@ import {ANT_CALLBACKS} from './const/CALLBACKS'; | ||
const Plugin = videojs.getPlugin('plugin'); | ||
// Default options for the plugin. | ||
@@ -20,19 +17,20 @@ const defaults = { | ||
class AntmediaWebrtc extends Plugin { | ||
class WebRTCHandler { | ||
/** | ||
* Create a AntmediaWebrtc plugin instance. | ||
* Create a WebRTC source handler instance. | ||
* | ||
* @param {Player} player | ||
* A Video.js Player instance. | ||
* @param {Object} source | ||
* Source object that is given in the DOM, includes the stream URL | ||
* | ||
* @param {Object} [options] | ||
* An optional options object. | ||
* | ||
* While not a core part of the Video.js plugin architecture, a | ||
* second argument of options is a convenient way to accept inputs | ||
* from your plugin's caller. | ||
* Options include: | ||
* ICE Server | ||
* Tokens | ||
* Subscriber ID | ||
* Subscriber code | ||
*/ | ||
constructor(player, options) { | ||
super(player); | ||
this.initiateWebRTCAdaptor(options); | ||
constructor(source, tech, options) { | ||
this.player = videojs(options.playerId); | ||
this.initiateWebRTCAdaptor(source, options); | ||
this.player.ready(() => { | ||
@@ -56,16 +54,19 @@ this.player.addClass('videojs-webrtc-plugin'); | ||
*/ | ||
initiateWebRTCAdaptor(options) { | ||
initiateWebRTCAdaptor(source, options) { | ||
this.options = videojs.mergeOptions(defaults, options); | ||
this.options.pcConfig = { iceServers: JSON.parse(options.iceServers) }; | ||
this.options.mediaServerUrl = options.streamUrl.split('?')[0]; | ||
this.options.streamName = this.getUrlParameter('streamId'); | ||
this.options.token = this.getUrlParameter('token'); | ||
this.options.subscriberId = this.getUrlParameter('subscriberId'); | ||
this.options.subscriberCode = this.getUrlParameter('subscriberCode'); | ||
this.source = source; | ||
this.source.pcConfig = { iceServers: JSON.parse(source.iceservers) }; | ||
this.source.mediaServerUrl = `${source.src.split('/').slice(0, 4).join('/')}/websocket`; | ||
this.source.streamName = source.src.split('/')[4].split('.webrtc')[0]; | ||
this.source.token = this.getUrlParameter('token'); | ||
this.source.subscriberId = this.getUrlParameter('subscriberId'); | ||
this.source.subscriberCode = this.getUrlParameter('subscriberCode'); | ||
this.webRTCAdaptor = new WebRTCAdaptor({ | ||
websocketUrl: this.options.mediaServerUrl, | ||
mediaConstraints: this.options.mediaConstraints, | ||
pcConfig: this.options.pcConfig, | ||
sdpConstraints: this.options.sdpConstraints, | ||
websocketUrl: this.source.mediaServerUrl, | ||
mediaConstraints: this.source.mediaConstraints, | ||
pcConfig: this.source.pcConfig, | ||
sdpConstraints: this.source.sdpConstraints, | ||
player: this.player, | ||
@@ -117,2 +118,3 @@ callback: (info, obj) => { | ||
this.errorModal.setTimeout(() => this.errorModal.close(), 3000); | ||
this.player.trigger('webrtc-error', { error }); | ||
} | ||
@@ -126,6 +128,6 @@ }); | ||
this.webRTCAdaptor.play( | ||
this.options.streamName, | ||
this.options.token, | ||
this.options.subscriberId, | ||
this.options.subscriberCode | ||
this.source.streamName, | ||
this.source.token, | ||
this.source.subscriberId, | ||
this.source.subscriberCode | ||
); | ||
@@ -139,3 +141,3 @@ } | ||
joinStreamHandler(obj) { | ||
this.webRTCAdaptor.getStreamInfo(this.options.streamName); | ||
this.webRTCAdaptor.getStreamInfo(this.source.streamName); | ||
} | ||
@@ -176,3 +178,3 @@ /** | ||
plugin: this, | ||
streamName: this.options.streamName | ||
streamName: this.source.streamName | ||
}).el(), fullscreenToggle); | ||
@@ -209,3 +211,3 @@ } | ||
changeStreamQuality(value) { | ||
this.webRTCAdaptor.forceStreamQuality(this.options.streamName, value); | ||
this.webRTCAdaptor.forceStreamQuality(this.source.streamName, value); | ||
this.player.selectedResolution = value; | ||
@@ -222,25 +224,57 @@ this.player.controlBar.getChild('ResolutionMenuButton').update(); | ||
getUrlParameter(param) { | ||
const urlParams = this.options.streamUrl.split('?')[1].split('&').reduce( | ||
(p, e) => { | ||
const a = e.split('='); | ||
if (this.source.src.includes('?')) { | ||
const urlParams = this.source.src.split('?')[1].split('&').reduce( | ||
(p, e) => { | ||
const a = e.split('='); | ||
p[ decodeURIComponent(a[0])] = decodeURIComponent(a[1]); | ||
return p; | ||
}, | ||
{} | ||
); | ||
p[decodeURIComponent(a[0])] = decodeURIComponent(a[1]); | ||
return p; | ||
}, | ||
{} | ||
) || {}; | ||
return urlParams[param]; | ||
return urlParams[param]; | ||
} | ||
return null; | ||
} | ||
} | ||
// Define default values for the plugin's `state` object here. | ||
AntmediaWebrtc.defaultState = {}; | ||
const webRTCSourceHandler = { | ||
name: 'videojs-webrtc-plugin', | ||
VERSION: '1.1', | ||
canHandleSource(srcObj, options = {}) { | ||
const localOptions = videojs.mergeOptions(videojs.options, options); | ||
// Include the version number. | ||
AntmediaWebrtc.VERSION = VERSION; | ||
localOptions.source = srcObj.src; | ||
// Register the plugin with video.js. | ||
videojs.registerPlugin('antmediaWebrtc', AntmediaWebrtc); | ||
return webRTCSourceHandler.canPlayType(srcObj.type, localOptions); | ||
}, | ||
handleSource(source, tech, options = {}) { | ||
const localOptions = videojs.mergeOptions(videojs.options, options); | ||
export default AntmediaWebrtc; | ||
// Register the plugin to source handler tech | ||
tech.webrtc = new WebRTCHandler(source, tech, localOptions); | ||
return tech.webrtc; | ||
}, | ||
canPlayType(type, options = {}) { | ||
const mediaUrl = options.source; | ||
if (mediaUrl.split('/')[4].includes('.webrtc')) { | ||
return 'maybe'; | ||
} | ||
return ''; | ||
} | ||
}; | ||
// register source handlers with the appropriate techs | ||
videojs.getTech('Html5').registerSourceHandler(webRTCSourceHandler, 0); | ||
export default | ||
{ | ||
WebRTCHandler, | ||
webRTCSourceHandler | ||
}; |
import {WebSocketAdaptor} from './websocket_adaptor.js'; | ||
import {COMMANDS} from './const/COMMANDS'; | ||
// A sample to put it in the src method of the videoJS player | ||
// so that the stream can be played (stream cannot be played without source) | ||
const DEFAULT_VIDEO_FALLBACK = 'http://vjs.zencdn.net/v/oceans.mp4'; | ||
/** | ||
@@ -103,3 +99,2 @@ * Adaptor for WebRTC methods | ||
if (this.remoteVideo) { | ||
this.remoteVideo.src({ type: 'video/mp4', src: DEFAULT_VIDEO_FALLBACK }); | ||
const vid = this.remoteVideo.tech().el(); | ||
@@ -106,0 +101,0 @@ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Unpublished package
Supply chain riskPackage version was not found on the registry. It may exist on a different registry and need to be configured to pull from that registry.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Unpopular package
QualityThis package is not very popular.
Found 1 instance in 1 package
142128
24
3613
0
136
1