瀏覽代碼

切换分辨率

huangxiaojing 3 年之前
父節點
當前提交
faef0c1ca1

+ 20 - 10
screenAndroid/WXdraw.js

@@ -24,7 +24,6 @@ var form = {};
 
 var cardToken = parameters["cardToken"];
 cardToken = cardToken && cardToken.replace(/@/g, "=");
-cardToken = cardToken.replace(/\$/g, "+");
 form.cardIp = parameters["cardIp"];
 form.port = parameters["port"];
 form.username = parameters["username"];
@@ -33,8 +32,8 @@ form.ip = parameters["ip"];
 form.domainName = parameters["domainName"];
 var isWSS = true;
 var cUrl = isWSS ? "wss://" + form.domainName + "?cardIp=" + form.ip + "&token=" + cardToken : "ws://" + form.domainName + "?cardIp=" + form.ip + "&token=" + cardToken;
-var videoWidth = parameters['mealType'] === "STARPRO" || parameters['mealType'] === "STAR" ? 1080 : 720
-var videoHeight = parameters['mealType'] === "STARPRO" || parameters['mealType'] === "STAR" ? 1920 : 1280
+var videoWidth = Number(parameters['resolvingPower']) ? Number(parameters['resolvingPower']) : 720
+var videoHeight = videoWidth === 720 ? 1280 : 1920
 
 var wsss, errorTime = 0;
 var first = true;
@@ -124,17 +123,28 @@ $(".botmat1img").on("click", function () {
   }
 
 })
-//高清控制
+// 高清控制
 $(".PictureQuality").on("click", function () {
   $(this).addClass("avit").siblings().removeClass('avit')
   var id = $(this).attr("data-id")
-  var bitRate = {
-    "data": {
-      "bitRate": id
-    },
-    "type": "bitRate"
+  var buffer = makeSharpness(Number(id));
+  ws.send(buffer);
+  isFeed = false;
+  isAudioPlay = false;
+  $('.weui-mask_transparent').show();
+  $('.weui-toast').show();
+  if (jmuxer) {
+    jmuxer.destroy();
   }
-  wsss.send(JSON.stringify(bitRate))
+  jmuxer = new JMuxer({
+    node: 'playerVideo',
+    flushingTime: 33,
+    fps: 30,
+    mode: 'video',
+    debug: false
+  });
+  myVideo.play();
+  isWaitSps = true;
 })
 //画图形
 var draw_graph = function (graphType, obj) {

+ 39 - 71
screenAndroid/WXtrialInterface.html

@@ -53,10 +53,10 @@
     </div>
     <div class="leftmains">
       <div class="PictureQualityMain">
-        <div class="PictureQuality " data-id="1803000">高清</div>
-        <div class="PictureQuality avit" data-id="1243000">标清</div>
-        <div class="PictureQuality" data-id="400000">极速</div>
-        <div class="PictureQuality" data-id="200">自动</div>
+        <div class="PictureQuality" data-id="4">高清</div>
+        <div class="PictureQuality avit" data-id="3">标清</div>
+        <div class="PictureQuality" data-id="2">极速</div>
+
       </div>
       <div class="operation">
         <div class="upload" id="showsuss" data-text="uploads">
@@ -111,8 +111,9 @@
   <script type="text/javascript" src="pcm-player.js"></script>
   <script type="text/javascript" src="https://cdn.bootcss.com/vConsole/3.2.0/vconsole.min.js"></script>
   <script src="https://cdn.bootcss.com/jquery-weui/1.2.1/js/jquery-weui.min.js"></script>
-  <script type="text/javascript" src="WXdraw.js?v=110"></script>
+  <script type="text/javascript" src="WXdraw.js"></script>
   <script type="text/javascript" src="jmuxer.js"></script>
+  <script type="text/javascript" src="spsParser.js"></script>
   <script>
     var parameters = GetRequest();
     if (parameters['mealType'] === 'VIP') {
@@ -163,15 +164,10 @@
     var winese = document.createElement("wine");
     wine.style.top = "-" + winese + 'px';
 
-    var requestCount = 0;
     var isVisuable = true;
     var isFeed = true;
-    var isDrag = false;
-    var isEnough = true;
     var isFinish = false;
-
-    var delayTime = new Date().getTime();
-    var curTime = new Date().getTime();
+    var isWaitSps = false;
     var myVideo = document.getElementById("playerVideo");
     Module = {};
     Module.onRuntimeInitialized = function () {
@@ -182,7 +178,6 @@
     var ip = parameters["ip"];
     var cardToken = parameters["cardToken"];
     cardToken = cardToken && cardToken.replace(/@/g, "=");
-    cardToken = cardToken.replace(/\$/g, "+");
     var appletPushAddress = parameters["appletPushAddress"];
     var socketURL = isWSS ? "wss://" + appletPushAddress + "?cardIp=" + ip + "&token=" + cardToken : "ws://" + appletPushAddress + "?cardIp=" + ip + "&token=" + cardToken;
 
@@ -195,8 +190,6 @@
     });
 
     window.onload = function () {
-      curTime = new Date().getTime();
-
       var myPlay = document.getElementById("wine");
 
       myPlay.onkeydown = function (event) {
@@ -228,7 +221,7 @@
           ws.send("ping");
         } else {
           clearInterval(intervaler);
-          $.toast("画面异常,请重新进入", "text");
+          $.toast("画面异常,请重新进入1", "text");
           if (navigator.userAgent.toLowerCase().includes('toutiaomicroapp')) {
             tt.miniProgram.switchTab({
               url: '/pages/home/home'
@@ -253,7 +246,7 @@
         clearInterval(intervaler);
         throttle(doConnect, 100);
         if (errorTime > 1000) {
-          $.toast("画面异常,请重新进入", "text");
+          $.toast("画面异常,请重新进入2", "text");
           wsss.close();
           if (navigator.userAgent.toLowerCase().includes('toutiaomicroapp')) {
             tt.miniProgram.switchTab({
@@ -282,9 +275,33 @@
           }
         }
 
+        if (data.frameType != undefined && data.frameType != 1 && data.frameType != 6) {
+          if (data.frameType == 7) {
+            let info = spsParser(data.video);
+
+            if (info.width != myVideo.videoWidth && info.height != myVideo.videoHeight) {
+              if (myVideo.videoWidth == 0) {
+                console.log("SPS计算得到宽 %d, 高 %d, 控件宽 %d, %d", info.width, info.height, myVideo.videoWidth, myVideo.videoHeight);
+              }
+            }
+          }
+        }
+
         if (data.video != null) { //喂视频
+          if (data.frameType == 0x05 && isVisuable) {
+            isFeed = true;
+          }
+
+          if (data.frameType == 7 || data.frameType == 8) {
+            isFeed = true;
+            isAudioPlay = true;
+            isWaitSps = false;
+          }
+
           if (isFeed) {
-            jmuxer.feed(data);
+            if (!isWaitSps) {
+              jmuxer.feed(data);
+            }
           }
         }
       });
@@ -348,11 +365,13 @@
       var input = new Uint8Array(data),
         duration,
         video,
+        frameType,
         audio;
       if (input[0] == 0 && input[1] == 0 && input[2] == 0 && input[3] == 1) {
         video = input;
         duration = 24;
         var nalType = input[4] & 0x1f;
+        frameType = nalType;
 
         if (!isFeed) {
           if (nalType == 0x05 && isVisuable) {
@@ -360,15 +379,7 @@
           }
         }
       } else if (input[0] == 0xff) {
-        if (!isEnough) {
-          requestCount++;
-        }
         audio = input;
-
-        if (new Date().getTime() - curTime > 100) {
-          delayTime = new Date().getTime();
-        }
-        curTime = new Date().getTime();
         duration = 24;
       } else if (input[0] == 0x68) {
         if (input[23] == 0x5c) {
@@ -380,7 +391,7 @@
             ws.send(checkBuffer);
           }
           else {
-            $.toast("画面异常,请重新进入", "text");
+            $.toast("画面异常,请重新进入3", "text");
             clearInterval(intervaler);
             ws.close();
             wsss.close();
@@ -417,7 +428,8 @@
       return {
         audio: audio,
         video: video,
-        duration: duration
+        duration: duration,
+        frameType: frameType
       };
     }
 
@@ -620,7 +632,6 @@
         }
       });
     }
-    var orientation = 0; //0 竖屏,1横屏
 
     var btnMuted = document.querySelector("#btnMuted");
     btnMuted && (function () {
@@ -758,24 +769,6 @@
       btnMuted.classList.remove("hide");
     })();
 
-    $(".boximg").on("click", function () {
-      $(".mainbox").css({
-        "display": "none"
-      })
-    })
-    // 剪贴板
-    $(".sboxbu").on("click", function () {
-      $(".sbox").css({
-        "display": "none"
-      })
-    })
-    // 剪贴板
-    $(".uploadss").on("click", function () {
-      $(".sbox").css({
-        "display": "none"
-      })
-    })
-
     $("#upload").on("click", function () {
       clearInterval(intervaler);
       ws.close();
@@ -790,31 +783,6 @@
         })
       }
     })
-
-    function selectText(x) {
-      if (document.selection) {
-        var range = document.body.createTextRange();
-        range.moveToElementText(x);
-        range.select();
-      } else if (window.getSelection) {
-        var selection = window.getSelection();
-        var range = document.createRange();
-        selection.removeAllRanges();
-        range.selectNodeContents(x);
-        selection.addRange(range);
-      }
-    }
-
-    function cp(x) {
-      $(".mainbox").css({
-        "display": "none"
-      })
-      $(".sbox").css({
-        "display": "block"
-      })
-      selectText(x);
-      document.execCommand("copy");
-    }
     window.onbeforeunload = function () {
       ws.close();
       wsss.close();

文件差異過大導致無法顯示
+ 136 - 128
screenAndroid/helper.js


+ 191 - 0
screenAndroid/spsParser.js

@@ -0,0 +1,191 @@
+//https://blog.csdn.net/lizhijian21/article/details/80982403
+function ceil(val) {
+  return Math.ceil(val);
+}
+
+//获取buf 的前n个bit组成的值
+function u(bitCount, input) {
+  let ret = 0;
+
+  for (var i = 0; i < bitCount; i++) {
+    ret <<= 1;
+
+
+    if (input.data[Math.floor(input.index / 8)] & (0x80 >> (input.index % 8))) {
+      ret += 1;
+    }
+
+    input.index++;
+  }
+
+  return ret;
+}
+
+/*无符号指数哥伦布编码(UE)
+*哥伦布编码的码字code_word由三部分组成:code_word = [M个0] + [1] + [Info]
+*其中,Info是一个携带信息的M位数据,每个哥伦布码的长度为(2M+1)位,每个码字都可由code_num产生。
+*根据码字code_word解码出code_num值的过程如下:
+*1. 首先读入M位以"1"为结尾的0;
+*2. 根据得到的M,读入接下来的M位Info数据;
+*3. 根据这个公式得到计算结果code_num = Info – 1 + 2M
+*/
+
+function ue(input, len) {
+  let zeroNum = 0;
+  while (input.index < len * 8) {
+    if (input.data[Math.floor(input.index / 8)] & (0x80 >> (input.index % 8)))//遇到1则停止,统计0的个数
+    {
+      break;
+    }
+
+    zeroNum++;
+    input.index++;
+  }
+
+  input.index++;
+
+  let ret = 0;
+  //计算
+  for (var i = 0; i < zeroNum; i++) {
+    ret <<= 1;
+    if (input.data[Math.floor(input.index / 8)] & (0x80 >> input.index % 8)) {
+      ret += 1;
+    }
+
+    input.index++;
+  }
+
+  return (1 << zeroNum) - 1 + ret;
+}
+
+//有符号哥伦布编码
+function se(input, len) {
+  let ueVal = ue(input, len);
+  let k = ueVal;
+  let nValue = ceil(k / 2);
+
+  if (ueVal % 2 == 0)
+    nValue = -nValue;
+  return nValue;
+}
+
+
+function spsParser(buf) {
+  let startBitIndex = 0;
+
+  buf = buf.slice(4);//去除00 00 00 01竞争码
+  let len = buf.length;
+
+  //输入参数
+  let input = {
+    data: buf,
+    index: startBitIndex
+  };
+
+
+  let forbidden_zero_bit = u(1, input);
+  let nal_ref_idc = u(2, input);
+  let nal_unit_type = u(5, input);
+  let chroma_format_idc;
+
+  if (nal_unit_type == 7) {
+    let profile_idc = u(8, input);
+    let constraint_set0_flag = u(1, input);
+    let constraint_set1_flag = u(1, input);
+    let constraint_set2_flag = u(1, input);
+    let constraint_set3_flag = u(1, input);
+    let constraint_set4_flag = u(1, input);
+    let constraint_set5_flag = u(1, input);
+
+    let reserved_zero_2bits = u(2, input);
+    let level_idc = u(8, input);
+    let seq_parameter_set_id = ue(input, len);
+
+    if (profile_idc == 100 | profile_idc == 110 || profile_idc == 122 || profile_idc == 144) {
+      chroma_format_idc = ue(input, len);
+
+      if (chroma_format_idc == 3) {
+        var residual_colour_transform_flag = u(1, input);
+      }
+
+      let bit_depth_luma_minus8 = ue(input, len);
+      let bit_depth_chroma_minus8 = ue(input, len);
+      let qpprime_y_zero_transform_bypass_flag = u(1, input);
+      let seq_scaling_matrix_present_flag = u(1, input);
+
+      let seq_scaling_list_present_flag = new Uint8Array(8);
+      if (seq_scaling_matrix_present_flag) {
+        for (var i = 0; i < 8; i++) {
+          seq_scaling_list_present_flag[i] = u(1, input);
+        }
+      }
+    }
+
+
+    let log2_max_frame_num_minus4 = ue(input, len);
+    let pic_order_cnt_type = ue(input, len);
+
+    if (pic_order_cnt_type == 0)
+      log2_max_pic_order_cnt_lsb_minus4 = ue(input, len);
+
+    else if (pic_order_cnt_type == 1) {
+      let delta_pic_order_always_zero_flag = u(1, input);
+      let offset_for_non_ref_pic = se(input, len);
+      let offset_for_top_to_bottom_field = se(input, len);
+      let num_ref_frames_in_pic_order_cnt_cycle = ue(input, len);
+
+      let offset_for_ref_frame = new Uint8Array[num_ref_frames_in_pic_order_cnt_cycle];
+
+      for (var i = 0; i < num_ref_frames_in_pic_order_cnt_cycle; i++)
+        offset_for_ref_frame[i] = se(input, len);
+    }
+
+    let num_ref_frames = ue(input, len);
+    let gaps_in_frame_num_value_allowed_flag = u(1, input);
+    let pic_width_in_mbs_minus1 = ue(input, len);
+    let pic_height_in_map_units_minus1 = ue(input, len);
+
+    let width = (pic_width_in_mbs_minus1 + 1) * 16;//可能还要进行裁剪处理
+    let height = (pic_height_in_map_units_minus1 + 1) * 16;
+
+    let frame_mbs_only_flag = u(1, input);
+
+    if (!frame_mbs_only_flag) {
+      u(1, input);
+    }
+
+    let direct_8x8_inference_flag = u(1, input);
+    let frame_cropping_flag = u(1, input);
+
+    if (frame_cropping_flag) {
+      let frame_crop_left_offset = ue(input, len);
+      let frame_crop_right_offset = ue(input, len);
+      let frame_crop_top_offset = ue(input, len);
+      let frame_crop_bottom_offset = ue(input, len);
+
+      let crop_unit_x = 1;
+      let crop_unit_y = 2 - frame_mbs_only_flag;
+
+      if (chroma_format_idc == 1) {   //4:2:0
+        crop_unit_x = 2;
+        crop_unit_y = 2 * (2 - frame_mbs_only_flag);
+      }
+      else if (chroma_format_idc == 2) {    //4:2:2
+        crop_unit_x = 2;
+        crop_unit_y = 2 - frame_mbs_only_flag;
+      }
+
+
+      width -= crop_unit_x * (frame_crop_left_offset + frame_crop_right_offset);
+      height -= crop_unit_y * (frame_crop_top_offset + frame_crop_bottom_offset);
+    }
+
+    return {
+      width: width,
+      height: height
+    }
+
+  }
+}
+
+

+ 10 - 11
screenIos/WXdraw.js

@@ -22,7 +22,6 @@ var parameters = GetRequest();
 var form = {};
 var cardToken = parameters["cardToken"];
 cardToken = cardToken && cardToken.replace(/@/g, "=");
-cardToken = cardToken.replace(/\$/g, "+");
 form.cardIp = parameters['cardIp'];
 form.port = parameters['port'];
 form.sn = parameters['sn'];
@@ -32,8 +31,8 @@ form.ip = parameters['ip'];
 form.domainName = parameters["domainName"];
 var isWSS = true;
 var cUrl = isWSS ? "wss://" + form.domainName + "?cardIp=" + form.ip + "&token=" + cardToken : "ws://" + form.domainName + "?cardIp=" + form.ip + "&token=" + cardToken;
-var videoWidth = parameters['mealType'] === "STARPRO" || parameters['mealType'] === "STAR" ? 1080 : 720
-var videoHeight = parameters['mealType'] === "STARPRO" || parameters['mealType'] === "STAR" ? 1920 : 1280
+var videoWidth = parameters['resolvingPower'] ? parameters['resolvingPower'] : 720
+var videoHeight = parameters['resolvingPower'] === 720 ? 1280 : 1920
 var wsss;
 var errorTime = 0;
 var first = true;
@@ -122,17 +121,17 @@ $(".botmat1img").on("click", function () {
     wsss.send(ExexuteKeyBoard(187));
   }
 })
-//高清控制
+// 高清控制
 $(".PictureQuality").on("click", function () {
   $(this).addClass("avit").siblings().removeClass('avit')
   var id = $(this).attr("data-id")
-  var bitRate = {
-    "data": {
-      "bitRate": id
-    },
-    "type": "bitRate"
-  }
-  wsss.send(JSON.stringify(bitRate))
+  var cmd = {
+    type: "switchSharpness",
+  };
+
+  decodeWoker.postMessage(cmd);//通知解码器worker切换分辨率		
+  var buffer = makeSharpness(Number(id));
+  webSocketWorker.postMessage(buffer);
 })
 var canDraw = false;
 //画图形

+ 38 - 60
screenIos/WXtrialInterface.html

@@ -51,10 +51,9 @@
     </div>
     <div class="leftmains">
       <div class="PictureQualityMain">
-        <div class="PictureQuality " data-id="1803000">高清</div>
-        <div class="PictureQuality avit" data-id="1243000">标清</div>
-        <div class="PictureQuality" data-id="400000">极速</div>
-        <div class="PictureQuality" data-id="200">自动</div>
+        <div class="PictureQuality" data-id="4">高清</div>
+        <div class="PictureQuality avit" data-id="3">标清</div>
+        <div class="PictureQuality" data-id="2">极速</div>
       </div>
       <div class="operation">
         <div class="upload" id="showsuss" data-text="uploads">
@@ -108,7 +107,7 @@
   <script type="text/javascript" src="pcm-player.js"></script>
   <script type="text/javascript" src="webgl.js"></script>
   <script type="text/javascript" src="https://cdn.bootcss.com/vConsole/3.2.0/vconsole.min.js"></script>
-  <script type="text/javascript" src="WXdraw.js?id=105"></script>
+  <script type="text/javascript" src="WXdraw.js"></script>
   <script type="text/javascript">
     $(function () {
       //手指滑动多少距离就认为是滑成功
@@ -190,7 +189,7 @@
   <script>
     var topwinHeight = window.screen.height - window.innerHeight + 30; //计算title top 头部
     var parameters = GetRequest();
-    var renderCount = 0;
+
     if (parameters['mealType'] === 'VIP') {
       $(".loading_sceen_pic").attr('src', '../static/img/home_bg_VIP.png');
     } else if (parameters['mealType'] === 'SVIP') {
@@ -404,9 +403,6 @@
         });
     }
 
-    // 初始化一下就可以了,
-    // var vConsole = new VConsole();
-
     var btnMuted = document.querySelector("#btnMuted");
     btnMuted && (function () {
       var setHistory = function (left, top) {
@@ -545,25 +541,6 @@
       btnMuted.classList.remove("hide");
     })();
 
-    $(".boximg").on("click", function () {
-      $(".mainbox").css({
-        "display": "none"
-      })
-    })
-
-    // 剪贴板
-    $(".sboxbu").on("click", function () {
-      $(".sbox").css({
-        "display": "none"
-      })
-    })
-    // 剪贴板
-    $(".uploadss").on("click", function () {
-      $(".sbox").css({
-        "display": "none"
-      })
-    })
-
     $("#upload").on("click", function () {
       decodeWoker.postMessage('close');
       decodeWoker.terminate();
@@ -579,35 +556,10 @@
       }
     })
 
-    function selectText(x) {
-      if (document.selection) {
-        var range = document.body.createTextRange();
-        range.moveToElementText(x);
-        range.select();
-      } else if (window.getSelection) {
-        var selection = window.getSelection();
-        var range = document.createRange();
-        selection.removeAllRanges();
-        range.selectNodeContents(x);
-        selection.addRange(range);
-      }
-    }
-
     function handleClose() {
       $('.mask').hide();
     }
 
-    function cp(x) {
-      $(".mainbox").css({
-        "display": "none"
-      })
-      $(".sbox").css({
-        "display": "block"
-      })
-      selectText(x);
-      document.execCommand("copy");
-
-    }
     var decodeCount = 1;
     var isFinish = false;
     var player = new PCMPlayer({
@@ -645,8 +597,10 @@
       Module._free(inputPtr);
       Module._free(retPtr);
     }
-    var decodeWoker = new Worker('decoder.js?width=' + videoWidth + '&height=' + videoHeight);
+    var decodeWoker = new Worker('decoder.js');
     var myVideo = document.getElementById("playCanvas");
+    var logicWidth = 720;
+		var logicHeight = 1280;
     decodeWoker.onmessage = function (event) {
       var objData = event.data;
 
@@ -654,13 +608,18 @@
         case 0:
           break;
         case 1:
-          if (renderCount++ < 4 || !isAudioPlay) {
-            return
+          if (logicWidth != objData.width || logicHeight != objData.height) {
+            logicWidth = objData.width;
+						logicHeight = objData.height;
           }
-          webglPlayer.renderFrame(objData.data, videoWidth, videoHeight, videoWidth * videoHeight, (videoWidth / 2) * (videoHeight / 2));
+          webglPlayer.renderFrame(objData.data, logicWidth, logicHeight, logicWidth * logicHeight, (logicWidth / 2) * (logicHeight / 2));
           $('.weui-mask_transparent').hide()
           $('.weui-toast').hide()
           $('.loading').hide()
+          break;
+        case 5:
+          var buffer = RequestIFrame();
+          webSocketWorker.postMessage(buffer);
       }
     }
 
@@ -685,16 +644,19 @@
     var appletPushAddress = parameters["appletPushAddress"];
     var token = parameters["cardToken"];
     cardToken = cardToken && cardToken.replace(/@/g, "=");
-    cardToken = cardToken.replace(/$/g, "+");
     var webSocketWorker = new Worker('websocket.js?ip=' + ip + '&appletPushAddress=' + appletPushAddress + '&token=' + token);
 
     webSocketWorker.onmessage = function (event) {
       var input = event.data;
-      if (input[0] == 0xff && isAudioPlay && renderCount >= 4) {
+      if (input[0] == 0xff && isAudioPlay) {
         decodeAAC(input);
       }
       if (input[0] == 0 && input[1] == 0 && input[2] == 0 && input[3] == 1) {
-        decodeWoker.postMessage(event.data);
+        var cmd = {
+          type: "rawData",
+          data: event.data
+        };
+        decodeWoker.postMessage(cmd);
       }
       if (input[0] == 0x68) {
         if (input[23] == 0x5c) {
@@ -768,6 +730,22 @@
     myVideo.onkeydown = function (event) {
       ExexuteKeyDown(e.keyCode);
     }
+    var level = 2;
+    function switchSharpness() {
+      var cmd = {
+        type: "switchSharpness",
+      };
+
+      decodeWoker.postMessage(cmd);//通知解码器worker切换分辨率		
+      var buffer = makeSharpness(level);
+      webSocketWorker.postMessage(buffer);
+
+      if (level < 4) {
+        level++;
+      } else {
+        level = 0;
+      }
+    }
     window.onbeforeunload = function () {
       wsss.close();
       decodeWoker.postMessage('close');

+ 110 - 60
screenIos/decoder.js

@@ -1,16 +1,27 @@
 var isFinish = false;
-var decodeCount = 0;
+var isSwitchSharpness = false;
 var h264Queue = [];
-var isFirst = true;
-var ret = ''
-var parameters = GetRequest();
-var videoWidth = parameters['width'];
-var videoHeight = parameters['height'];
+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 () {
-    ret = Module._openDecoder(videoWidth, videoHeight);
+    isFinish = true;
+    doSomeInit();
+    ret = Module._openDecoder();
+
     if (!ret) {
-      isFinish = true;
+      console.log("打开编码器成功");
     }
   }
 };
@@ -18,7 +29,32 @@ self.Module = {
 self.importScripts("ffmpeghelper.js");
 
 self.addEventListener('message', function (e) {
-  h264Queue.push(e.data);
+  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) {
@@ -31,76 +67,90 @@ function PrintfLog(str) {
   self.postMessage(objData);
 }
 
-setInterval(
-  function () {
-    if (h264Queue.length > 0 && isFinish) {
-      if (isFirst) {
-        PrintfLog("当前队列大小 :" + h264Queue.length);
-        isFirst = false;
-      }
+function doRequestIFrame() {
+  var objData = {
+    cmd: 5,
+  };
+  self.postMessage(objData);
+}
 
-      if (h264Queue.length > 10 && isFinish) {
-        PrintfLog("解不过来 " + h264Queue.length);
-        return;
-      }
 
-      decodeH264(h264Queue.shift());
-    }
-  }, 1);
+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 size = videoWidth * videoHeight *3;
-  var retPtr = Module._malloc(size); //接收的数据
+  var frameWidth = 0;
+  var frameHeight = 0;
   var inputPtr = Module._malloc(data.length); //输入数据
 
-  for (var i = 0; i < data.length; i++) {
+  for (i = 0; i < data.length; i++) {
     Module.HEAPU8[(inputPtr) + i] = data[i]; //转换为堆数据
   }
 
   var time = new Date().getTime();
-  var ret = Module._feedData(inputPtr, data.length, retPtr);
-
-  if (ret >= 0) {
-    if (decodeCount > 50) {
-      var curCost = new Date().getTime() - time;
-      PrintfLog("解码耗时 " + curCost + " ms");
-      decodeCount = 0;
-    }
-    decodeCount++;
+  var allocSize = maxWidth * maxHeight * 3 / 2;
+  if (globalYuvPtr == undefined) {
+    globalYuvPtr = Module._malloc(allocSize);
   }
 
-  var yuvData = new Uint8Array(size);
-  for (var i = 0; i < yuvData.length; i++) {
-    yuvData[i] = Module.HEAPU8[(retPtr) + i];
+  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++;
+    }
   }
 
-  var curTime = new Date().getTime();
-  var objData = {
-    cmd: 1,
-    data: yuvData,
-    time: curTime
-  };
-  self.postMessage(objData);
   Module._free(inputPtr);
-  Module._free(retPtr);
 }
 
 
 function closeDecoder() {
-  Module._destroyDecoder();
-}
+  clearInterval(timeFlag);//关闭原有定时器
+  Module._closeDecoder();
+  renderCount = 0;
 
-// 获取url中"?"符后的字串
-function GetRequest() {
-  var url = location.search;
-  var obj = new Object();
-  if (url.indexOf("?") != -1) {
-    var str = url.substring(1);
-    strs = str.split("&");
-    for (var i = 0; i < strs.length; i++) {
-      obj[strs[i].split("=")[0]] = (strs[i].split("=")[1]);
-    }
+  if (globalYuvPtr != undefined) {
+    Module._free(globalYuvPtr);
+    globalYuvPtr = undefined;
   }
-  return obj;
-}
+  console.log("此时buffer长度: %d", h264Queue.length);
+  while (h264Queue.lengh > 0) {
+    h264Queue.shift();
+  }
+}

文件差異過大導致無法顯示
+ 1 - 1
screenIos/ffmpeghelper.js


二進制
screenIos/ffmpeghelper.wasm


文件差異過大導致無法顯示
+ 192 - 198
screenIos/helper.js