123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176 |
- 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) {
- // 分辨率发生改变,切换
- console.log('🚀 ~ file: decoder.js ~ line 44 ~ 分辨率发生改变');
- 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();
- // console.log("🚀 ~ file: decoder.js ~ line 134 ~ decodeH264 ~ frameWidth", frameWidth,frameHeight)
- 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();
- }
- }
|