symple-client-player-fixed
Version:
Symple realtime media player - Fixed
1 lines • 7.72 kB
JavaScript
!function(a){a.Player=a.Emitter.extend({init:function(b,c){if(this._super(),this.options=a.extend({template:' <div class="symple-player"> <div class="symple-player-message"></div> <div class="symple-player-status"></div> <div class="symple-player-loading"></div> <div class="symple-player-screen"></div> <div class="symple-player-controls"> <a class="play-btn" rel="play" href="#">Play</a> <a class="stop-btn" rel="stop" href="#">Stop</a> <a class="fullscreen-btn" rel="fullscreen" href="#">Fullscreen</a> </div> </div>'},c),this.element=b,a.hasClass(this.element,"symple-player")||(this.element.innerHTML=this.options.template),!this.element)throw"Player element not found";if(this.screen=this.element.getElementsByClassName("symple-player-screen")[0],!this.screen)throw"Player screen element not found";if(this.message=this.element.getElementsByClassName("symple-player-message")[0],!this.message)throw"Player message element not found";this.setup(),this.bind()},setup:function(){},play:function(){this.setState("playing")},stop:function(){this.setState("stopped")},destroy:function(){},mute:function(){},setError:function(a,b){this.setState("error",b)},setState:function(b,c){return a.log("symple:player: set state",this.state,"<=>",b),this.state===b?!1:(this.state=b,this.displayStatus(null),this.playing="playing"===b,c?this.displayMessage("error"===b?"error":"info",c):this.displayMessage(null),void this.emit("state",b,c))},displayStatus:function(a){var b=this.element.getElementsByClassName("symple-player-status")[0];b&&(b.innerHTML=a||"")},displayMessage:function(b,c){a.log("symple:player: display message",b,c),c?(this.message.innerHTML='<p class="'+b+'-message">'+c+"</p>",this.message.style.display="block"):this.message.style.display="none"},bind:function(){var a=this;this.element.addEventListener("loaded",function(){return a.onAction(this.rel,this),!1})},onAction:function(a,b){switch(a){case"play":this.play();break;case"stop":this.stop();break;case"mute":this.mute(!0);break;case"unmute":this.mute(!1);break;case"fullscreen":this.toggleFullScreen();break;default:this.emit("action",a,b)}},toggleFullScreen:function(){var b=this.options.fullscreenElement||this.element;a.runVendorMethod(document,"FullScreen")||a.runVendorMethod(document,"IsFullScreen")?a.runVendorMethod(document,"CancelFullScreen"):a.runVendorMethod(b,"RequestFullScreen")}}),a.Media={engines:{},register:function(b){return a.log("symple:media: register media engine: ",b),b.name&&"undefined"!=typeof b.preference&&"undefined"!=typeof b.support?(this.engines[b.id]=b,!0):(a.log("symple:media: cannot register invalid engine",b),!1)},has:function(a){return"object"==typeof this.engines[a]},supports:function(a){return!(!this.has(a)||!this.engines[a].support)},supportsFormat:function(a){return!!preferredEngine(a)},compatibleEngines:function(){var b,c=[];for(var d in this.engines)b=this.engines[d],0!==b.preference&&(a.log("symple:media: supported",b.name,b.support),b.support===!0&&c.push(b));return c.sort(function(a,b){return a.preference<b.preference?1:a.preference>b.preference?-1:void 0}),c},preferredEngine:function(b){var c=this.compatibleEngines(b),d=c.length?c[0]:null;return a.log("symple:media: preferred engine",d),d},buildURL:function(a){var b,c=[],d=a.address;b=d.scheme+"://"+d.host+":"+d.port+(d.uri?d.uri:"/");for(var e in a)"address"!=e&&c.push(encodeURIComponent(e)+"="+encodeURIComponent(a[e]));return c.push("rand="+Math.random()),b+="?",b+=c.join("&")}}}(window.Symple=window.Symple||{}),function(a){window.RTCPeerConnection=window.mozRTCPeerConnection||window.webkitRTCPeerConnection,window.RTCSessionDescription=window.mozRTCSessionDescription||window.RTCSessionDescription,window.RTCIceCandidate=window.mozRTCIceCandidate||window.RTCIceCandidate,window.URL=window.webkitURL||window.URL,navigator.getUserMedia=navigator.getUserMedia||navigator.webkitGetUserMedia||navigator.mozGetUserMedia||navigator.msGetUserMedia,a.Media.register({id:"WebRTC",name:"WebRTC Player",formats:"VP9, VP4, H.264, Opus",preference:100,support:function(){return"undefined"!=typeof RTCPeerConnection}()}),a.Player.WebRTC=a.Player.extend({init:function(b,c){a.log("symple:webrtc: init"),this.stream=null,this._super(b,a.extend({initiator:!0,rtcConfig:{iceServers:[{url:"stun:stun.l.google.com:19302"}]},userMediaConstraints:{audio:!0,video:!0},sdpConstraints:{mandatory:{OfferToReceiveAudio:!0,OfferToReceiveVideo:!0}}},c))},setup:function(){a.log("symple:webrtc: setup"),this._createPeerConnection(),"undefined"==typeof this.video&&(this.video=document.createElement("video"),this.video.autoplay=!0,this.screen.appendChild(this.video))},destroy:function(){a.log("symple:webrtc: destroy"),this.stream&&(!this.stream.stop&&this.stream.getTracks&&(this.stream.stop=function(){this.getTracks().forEach(function(a){a.stop()})}),this.stream.stop(),this.stream=null),this.video&&(this.video.src="",this.video=null),this.pc&&(this.pc.close(),this.pc=null)},play:function(b){if(a.log("symple:webrtc: play",b),this.stream)return this.video.src=URL.createObjectURL(this.stream),this.video.play(),void this.setState("playing");if(this.setState("loading"),this.options.initiator){var c=this;a.log("symple:webrtc: initiating",this.options.userMediaConstraints),navigator.getUserMedia(this.options.userMediaConstraints,function(b){c.video.src=URL.createObjectURL(b),c.pc.addStream(b),c.pc.createOffer(function(b){a.log("symple:webrtc: offer",b),c._onLocalSDP(b)},function(b){a.log("symple:webrtc: offer failed",b)}),c.stream=b},function(a){c.setError("getUserMedia() failed: "+a)})}},stop:function(){this.video&&(this.video.src=""),this.setState("stopped")},mute:function(b){b=b!==!1,a.log("symple:webrtc: mute",b),this.video&&(this.video.muted=b)},recvRemoteSDP:function(b){if(a.log("symple:webrtc: recv remote sdp",b),!b||!b.type||!b.sdp)throw"Invalid remote SDP";var c=this;this.pc.setRemoteDescription(new RTCSessionDescription(b),function(){a.log("symple:webrtc: sdp success")},function(a){console.error("symple:webrtc: sdp error",a),c.setError("Cannot parse remote SDP offer: "+a)}),"offer"===b.type&&c.pc.createAnswer(function(a){c._onLocalSDP(a)},function(a){console.error("symple:webrtc: answer error",a),c.setError("Cannot create local SDP answer: "+a)},c.options.sdpConstraints)},recvRemoteCandidate:function(b){if(a.log("symple:webrtc: recv remote candiate",b),!this.pc)throw"The peer connection is not initialized";this.pc.addIceCandidate(new RTCIceCandidate(b))},_onLocalSDP:function(b){try{this.pc.setLocalDescription(b),this.emit("sdp",b)}catch(c){a.log("symple:webrtc: failed to send local SDP",c)}},_createPeerConnection:function(){if(this.pc)throw"The peer connection is already initialized";a.log("symple:webrtc: create peer connnection",this.rtcConfig);var b=this;this.pc=new RTCPeerConnection(this.rtcConfig),this.pc.onicecandidate=function(c){c.candidate?(a.log("symple:webrtc: candidate gathered",c.candidate),b.emit("candidate",c.candidate)):a.log("symple:webrtc: candidate gathering complete")},this.pc.onaddstream=function(c){a.log("symple:webrtc: remote stream added",URL.createObjectURL(c.stream)),b.setState("playing"),b.video.src=URL.createObjectURL(c.stream),b.video.play(),b.stream=c.stream},this.pc.onremovestream=function(c){a.log("symple:webrtc: remote stream removed",c),b.video.stop(),b.video.src=""}}}),a.iceCandidateType=function(a){return-1!==a.indexOf("typ relay")?"turn":-1!==a.indexOf("typ srflx")?"stun":-1!==a.indexOf("typ host")?"host":"unknown"}}(window.Symple=window.Symple||{});