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.
 
 
 
 
 
 

453 lines
14 KiB

self.Module = {
onRuntimeInitialized: function () {
}
};
self.importScripts("common.js");
// var USE_MISSILE = false;
// var decoder_type;
// var DECODER_TYPE = kDecoder_decodeer_js;
// var DECODER_TYPE = kDecoder_wx_h265_wasm_combine_js;
var webglPlayer, canvas, videoWidth, videoHeight, yLength, uvLength;
var LOG_LEVEL_JS = 0;
var LOG_LEVEL_WASM = 1;
var LOG_LEVEL_FFMPEG = 2;
var DECODER_H264 = 0;
var DECODER_H265 = 1;
function Player(){
this.decoder_type = DECODER_TYPE;//DECODER_H265;
this.decoding = false;
this.webrtcplayerState = playerStateIdle;
this.decodeInterval = 5; //编码定时器
this.urgent = false;
this.destroied = false;
this.decoderworker=null;
this.frameBuffer = [];
// this.Module = {};
}
Player.prototype.setDecoder=function(type) {
this.decoder_type = type;
}
Player.prototype.startDecoder=function(decoder_type){
var self = this;
self.setDecoder(decoder_type);
switch(decoder_type){
case kDecoder_simd_decoder_js:
self.decoderworker=new Worker("decoder_simd.js");
var req = {
t: kInitDecoderReq,
};
self.decoderworker.postMessage(req);
self.decoderworker.onmessage=function (evt) {
var objData = evt.data;
switch (objData.t) {
case kInitDecoderRsp:
self.onInitDecoder(objData);
break;
case kOpenDecoderRsp:
self.onOpenDecoder(objData);
break;
case kVideoFrame:
self.onVideoFrame(objData.d);
break;
default:
console.log("Unsupport messsage " + req.t);
}
}
break;
case kDecoder_decodeer_js:
self.decoderworker=new Worker("decoder.js");
var req = {
t: kInitDecoderReq,
};
self.decoderworker.postMessage(req);
self.decoderworker.onmessage=function (evt) {
var objData = evt.data;
switch (objData.t) {
case kInitDecoderRsp:
self.onInitDecoder(objData);
break;
case kOpenDecoderRsp:
self.onOpenDecoder(objData);
break;
case kVideoFrame:
self.onVideoFrame(objData.d);
break;
default:
console.log("Unsupport messsage " + req.t);
}
}
break;
// this.decoderworker=new Worker("decoder_missle.js");
case kDecoder_wx_h265_wasm_combine_js:
// this.decoderworker=new Worker("prod_decoder.js");
self.Module = {};
self.decoderworker=new Worker("decoder_wx.js");
// self.SetWxDecoder(self.decoderworker,self);
var req = {
t: kInitDecoderReq,
};
self.decoderworker.postMessage(req);
self.decoderworker.onmessage=function (evt) {
var objData = evt.data;
switch (objData.t) {
case kInitDecoderRsp:
self.onInitDecoder(objData);
break;
case kOpenDecoderRsp:
self.onOpenDecoder(objData);
break;
case kVideoFrame:
self.onVideoFrame(objData);
break;
default:
console.log("Unsupport messsage " + req.t);
}
}
break;
case kDecoder_missile_decoder_js:
self.decoderworker=new Worker("decoder_missle.js");//prod.h265.wasm.combine.js");
var req = {
t: kInitDecoderReq,
};
self.decoderworker.postMessage(req);
console.log("InitMissleDecoder");
self.decoderworker.onmessage=function (evt) {
var objData = evt.data;
switch (objData.t) {
case kInitDecoderRsp:
self.onInitDecoder(objData);
break;
case kOpenDecoderRsp:
self.onOpenDecoder(objData);
// self.displayLoop();
// var req = {
// t: kInitPlayerReq,
// };
// self.postMessage(req);
break;
case kVideoFrame_Missle:
self.onVideoFrame_Missle(objData);
break;
default:
console.log("Unsupport messsage " + req.t);
}
}
// this.InitMissleDecoder();
break;
default:
console.error("not supported");
}
};
Player.prototype.ReqInitDecoder = function(){
var req = {
t: kInitDecoderReq,
};
this.decoderworker.postMessage(req);
}
Player.prototype.InitMissleDecoder =function(){
var req = {
t: kInitDecoderReq,
};
this.decoderworker.postMessage(req);
console.log("InitMissleDecoder");
this.decoderworker.onmessage=function (evt) {
var objData = evt.data;
switch (objData.t) {
case kInitDecoderRsp:
self.onInitDecoder(objData);
break;
case kOpenDecoderRsp:
self.onOpenDecoder(objData);
// self.displayLoop();
// var req = {
// t: kInitPlayerReq,
// };
// this.postMessage(req);
break;
case kVideoFrame_Missle:
self.onVideoFrame_Missle(objData);
break;
default:
console.log("Unsupport messsage " + req.t);
}
}
}
// Player.prototype.SetDecoder = function (worker,self){
// var req = {
// t: kInitDecoderReq,
// };
// worker.postMessage(req);
// worker.onmessage=function (evt) {
// var objData = evt.data;
// switch (objData.t) {
// case kInitDecoderRsp:
// self.onInitDecoder(objData);
// break;
// case kOpenDecoderRsp:
// self.onOpenDecoder(objData);
// break;
// case kVideoFrame:
// self.onVideoFrame(objData);
// break;
// // case kVideoFrame_Missle:
// // self.onVideoFrame_Missle(objData);
// // break;
// case kprodVideoFrame:
// self.onVideoFrame_Prod(objData);
// break;
// case "decode":
// console.log("decode"+objData)
// break;
// default:
// console.log("Unsupport messsage " + req.t);
// }
// }
// }
Player.prototype.SetWxDecoder = function (worker,self){
worker.onmessage = function(msg){ // 收到胶水代码返回来的消息的处理方式
var data = msg.data;
var decodet1=new Date().getTime();
console.log(decodet1,"->worker.onmessage",data.type,data.data)
if(typeof self.onmessage == "function"){
self.onmessage(data); // 收到解码器的事件,如果设置了onmessage函数,透传到上层,processor通过这种方式拿到解码器事件
//data.type
if(data.type == 'destroy' && typeof self.onterminate == 'function'){
self.onterminate();
worker.terminate();
worker = null;
}
}
}
worker.onterminate = function(){
}
this.onmessage = function(data){
console.log("player onmessage",data.type);
};
this.onterminate = function(){
console.log("playe onterminate");
};
};
Player.prototype.decode = function(buffer){ // 对外api,解码一段数据
if(this.decoderworker){
this.decoderworker.postMessage({
type: 'decode',
buffer: buffer,
});
}
}
Player.prototype.destroy = function(){ // 对外api,销毁解码器
this.destroied = true;
if(this.decoderworker){
// window.URL.revokeObjectURL(this.url);
this.decoderworker.postMessage({type: 'destroy'});
}
}
Player.prototype.startDecoding = function () {
var req = {
t: kStartDecodingReq,
i: this.urgent ? 0 : this.decodeInterval,
};
this.decoderworker.postMessage(req);
this.decoding = true;
this.webrtcplayerState = playerStatePlaying;
this.displayLoop();
};
Player.prototype.pauseDecoding = function () {
var req = {
t: kPauseDecodingReq
};
this.decoderworker.postMessage(req);
this.decoding = false;
};
Player.prototype.onOpenDecoder=function(objData){
console.log("reqOpenDecoder response " + objData.e + ".");
if(objData.e==0){
this.startDecoding();
}
}
Player.prototype.onInitDecoder = function (objData) {
console.log("Init decoder response " + objData.e + ".");
this.reqOpenDecoder();
};
Player.prototype.reqOpenDecoder=function(){
var req = {
t: kOpenDecoderReq
};
this.decoderworker.postMessage(req);
}
Player.prototype.onFrameData = function (data, len,type) {
// console.log("Got data bytes=" + start + "-" + end + ".");
if(this.decoder_type===kDecoder_wx_h265_wasm_combine_js){
this.decode(data);
}else{
var objData = {
t: kFeedDataReq,
type:type,
d: data
};
this.decoderworker.postMessage(objData, [objData.d.packet.buffer]); //见h265dc.js
}
}
// Player.prototype.onFrameData = function (data, len) {
// // console.log("Got data bytes=" + start + "-" + end + ".");
// if(this.decoder_type===kDecoder_wx_h265_wasm_combine_js){
// this.decode(data);
// }else{
// var objData = {
// t: kFeedDataReq,
// d: data
// };
// this.decoderworker.postMessage(objData, [objData.d.packet]); //见h265.js
// }
// }
Player.prototype.startBuffering = function () {
this.buffering = true;
this.showLoading();
this.pause();
}
Player.prototype.stopBuffering = function () {
this.buffering = false;
this.hideLoading();
this.resume();
}
Player.prototype.displayVideoFrame = function (frame) {
var audioTimestamp=0;
var delay=0
console.log("displayVideoFrame" );//delay=" + delay + "=" + " " + frame.s + " - (" + audioCurTs + " + " + this.beginTimeOffset + ")" + "->" + audioTimestamp);
if (audioTimestamp <= 0 || delay <= 0) {
this.renderVideoFrame(frame);
return true;
}
return false;
};
Player.prototype.displayLoop = function() {
// console.log("displayLoop")
if (this.webrtcplayerState !== playerStateIdle) {
requestAnimationFrame(this.displayLoop.bind(this));
}
if(this.frameBuffer.length>0){
console.log("displayLoop ready to display: ",this.frameBuffer.length)
var frame = this.frameBuffer[0];
if (this.displayVideoFrame(frame)) {
this.frameBuffer.shift();
}
}
};
Player.prototype.stopDecoder = function() {
var req={
t: kPauseDecodingReq,
}
this.decoderworker.postMessage(req);
var req={
t: kUninitDecoderReq,
}
this.decoderworker.postMessage(req);
// this.stopBuffering();
this.webrtcplayerState=playerStateIdle;
};
Player.prototype.renderVideoFrame = function (data) {
// var self = this;
var playFrame={
t: kplayeVideoFrame,
d: data
}
self.postMessage(playFrame,[playFrame.d.data.buffer])
};
Player.prototype.onNetStatus = function (status){
var playStatus={
t: kplaterNetStatus,
s: status
}
self.postMessage(playStatus)
}
Player.prototype.getBufferTimerLength = function() {
if (!this.frameBuffer || this.frameBuffer.length == 0) {
return 0;
}
let oldest = this.frameBuffer[0];
let newest = this.frameBuffer[this.frameBuffer.length - 1];
return newest.s - oldest.s;
};
Player.prototype.bufferFrame = function (frame) {
// If not decoding, it may be frame before seeking, should be discarded.
this.frameBuffer.push(frame);
console.log("bufferFrame pts:" + frame.s+" w:" + frame.width + ", h: " + frame.height);
}
Player.prototype.onVideoFrame = function (frame) {
this.bufferFrame(frame);
};
Player.prototype.onVideoFrame_Prod = function (frame) {
this.bufferFrame(frame);
};
Player.prototype.onVideoFrame_Missle = function (frame) {
this.bufferFrame(frame);
};
Player.prototype.processReq = function (req) {
// console.log("processReq " + req.t + ".");
switch (req.t) {
case kstartPlayerCoderReq:
this.startDecoder(req.decoder_type);
break;
case kendPlayerCoderReq:
this.stopDecoder();
break;
case kInitPlayerReq:
this.displayLoop();
break;
case ksendPlayerVideoFrameReq:
this.onFrameData(req.d,req.l,"VIDEO");
break;
case ksendPlayerAudioFrameReq:
this.onFrameData(req.d,req.l,"AUDIO");
break;
case kconnectStatusResponse:
this.onNetStatus(req.s);
break;
default:
console.log("Unsupport messsage " + req.t);
}
};
self.player = new Player;
self.onmessage = function (evt) {
if (!self.player) {
console.log("[ER] Player not initialized!");
return;
}
var req = evt.data;
self.player.processReq(req);
};