You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
2 lines
8.0 KiB
2 lines
8.0 KiB
var JSWebrtc={Player:null,VideoElement:null,CreateVideoElements:function(){var elements=document.querySelectorAll(".jswebrtc");for(var i=0;i<elements.length;i++){new JSWebrtc.VideoElement(elements[i])}},FillQuery:function(query_string,obj){obj.user_query={};if(query_string.length==0)return;if(query_string.indexOf("?")>=0)query_string=query_string.split("?")[1];var queries=query_string.split("&");for(var i=0;i<queries.length;i++){var query=queries[i].split("=");obj[query[0]]=query[1];obj.user_query[query[0]]=query[1]}if(obj.domain)obj.vhost=obj.domain},ParseUrl:function(rtmp_url){var a=document.createElement("a");a.href=rtmp_url.replace("rtmp://","http://").replace("webrtc://","http://").replace("rtc://","http://");var vhost=a.hostname;var app=a.pathname.substr(1,a.pathname.lastIndexOf("/")-1);var stream=a.pathname.substr(a.pathname.lastIndexOf("/")+1);app=app.replace("...vhost...","?vhost=");if(app.indexOf("?")>=0){var params=app.substr(app.indexOf("?"));app=app.substr(0,app.indexOf("?"));if(params.indexOf("vhost=")>0){vhost=params.substr(params.indexOf("vhost=")+"vhost=".length);if(vhost.indexOf("&")>0){vhost=vhost.substr(0,vhost.indexOf("&"))}}}if(a.hostname==vhost){var re=/^(\d+)\.(\d+)\.(\d+)\.(\d+)$/;if(re.test(a.hostname))vhost="__defaultVhost__"}var schema="rtmp";if(rtmp_url.indexOf("://")>0)schema=rtmp_url.substr(0,rtmp_url.indexOf("://"));var port=a.port;if(!port){if(schema==="http"){port=80}else if(schema==="https"){port=443}else if(schema==="rtmp"){port=1935}else if(schema==="webrtc"||schema==="rtc"){port=1985}}var ret={url:rtmp_url,schema:schema,server:a.hostname,port:port,vhost:vhost,app:app,stream:stream};JSWebrtc.FillQuery(a.search,ret);return ret},HttpPost:function(url,data){return new Promise(function(resolve,reject){var xhr=new XMLHttpRequest;xhr.onreadystatechange=function(){if(xhr.readyState===4&&(xhr.status>=200&&xhr.status<300)){var respone=JSON.parse(xhr.responseText);xhr.onreadystatechange=new Function;xhr=null;resolve(respone)}};xhr.open("POST",url,true);xhr.timeout=5e3;xhr.responseType="text";xhr.setRequestHeader("Content-Type","application/json");xhr.send(data)})}};if(document.readyState==="complete"){JSWebrtc.CreateVideoElements()}else{document.addEventListener("DOMContentLoaded",JSWebrtc.CreateVideoElements)}JSWebrtc.VideoElement=function(){"use strict";var VideoElement=function(element){var url=element.dataset.url;if(!url){throw"VideoElement has no `data-url` attribute"}var addStyles=function(element,styles){for(var name in styles){element.style[name]=styles[name]}};this.container=element;addStyles(this.container,{display:"inline-block",position:"relative",minWidth:"80px",minHeight:"80px"});this.video=document.createElement("video");this.video.width=960;this.video.height=540;addStyles(this.video,{display:"block",width:"100%"});this.container.appendChild(this.video);this.playButton=document.createElement("div");this.playButton.innerHTML=VideoElement.PLAY_BUTTON;addStyles(this.playButton,{zIndex:2,position:"absolute",top:"0",bottom:"0",left:"0",right:"0",maxWidth:"75px",maxHeight:"75px",margin:"auto",opacity:"0.7",cursor:"pointer"});this.container.appendChild(this.playButton);var options={video:this.video};for(var option in element.dataset){try{options[option]=JSON.parse(element.dataset[option])}catch(err){options[option]=element.dataset[option]}}this.player=new JSWebrtc.Player(url,options);element.playerInstance=this.player;if(options.poster&&!options.autoplay){options.decodeFirstFrame=false;this.poster=new Image;this.poster.src=options.poster;this.poster.addEventListener("load",this.posterLoaded);addStyles(this.poster,{display:"block",zIndex:1,position:"absolute",top:0,left:0,bottom:0,right:0});this.container.appendChild(this.poster)}if(!this.player.options.streaming){this.container.addEventListener("click",this.onClick.bind(this))}if(options.autoplay){this.playButton.style.display="none"}if(this.player.audioOut&&!this.player.audioOut.unlocked){var unlockAudioElement=this.container;if(options.autoplay){this.unmuteButton=document.createElement("div");this.unmuteButton.innerHTML=VideoElement.UNMUTE_BUTTON;addStyles(this.unmuteButton,{zIndex:2,position:"absolute",bottom:"10px",right:"20px",width:"75px",height:"75px",margin:"auto",opacity:"0.7",cursor:"pointer"});this.container.appendChild(this.unmuteButton);unlockAudioElement=this.unmuteButton}this.unlockAudioBound=this.onUnlockAudio.bind(this,unlockAudioElement);unlockAudioElement.addEventListener("touchstart",this.unlockAudioBound,false);unlockAudioElement.addEventListener("click",this.unlockAudioBound,true)}};VideoElement.prototype.onUnlockAudio=function(element,ev){if(this.unmuteButton){ev.preventDefault();ev.stopPropagation()}this.player.audioOut.unlock(function(){if(this.unmuteButton){this.unmuteButton.style.display="none"}element.removeEventListener("touchstart",this.unlockAudioBound);element.removeEventListener("click",this.unlockAudioBound)}.bind(this))};VideoElement.prototype.onClick=function(ev){if(this.player.isPlaying){this.player.pause();this.playButton.style.display="block"}else{this.player.play();this.playButton.style.display="none";if(this.poster){this.poster.style.display="none"}}};VideoElement.PLAY_BUTTON='<svg style="max-width: 75px; max-height: 75px;" '+'viewBox="0 0 200 200" alt="Play video">'+'<circle cx="100" cy="100" r="90" fill="none" '+'stroke-width="15" stroke="#fff"/>'+'<polygon points="70, 55 70, 145 145, 100" fill="#fff"/>'+"</svg>";VideoElement.UNMUTE_BUTTON='<svg style="max-width: 75px; max-height: 75px;" viewBox="0 0 75 75">'+'<polygon class="audio-speaker" stroke="none" fill="#fff" '+'points="39,13 22,28 6,28 6,47 21,47 39,62 39,13"/>'+'<g stroke="#fff" stroke-width="5">'+'<path d="M 49,50 69,26"/>'+'<path d="M 69,50 49,26"/>'+"</g>"+"</svg>";return VideoElement}();JSWebrtc.Player=function(){"use strict";var Player=function(url,options){this.options=options||{};if(!url.match(/^webrtc?:\/\//)){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;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;var api=_self.urlParams.user_query.play||"/rtc/v1/play/";if(api.lastIndexOf("/")!=api.length-1){api+="/"}var url="http://"+_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]}}var data={api:url,streamurl:_self.urlParams.url,clientip:null,sdp:offer.sdp};JSWebrtc.HttpPost(url,JSON.stringify(data)).then(function(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}();
|