var isFinish = false; var isSwitchSharpness = false; var h264Queue = []; var ret; var maxWidth = 1080; var maxHeight = 1920; var globalYuvPtr = undefined; var golbalYuvData;//全局,只分配一次 var renderCount = 0; function doSomeInit() { var allocSize = maxWidth * maxHeight * 3; golbalYuvData = new Uint8Array(allocSize); } self.Module = { onRuntimeInitialized: function () { isFinish = true; doSomeInit(); ret = Module._openDecoder(); if (!ret) { console.log("打开编码器成功"); } } }; self.importScripts("ffmpeghelper.js"); self.addEventListener('message', function (e) { var msg = e.data; if (msg.type == "rawData") { var buffer = e.data.data; if (buffer[0] !== 0xff) { // 音频解码 if (isSwitchSharpness) { var type = buffer[4] & 0x1f; if (type == 7 || type == 8) { console.log("视频类型:" + type); isSwitchSharpness = false; h264Queue.push(buffer); } } else { h264Queue.push(buffer); } } } if (msg.type == "switchSharpness") { // 分辨率切换实现 isSwitchSharpness = true; closeDecoder(); var ret = Module._openDecoder();//再次开启解码器 var timeFlag = setInterval(decodeVideo, 1); console.log("切换解码器成功"); } }, 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 (i = 0; i < data.length; i++) { Module.HEAPU8[(inputPtr) + i] = data[i]; //转换为堆数据 } var time = new Date().getTime(); 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 curCost = new Date().getTime() - time; var copyLen = frameWidth * frameHeight * 3 / 2;//只拷贝必须的长度 if (renderCount > 1)//第一帧因为画面时全绿色的不渲染 { dispatchYuvData(golbalYuvData, globalYuvPtr, frameWidth, frameHeight, copyLen); } else { renderCount++; } } Module._free(inputPtr); } 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(); } }