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.
191 lines
4.8 KiB
191 lines
4.8 KiB
2 years ago
|
self.Module = {
|
||
|
onRuntimeInitialized: function () {
|
||
|
|
||
|
}
|
||
|
};
|
||
|
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;
|
||
|
self.importScripts("common.js");
|
||
|
function Player(){
|
||
|
this.decoder_type = DECODER_H265;
|
||
|
this.decoding = false;
|
||
|
this.webrtcplayerState = playerStateIdle;
|
||
|
this.decodeInterval = 5;
|
||
|
this.urgent = false;
|
||
|
|
||
|
this.frameBuffer = [];
|
||
|
}
|
||
|
Player.prototype.setDecoder=function(type) {
|
||
|
this.decoder_type = type;
|
||
|
}
|
||
|
Player.prototype.startDecoder=function(){
|
||
|
var self = this;
|
||
|
this.decoderworker=new Worker("decoder.js");
|
||
|
// this.decoderworker.initDecoder();
|
||
|
var req = {
|
||
|
t: kInitDecoderReq,
|
||
|
};
|
||
|
this.decoderworker.postMessage(req);
|
||
|
this.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;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
};
|
||
|
Player.prototype.startDecoding = function () {
|
||
|
var req = {
|
||
|
t: kStartDecodingReq,
|
||
|
i: this.urgent ? 0 : this.decodeInterval,
|
||
|
};
|
||
|
this.decoderworker.postMessage(req);
|
||
|
this.decoding = true;
|
||
|
this.webrtcplayerState = playerStatePlaying;
|
||
|
|
||
|
};
|
||
|
|
||
|
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) {
|
||
|
// console.log("Got data bytes=" + start + "-" + end + ".");
|
||
|
|
||
|
var objData = {
|
||
|
t: kFeedDataReq,
|
||
|
d: data
|
||
|
};
|
||
|
this.decoderworker.postMessage(objData, [objData.d]);
|
||
|
}
|
||
|
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.d);
|
||
|
return true;
|
||
|
}
|
||
|
return false;
|
||
|
};
|
||
|
|
||
|
Player.prototype.displayLoop = function() {
|
||
|
if (this.webrtcplayerState !== playerStateIdle) {
|
||
|
requestAnimationFrame(this.displayLoop.bind(this));
|
||
|
}
|
||
|
if(this.frameBuffer.length>0){
|
||
|
var frame = this.frameBuffer[0];
|
||
|
if (this.displayVideoFrame(frame)) {
|
||
|
this.frameBuffer.shift();
|
||
|
}
|
||
|
}
|
||
|
};
|
||
|
|
||
|
Player.prototype.renderVideoFrame = function (data) {
|
||
|
// var self = this;
|
||
|
var playFrame={
|
||
|
t: kplayeVideoFrame,
|
||
|
d: data
|
||
|
}
|
||
|
self.postMessage(playFrame,[playFrame.d.data.buffer])
|
||
|
|
||
|
};
|
||
|
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.d.width + ", h: " + frame.d.height);
|
||
|
|
||
|
}
|
||
|
Player.prototype.onVideoFrame = function (frame) {
|
||
|
this.bufferFrame(frame);
|
||
|
};
|
||
|
|
||
|
Player.prototype.processReq = function (req) {
|
||
|
// console.log("processReq " + req.t + ".");
|
||
|
switch (req.t) {
|
||
|
case kstartPlayerCoderReq:
|
||
|
this.startDecoder();
|
||
|
break;
|
||
|
case kInitPlayerReq:
|
||
|
this.displayLoop();
|
||
|
break;
|
||
|
case ksendPlayerVideoFrameReq:
|
||
|
this.onFrameData(req.d,req.l);
|
||
|
break;
|
||
|
default:
|
||
|
this.logger.logError("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);
|
||
|
};
|