1 line
No EOL
9.7 KiB
JavaScript
1 line
No EOL
9.7 KiB
JavaScript
mistplayers.rawws={name:"RAW to Canvas",mimes:["ws/video/raw"],priority:MistUtil.object.keys(mistplayers).length+1,isMimeSupported:function(e){return MistUtil.array.indexOf(this.mimes,e)==-1?false:true},isBrowserSupported:function(e,t,r){if(location.protocol!=MistUtil.http.url.split(t.url.replace(/^ws/,"http")).protocol){if(location.protocol=="file:"&&MistUtil.http.url.split(t.url.replace(/^ws/,"http")).protocol=="http:"){r.log("This page was loaded over file://, the player might not behave as intended.")}else{r.log("HTTP/HTTPS mismatch for this source");return false}}for(var i in r.info.meta.tracks){if(r.info.meta.tracks[i].codec=="HEVC"){return true}}return false},player:function(){this.onreadylist=[]},scriptsrc:function(e){return e+"/libde265.js"}};var p=mistplayers.rawws.player;p.prototype=new MistPlayer;p.prototype.build=function(e,t){var r=this;r.onDecoderLoad=function(){if(e.destroyed){return}e.log("Building rawws player..");var i={};e.player.api=i;var a=document.createElement("canvas");var s=a.getContext("2d");a.style.objectFit="contain";r.vars={};if(e.options.autoplay){r.vars.wantToPlay=true}r.dropping=false;r.frames={received:0,bitsReceived:0,decoded:0,dropped:0,behind:function(){return this.received-this.decoded-this.dropped},timestamps:{},frame2time:function(e,t){if(e in this.timestamps){if(t){for(var r in this.timestamps){if(r==e){break}delete this.timestamps[r]}}return this.timestamps[e]*.001}return 0;var i=0;var a=0;for(var r in this.timestamps){i=r;a=this.timestamps[r];if(r>=e){break}}if(t){for(var r in this.timestamps){if(r==i){break}delete this.timestamps[r]}}var s=this.framerate();if(typeof s!="undefined"&&s>0){return a+(e-i)/s}else{return a}},history:{log:[],add:function(){this.log.unshift({time:(new Date).getTime(),received:r.frames.received,bitsReceived:r.frames.bitsReceived,decoded:r.frames.decoded});if(this.log.length>3){this.log.splice(3)}}},framerate_in:function(){var e=this.history.log.length-1;if(e<1){return 0}var t=this.history.log[0].received-this.history.log[e].received;var r=(this.history.log[0].time-this.history.log[e].time)*.001;return t/r},bitrate_in:function(){var e=this.history.log.length-1;if(e<1){return 0}var t=this.history.log[0].bitsReceived-this.history.log[e].bitsReceived;var r=(this.history.log[0].time-this.history.log[e].time)*.001;return t/r},framerate_out:function(){var e=this.history.log.length-1;if(e<1){return 0}var t=this.history.log[0].decoded-this.history.log[e].decoded;var r=(this.history.log[0].time-this.history.log[e].time)*.001;return t/r},framerate:function(){if("rate_theoretical"in this){return this.rate_theoretical}return this.framerate_in()},keepingUp:function(){var e=this.history.log.length-1;if(e<1){return 0}var t=this.history.log[e].received-this.history.log[e].decoded-(this.history.log[0].received-this.history.log[0].decoded);var r=(this.history.log[0].time-this.history.log[e].time)*.001;var i=t/r;return i/this.framerate()}};i.framerate_in=function(){return r.frames.framerate_in()};i.framerate_out=function(){return r.frames.framerate_out()};i.currentBps=function(){return r.frames.bitrate_in()};i.loop=e.options.loop;Object.defineProperty(e.player.api,"webkitDecodedFrameCount",{get:function(){return r.frames.decoded}});Object.defineProperty(e.player.api,"webkitDroppedFrameCount",{get:function(){return r.frames.dropped}});var n;this.decoder=null;function o(e){MistUtil.event.send(e,undefined,a)}function d(){function i(){n=new libde265.Decoder;e.player.decoder=n;var t=[];n.addListener=function(e){t.push(e)};n.removeListener=function(e){var r=t.indexOf(e);if(r<0){return}t.splice(r,1);return true};var i;if(window.requestAnimationFrame){i=function(e){n.pending_image_data=e;window.requestAnimationFrame(function(){if(n.pending_image_data){s.putImageData(n.pending_image_data,0,0);n.pending_image_data=null}})}}else{i=function(e){s.putImageData(e,0,0)}}n.set_image_callback(function(d){r.frames.decoded++;if(r.vars.wantToPlay&&r.state!="seeking"){o("timeupdate")}if(!n.image_data){var f=d.get_width();var p=d.get_height();if(f!=a.width||p!=a.height||!this.image_data){a.width=f;a.height=p;var l=s.createImageData(f,p);n.image_data=l}}if(r.state!="seeking"){d.display(this.image_data,function(e){n.decoding=false;i(e)})}d.free();switch(r.state){case"play":case"waiting":{if(!r.dropping){o("canplay");o("playing");r.state="playing";if(!r.vars.wantToPlay){e.player.send({type:"hold"})}}break}case"seeking":{var c=r.frames.frame2time(r.frames.decoded+r.frames.dropped);if(c>=r.vars.seekTo){o("seeked");r.vars.seekTo=null;r.state="playing";if(!r.vars.wantToPlay){o("timeupdate");e.player.send({type:"hold"})}}break}default:{r.state="playing"}}for(var u in t){t[u]()}})}i();function d(e){return!!e[1]}function f(e){var t=new DataView(new ArrayBuffer(8));for(var r=0;r<8;r++){t.setUint8(r,e[r+2])}return t.getInt32(4)}function p(){o("loadstart");var i=MistUtil.http.url.addParam(e.source.url,{buffer:0,video:"hevc,|minbps"});var s=new WebSocket(i);e.player.ws=s;s.binaryType="arraybuffer";function l(t){if(!e.player.ws){throw"No websocket to send to"}if(s.readyState==1){s.send(JSON.stringify(t))}return false}e.player.send=l;s.wasConnected=false;s.onopen=function(){if(!e.player.built){e.player.built=true;t(a)}l({type:"request_codec_data",supported_codecs:["HEVC"]});s.wasConnected=true};s.onclose=function(){if(this.wasConnected&&!e.destroyed&&e.state=="Stream is online"){e.log("Raw over WS: reopening websocket");p(i)}else{e.showError("Raw over WS: websocket closed")}};s.onerror=function(t){e.showError("Raw over WS: websocket error")};s.onmessage=function(t){if(typeof t.data=="string"){var i=JSON.parse(t.data);switch(i.type){case"on_time":{r.vars.paused=false;r.frames.history.add();if(r.vars.duration!=i.data.end*.001){r.vars.duration=i.data.end*.001;o("durationchange")}break}case"seek":{e.player.frames.timestamps={};if(e.player.dropping){e.log("Emptying drop queue for seek");e.player.frames.dropped+=e.player.dropping.length;e.player.dropping=[]}break}case"codec_data":{o("loadedmetadata");l({type:"play"});r.state="play";break}case"info":{var a=e.info.meta.tracks;var p;for(var c in a){if(a[c].idx==i.data.tracks[0]){p=a[c];break}}if(typeof p!=undefined&&p.fpks>0){r.frames.rate_theoretical=p.fpks*.001}break}case"pause":{r.vars.paused=i.paused;if(i.paused){r.decoder.flush();o("pause")}break}case"on_stop":{if(r.state=="ended"){return}r.state="ended";r.vars.paused=true;s.onclose=function(){};s.close();r.decoder.flush();o("ended");break}default:{}}}else{r.frames.received++;r.frames.bitsReceived+=t.data.byteLength*8;var u=12;var h=new Uint8Array(t.data.slice(0,u));var m=new Uint8Array(t.data.slice(u,t.data.byteLength));r.frames.timestamps[r.frames.received]=f(h);function y(t,i){setTimeout(function(){if(r.dropping){if(r.state!="waiting"){o("waiting");r.state="waiting"}if(d(i)){if(r.dropping.length){r.frames.dropped+=r.dropping.length;e.log("Dropped "+r.dropping.length+" frames");r.dropping=[]}else{e.log("Caught up! no longer dropping");r.dropping=false}}else{r.dropping.push([i,t]);if(!n.decoding){var a=r.dropping.shift();e.player.process(a[1],a[0])}return}}else{if(r.frames.behind()>20){r.dropping=[];e.log("Falling behind, dropping files..")}}e.player.process(t,i)},0)}y(m,h)}};s.listeners={};s.addListener=function(e,t){if(!(e in this.listeners)){this.listeners[e]=[]}this.listeners[e].push(t)};s.removeListener=function(e,t){if(!(e in this.listeners)){return}var r=this.listeners[e].indexOf(t);if(r<0){return}this.listeners[e].splice(r,1);return true}}e.player.connect=p;e.player.process=function(e,t){n.decoding=true;var i=n.push_data(e);if(r.state=="play"){o("loadeddata");r.state="waiting"}if(r.vars.wantToPlay&&r.state!="seeking"){o("progress")}function s(e){if(e==0){return}if(e==libde265.DE265_ERROR_WAITING_FOR_INPUT_DATA){r.state="waiting";return}if(!libde265.de265_isOK(e)){a.error="Decode error: "+libde265.de265_get_error_text(e);o("error");return true}}if(!s(i)){n.decode(s)}else{n.free()}};p()}d();function f(t){Object.defineProperty(e.player.api,t,{get:function(){return r.vars[t]},set:function(e){return r.vars[t]=e}})}var p=["duration","paused","error"];for(var l in p){f(p[l])}i.play=function(){return new Promise(function(t,a){r.vars.wantToPlay=true;var s=function(){t();e.player.decoder.removeListener(s)};e.player.decoder.addListener(s);if(e.player.ws.readyState>e.player.ws.OPEN){e.player.connect();e.log("Websocket was closed: reconnecting to resume playback");return}if(i.paused)e.player.send({type:"play"});r.state="play"})};i.pause=function(){r.vars.wantToPlay=false;e.player.send({type:"hold"})};e.player.api.unload=function(){if(e.player.ws){e.player.ws.onclose=function(){};e.player.ws.close()}if(e.player.decoder){e.player.decoder.push_data=function(){};e.player.decoder.flush();e.player.decoder.free()}};e.player.setSize=function(e){a.style.width=e.width+"px";a.style.height=e.height+"px"};Object.defineProperty(e.player.api,"currentTime",{get:function(){var e=r.frames.decoded+r.frames.dropped;if(r.state=="seeking"){return r.vars.seekTo}if(e in r.frames.timestamps){return r.frames.frame2time(e)}return 0},set:function(t){o("seeking");r.state="seeking";r.vars.seekTo=t;e.player.send({type:"seek",seek_time:t*1e3});return t}});Object.defineProperty(e.player.api,"buffered",{get:function(){return{start:function(e){if(this.length&&e==0){return r.frames.frame2time(r.frames.decoded+r.frames.dropped)}},end:function(e){if(this.length&&e==0){return r.frames.frame2time(r.frames.received)}},length:r.frames.received-r.frames.decoded>0?1:0}}});if(e.info.type!="live"){MistUtil.event.addListener(a,"ended",function(){if(r.api.loop){r.api.play();r.api.currentTime=0}})}};if("libde265"in window){this.onDecoderLoad()}else{var i=MistUtil.scripts.insert(e.urlappend(mistplayers.rawws.scriptsrc(e.options.host)),{onerror:function(t){var r="Failed to load H265 decoder";if(t.message){r+=": "+t.message}e.showError(r)},onload:e.player.onDecoderLoad},e)}}; |