JSWebrtc.Player = (function () { "use strict"; var Player = function (url, options) { this.options = options || {}; if (!url.match(/^webrtc?:\/\//) && !url.match(/^webrtcs?:\/\//)) { throw ("JSWebrtc just work with webrtc"); } if (!this.options.video) { throw ("VideoElement is null"); } this.urlParams = JSWebrtc.ParseUrl(url); this.pc = null; this.autoplay = !!options.autoplay || false; this.paused = true; // set muted for autoplay if (this.autoplay) this.options.video.muted = true; this.startLoading(); }; Player.prototype.startLoading = function () { var _self = this; if (_self.pc) { _self.pc.close(); } _self.pc = new RTCPeerConnection(null); _self.pc.ontrack = function (event) { _self.options.video['srcObject'] = event.streams[0]; }; _self.pc.addTransceiver("audio", { direction: "recvonly" }); _self.pc.addTransceiver("video", { direction: "recvonly" }); _self.pc.createOffer().then(function (offer) { return _self.pc.setLocalDescription(offer).then(function () { return offer; }); }).then(function (offer) { return new Promise(function (resolve, reject) { var port = _self.urlParams.port || 1985; // @see https://github.com/rtcdn/rtcdn-draft var api = _self.urlParams.user_query.play || '/rtc/v1/play/'; if (api.lastIndexOf('/') != api.length - 1) { api += '/'; } var url = 'https://' + _self.urlParams.server + ':' + port + api; for (var key in _self.urlParams.user_query) { if (key != 'api' && key != 'play') { url += '&' + key + '=' + _self.urlParams.user_query[key]; } } // @see https://github.com/rtcdn/rtcdn-draft var data = { api: url, streamurl: _self.urlParams.url, clientip: null, sdp: offer.sdp }; console.log("offer: " + JSON.stringify(data)); JSWebrtc.HttpPost(url, JSON.stringify(data)).then(function (res) { console.log("answer: " + JSON.stringify(res)); resolve(res.sdp); }, function (rej) { reject(rej); }) }); }).then(function (answer) { return _self.pc.setRemoteDescription(new RTCSessionDescription({ type: 'answer', sdp: answer })); }).catch(function (reason) { throw reason; }); if (this.autoplay) { this.play(); } }; Player.prototype.play = function (ev) { if (this.animationId) { return; } this.animationId = requestAnimationFrame(this.update.bind(this)); this.paused = false; }; Player.prototype.pause = function (ev) { if (this.paused) { return; } cancelAnimationFrame(this.animationId); this.animationId = null; this.isPlaying = false; this.paused = true; this.options.video.pause(); if (this.options.onPause) { this.options.onPause(this); } }; Player.prototype.stop = function (ev) { this.pause(); }; Player.prototype.destroy = function () { this.pause(); this.pc && this.pc.close() && this.pc.destroy(); this.audioOut && this.audioOut.destroy(); }; Player.prototype.update = function () { this.animationId = requestAnimationFrame(this.update.bind(this)); if (this.options.video.readyState < 4) { return; } if (!this.isPlaying) { this.isPlaying = true; this.options.video.play(); if (this.options.onPlay) { this.options.onPlay(this); } } }; return Player; })();