var isFinish = false; var isSwitchSharpness = false; var h264Queue = []; var ret; var maxWidth = 1080; var maxHeight = 1920; var globalYuvPtr = undefined; var golbalYuvData;//全局,只分配一次 var renderCount = 0; var curFrameWidth = undefined; var curFrameHeight = undefined; function doSomeInit() { var allocSize = maxWidth * maxHeight * 3; golbalYuvData = new Uint8Array(allocSize); } self.importScripts("ffmpeghelper.js"); self.importScripts("spsParser.js"); self.Module.onRuntimeInitialized = function () { isFinish = true; doSomeInit(); ret = Module._openDecoder(); if (!ret) { console.log("打开编码器成功"); } } self.addEventListener('message', function (e) { var msg = e.data; if (msg.type == "rawData") { var buffer = e.data.data; if (buffer[0] !== 0xff) { // 音频解码 var type = buffer[4] & 0x1f; if (type == 7) { let info = spsParser(buffer); if (curFrameWidth != undefined && curFrameHeight != undefined) { if (info.width != curFrameWidth || info.height != curFrameHeight) { // 分辨率发生改变,切换 switchNewStream(); } } curFrameWidth = info.width; curFrameHeight = info.height; h264Queue.push(buffer); } else { h264Queue.push(buffer); } } } }, false); function PrintfLog(str) { var curTime = new Date().getTime(); var objData = { cmd: 0, data: str, time: curTime }; self.postMessage(objData); } function doRequestIFrame() { var objData = { cmd: 5, }; self.postMessage(objData); } function decodeVideo() { if (h264Queue.length > 0 && isFinish) { decodeH264(h264Queue.shift()); } } var timeFlag = setInterval(decodeVideo, 1); //实现C 端到js yuv数据赋值, 并分配给opengl 渲染 /*yuvData, 存放yuv数据的数组 * inputYuvPtr C++ */ function dispatchYuvData(yuvData, inputYuvPtr, videoWidth, videoHeight, copyLen) { for (i = 0; i < copyLen; i++) { yuvData[i] = Module.HEAPU8[(inputYuvPtr) + i]; } var curTime = new Date().getTime(); var objData = { cmd: 1, data: yuvData, time: curTime, width: videoWidth, height: videoHeight }; self.postMessage(objData); } function decodeH264(data) { var frameWidth = 0; var frameHeight = 0; var inputPtr = Module._malloc(data.length); //输入数据 for (var i = 0; i < data.length; i++) { Module.HEAPU8[(inputPtr) + i] = data[i]; //转换为堆数据 } var allocSize = maxWidth * maxHeight * 3 / 2; if (globalYuvPtr == undefined) { globalYuvPtr = Module._malloc(allocSize); } var ret = Module._feedData(inputPtr, data.length, globalYuvPtr); if (ret >= 0) { //解码成功才考虑渲染 frameWidth = Module._getVideoWidth();//拿到解码器宽、高 frameHeight = Module._getVideoHeight(); var copyLen = frameWidth * frameHeight * 3 / 2;//只拷贝必须的长度 if (renderCount > 1) { //第一帧因为画面时全绿色的不渲染 dispatchYuvData(golbalYuvData, globalYuvPtr, frameWidth, frameHeight, copyLen); } else { renderCount++; } } Module._free(inputPtr); } function switchNewStream() { closeDecoder(); var ret = Module._openDecoder();//再次开启解码器 var timeFlag = setInterval(decodeVideo, 1); console.log("切换解码器成功"); } function closeDecoder() { clearInterval(timeFlag);//关闭原有定时器 Module._closeDecoder(); renderCount = 0; if (globalYuvPtr != undefined) { Module._free(globalYuvPtr); globalYuvPtr = undefined; } console.log("此时buffer长度: %d", h264Queue.length); while (h264Queue.lengh > 0) { h264Queue.shift(); } }