瀏覽代碼

新增安卓软解

wuyongxiang 4 年之前
父節點
當前提交
2a42e21229
共有 62 個文件被更改,包括 12210 次插入4 次删除
  1. 1 0
      screenAndroid/aac.js
  2. 37 0
      screenAndroid/aac.js.map
  3. 二進制
      screenAndroid/aac.wasm
  4. 3937 0
      screenAndroid/aurora.js
  5. 77 0
      screenAndroid/aurora.js.map
  6. 134 0
      screenAndroid/css/homePage.css
  7. 13 0
      screenAndroid/css/swiper-bundle.min.css
  8. 14 0
      screenAndroid/css/swiper-bundle.min.js
  9. 185 0
      screenAndroid/helper.js
  10. 1622 0
      screenAndroid/homeNew.html
  11. 二進制
      screenAndroid/images/loader-thumb.jpg
  12. 二進制
      screenAndroid/img/fenxiang_icon.png
  13. 二進制
      screenAndroid/img/fenxiang_icon@2x.png
  14. 二進制
      screenAndroid/img/goumai_icon(1).png
  15. 二進制
      screenAndroid/img/goumai_icon.png
  16. 二進制
      screenAndroid/img/goumai_icon@2x(1).png
  17. 二進制
      screenAndroid/img/goumai_icon@2x.png
  18. 二進制
      screenAndroid/img/jia_bu_icon.png
  19. 二進制
      screenAndroid/img/jia_bu_icon@2x.png
  20. 二進制
      screenAndroid/img/jia_ke_icon.png
  21. 二進制
      screenAndroid/img/jia_ke_icon@2x.png
  22. 二進制
      screenAndroid/img/jian_bu_icon.png
  23. 二進制
      screenAndroid/img/jian_bu_icon@2x.png
  24. 二進制
      screenAndroid/img/jian_ke_icon.png
  25. 二進制
      screenAndroid/img/jian_ke_icon@2x.png
  26. 二進制
      screenAndroid/img/kefu_wei_icon.png
  27. 二進制
      screenAndroid/img/kefu_wei_icon@2x.png
  28. 二進制
      screenAndroid/img/kefu_xuanzhong_icon.png
  29. 二進制
      screenAndroid/img/kefu_xuanzhong_icon@2x.png
  30. 二進制
      screenAndroid/img/kefurexian_icon.png
  31. 二進制
      screenAndroid/img/kefurexian_icon@2x.png
  32. 二進制
      screenAndroid/img/kuorong_icon.png
  33. 二進制
      screenAndroid/img/kuorong_icon@2x.png
  34. 二進制
      screenAndroid/img/qq_icon.png
  35. 二進制
      screenAndroid/img/qq_icon@2x.png
  36. 二進制
      screenAndroid/img/shijian_icon.png
  37. 二進制
      screenAndroid/img/shijian_icon@2x.png
  38. 二進制
      screenAndroid/img/wenzi_icon.png
  39. 二進制
      screenAndroid/img/wenzi_icon@2x.png
  40. 二進制
      screenAndroid/img/wode_wei_icon.png
  41. 二進制
      screenAndroid/img/wode_wei_icon@2x.png
  42. 二進制
      screenAndroid/img/wode_xuanzhong_icon.png
  43. 二進制
      screenAndroid/img/wode_xuanzhong_icon@2x.png
  44. 二進制
      screenAndroid/img/xiazai_icon.png
  45. 二進制
      screenAndroid/img/xiazai_icon@2x.png
  46. 二進制
      screenAndroid/img/xuankang_xuan_icon.png
  47. 二進制
      screenAndroid/img/xuankang_xuan_icon@2x.png
  48. 二進制
      screenAndroid/img/xuankuang_wei_icon.png
  49. 二進制
      screenAndroid/img/xuankuang_wei_icon@2x.png
  50. 二進制
      screenAndroid/img/yunshouji_wei_icon.png
  51. 二進制
      screenAndroid/img/yunshouji_wei_icon@2x.png
  52. 二進制
      screenAndroid/img/yunshouji_xuanzhong_icon.png
  53. 二進制
      screenAndroid/img/yunshouji_xuanzhong_icon@2x.png
  54. 411 0
      screenAndroid/index - 副本.html
  55. 415 0
      screenAndroid/index.html
  56. 2566 0
      screenAndroid/jmuxer.js
  57. 2563 0
      screenAndroid/jmuxer.min.js
  58. 3 0
      screenAndroid/package-lock.json
  59. 173 0
      screenAndroid/temp.html
  60. 48 1
      screenIos/homeNew.html
  61. 1 0
      screenIos/pcm-player.min.js
  62. 10 3
      screenIos/websocket.js

文件差異過大導致無法顯示
+ 1 - 0
screenAndroid/aac.js


文件差異過大導致無法顯示
+ 37 - 0
screenAndroid/aac.js.map


二進制
screenAndroid/aac.wasm


文件差異過大導致無法顯示
+ 3937 - 0
screenAndroid/aurora.js


文件差異過大導致無法顯示
+ 77 - 0
screenAndroid/aurora.js.map


+ 134 - 0
screenAndroid/css/homePage.css

@@ -0,0 +1,134 @@
+* {
+	margin: 0;
+	padding: 0;
+}
+
+.heads {
+	padding: 40px 30px 0px 30px;
+	overflow: hidden;
+}
+
+.heads-left {
+	color: #3399FF;
+}
+
+.heads-right {
+	width: 60px;
+	height: 60px;
+}
+
+.heads-right image {
+	width: 100%;
+	height: 100%;
+}
+
+.left {
+	float: left;
+}
+
+.right {
+	float: right;
+}
+
+#wine {
+	width: 100%;
+	height: 100%;
+}
+
+.newhelp {
+	display: flex;
+	font-size: 12px;
+	font-family: PingFangSC-Regular, PingFang SC;
+	font-weight: 400;
+	color: #999999;
+	line-height: 17px;
+	align-items: center;
+	position: absolute;
+	top: 0;
+	left: 0;
+	margin-top: 10px;
+	margin-left: 15px;
+}
+
+.newhelp .font {
+	text-decoration: underline;
+	margin-left: 2px;
+}
+
+.newhelp .helpImg {
+	width: 0.875rem;
+	height: 0.875rem;
+}
+
+.newhelp .helpImg img {
+	width: 100%;
+	height: 100%;
+}
+
+.buyIcon {
+	position: absolute;
+	top: 0;
+	right: 0;
+	/* 	margin-top: 0.625rem;
+	margin-right: 0.625rem;
+	 */
+}
+
+.swiper-container {
+	width: 100%;
+	height: 100%;
+}
+
+.swiper-slide {
+	/* padding: 43px 53px; */
+	padding: 12% 14%;
+	box-sizing: border-box;
+	text-align: center;
+	font-size: 18px;
+	/* background: #fff; */
+	/* height: 667px; */
+	height: 100%;
+	/* Center slide text vertically */
+	display: -webkit-box;
+	display: -ms-flexbox;
+	display: -webkit-flex;
+	display: flex;
+	-webkit-box-pack: center;
+	-ms-flex-pack: center;
+	-webkit-justify-content: center;
+	justify-content: center;
+	-webkit-box-align: center;
+	-ms-flex-align: center;
+	-webkit-align-items: center;
+	align-items: center;
+}
+
+.swiper-button-next {
+	width: 15px;
+	height: 15px;
+	background: url(../../static/img/xia_icon.png);
+	right: 15px;
+}
+
+.swiper-button-prev {
+	width: 15px;
+	height: 15px;
+	background: url(../../static/img/shang_icon.png);
+	left: 15px;
+}
+
+.swiper-button-next:after,
+.swiper-container-rtl .swiper-button-prev:after {
+	content: "" !important;
+}
+
+.swiper-button-prev:after,
+.swiper-container-rtl .swiper-button-next:after {
+	content: "" !important;
+}
+
+.thl-time {
+	text-align: left;
+	margin-left: -0.4rem !important;
+	c
+}

文件差異過大導致無法顯示
+ 13 - 0
screenAndroid/css/swiper-bundle.min.css


文件差異過大導致無法顯示
+ 14 - 0
screenAndroid/css/swiper-bundle.min.js


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


文件差異過大導致無法顯示
+ 1622 - 0
screenAndroid/homeNew.html


二進制
screenAndroid/images/loader-thumb.jpg


二進制
screenAndroid/img/fenxiang_icon.png


二進制
screenAndroid/img/fenxiang_icon@2x.png


二進制
screenAndroid/img/goumai_icon(1).png


二進制
screenAndroid/img/goumai_icon.png


二進制
screenAndroid/img/goumai_icon@2x(1).png


二進制
screenAndroid/img/goumai_icon@2x.png


二進制
screenAndroid/img/jia_bu_icon.png


二進制
screenAndroid/img/jia_bu_icon@2x.png


二進制
screenAndroid/img/jia_ke_icon.png


二進制
screenAndroid/img/jia_ke_icon@2x.png


二進制
screenAndroid/img/jian_bu_icon.png


二進制
screenAndroid/img/jian_bu_icon@2x.png


二進制
screenAndroid/img/jian_ke_icon.png


二進制
screenAndroid/img/jian_ke_icon@2x.png


二進制
screenAndroid/img/kefu_wei_icon.png


二進制
screenAndroid/img/kefu_wei_icon@2x.png


二進制
screenAndroid/img/kefu_xuanzhong_icon.png


二進制
screenAndroid/img/kefu_xuanzhong_icon@2x.png


二進制
screenAndroid/img/kefurexian_icon.png


二進制
screenAndroid/img/kefurexian_icon@2x.png


二進制
screenAndroid/img/kuorong_icon.png


二進制
screenAndroid/img/kuorong_icon@2x.png


二進制
screenAndroid/img/qq_icon.png


二進制
screenAndroid/img/qq_icon@2x.png


二進制
screenAndroid/img/shijian_icon.png


二進制
screenAndroid/img/shijian_icon@2x.png


二進制
screenAndroid/img/wenzi_icon.png


二進制
screenAndroid/img/wenzi_icon@2x.png


二進制
screenAndroid/img/wode_wei_icon.png


二進制
screenAndroid/img/wode_wei_icon@2x.png


二進制
screenAndroid/img/wode_xuanzhong_icon.png


二進制
screenAndroid/img/wode_xuanzhong_icon@2x.png


二進制
screenAndroid/img/xiazai_icon.png


二進制
screenAndroid/img/xiazai_icon@2x.png


二進制
screenAndroid/img/xuankang_xuan_icon.png


二進制
screenAndroid/img/xuankang_xuan_icon@2x.png


二進制
screenAndroid/img/xuankuang_wei_icon.png


二進制
screenAndroid/img/xuankuang_wei_icon@2x.png


二進制
screenAndroid/img/yunshouji_wei_icon.png


二進制
screenAndroid/img/yunshouji_wei_icon@2x.png


二進制
screenAndroid/img/yunshouji_xuanzhong_icon.png


二進制
screenAndroid/img/yunshouji_xuanzhong_icon@2x.png


+ 411 - 0
screenAndroid/index - 副本.html

@@ -0,0 +1,411 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <meta name="description" content="jMuxer - a simple javascript mp4 muxer for non-standard streaming communications protocol">
+    <meta name="keywords" content="h264 player, mp4 player, mse, mp4 muxing, jmuxer, aac player">
+    <title>JMuxer demo</title>
+    <script async defer src="https://buttons.github.io/buttons.js"></script>
+    <style type="text/css">
+        .github-tools {
+            position: absolute;
+            top: 15px;
+            right: 15px;
+        }
+        a.h264-player {
+            font-size: 20px;
+            text-decoration: none;
+            color: #07568e;
+            margin-top: 10px;
+            display: block;
+        }
+        .gesture {
+            font-size: 15px;
+            color: #ad4903;
+            margin-top: 10px;
+        }
+</style>
+</head>
+<body>
+
+<h2>jMuxer Demo</h2>
+<p>Sample demo node server is running on heroku free hosting</p>
+<br /><br />
+<div class="github-tools">
+<!-- Place this tag where you want the button to render. -->
+
+</div>
+
+<div id="container" style="width: 600px; margin: 0 auto;"> 
+    <video width="100%"   disablePictureInPicture ="true" autoplay poster="images/loader-thumb.jpg" id="player"></video>
+	<audio width="50%"  preload="none" autoplay controls poster="images/loader-thumb.jpg" id="audioPlayer" ></audio>
+    <div class="gesture">If it does not play automatically, Click the `video play button` to initiate the video</div>
+</div>
+
+<body oncontextmenu="Back()">
+</body>
+
+<script src="helper.js" >
+</script>
+
+<script>
+	//隐藏控件 controls
+  var fpsCount = 0;
+  var requestCount = 0;
+  var timeCount = 0;
+  var isVisuable = true;
+  var isFeed = true;
+  var isDrag = false;
+  var isEnough = true;
+  
+  var delayTime = new Date().getTime();
+  var feedTime = new Date().getTime();
+  var requestTime = new Date().getTime() ;
+  var curTime = new Date().getTime();
+  var requestTime = new Date().getTime();//记录离开时间
+  var myVideo = document.getElementById("player");
+  var myAudio = document.getElementById("audioPlayer");
+  var audioBuffer = [];
+  var audioBack = [];
+  
+  document.addEventListener("visibilitychange", () => {
+	
+    if (document.visibilityState == "visible") 
+	{
+		console.log("页面可见,继续喂视频");
+		//requestTime = new Date().getTime();	
+		isVisuable = true;
+    }
+	else
+	{
+		isVisuable = false;
+		isFeed = false;
+		myVideo.pause();
+	}
+	
+
+});  
+  
+  myVideo.addEventListener('pause',function(){
+            //console.log("视频播放暂停");
+			isFeed = false;
+        });
+		
+  myAudio.addEventListener('pause',function(){
+            console.log("音频播放暂停");
+			myAudio.play();
+        });
+ 
+ //解协议
+ function ParseProto(data)
+ {
+	var temp = "";
+	var input = new Uint8Array(data),
+	duration,
+	video,
+	audio;
+	
+	if(input[0] == 0 && input[1] == 0 && input[2] == 0 && input[3] == 1)
+	{
+		// debugger
+		video = input;
+		duration = 24;
+		var nalType = input[4] &0x1f;//nalType == 0x07|| nalType == 0x08 || nalType == 0x05
+		
+		if(!isFeed)
+		{	
+			if(nalType == 0x05)
+			{
+				console.log("发现I帧");
+			}
+		
+			 if(nalType  == 0x05 && isVisuable)
+			 {
+				console.log("检测到I帧 %d,重新渲染, 耗时 %d ms", nalType , new Date().getTime() - requestTime);
+				isFeed = true;	
+			 }			 			 	
+		}
+		
+	}
+	else if(input[0] == 0xff)
+	{
+		if(!isEnough)
+		{
+			requestCount++;
+		}
+		audio = input;
+		
+		if(new Date().getTime() - curTime > 100)
+		{
+			delayTime = new Date().getTime();
+			console.log("接收时间 %d ms", new Date().getTime() - curTime);
+		}
+		curTime = new Date().getTime();				
+		duration = 24;
+		//console.log("duration %d", duration);
+		
+	}
+	else if(input[0] == 0x68)
+	{	
+		if(input[23] == 0x05)//横竖屏标识
+		{
+			var state = CheckScreenDirection(input.slice(24, 24 + 8));
+			
+			if(state == 1)
+			{
+				console.log("安卓卡此时竖屏");
+				//竖屏处理
+			}
+			else
+			{
+				console.log("安卓卡此时横屏");
+				//横屏处理
+			}
+		}
+		
+		if(input[23] == 0x0b)
+		{
+			console.log("多端登陆");
+		}
+		//console.log("屏幕旋转 %s", PrintArry(input));
+	}
+
+	return {
+        audio: audio,
+        video: video,
+        duration: duration
+      };
+ }
+ 
+ window.onload = function() {
+    var socketURL = 'wss://jmuxer-demo-server.herokuapp.com';
+	 //socketURL = "ws://127.0.0.1:8080"
+	//socketURL = "ws://192.168.11.238:8080"
+	//socketURL = "ws://14.215.128.98:14112";
+	socketURL = "ws://192.168.11.66:9101";
+	//socketURL = "wss://192.168.11.242:9104";
+
+	
+    var jmuxer = new JMuxer({
+        node: 'player',
+		flushingTime:15 ,
+        fps: 30,
+		mode:'video',
+        debug: false
+     });
+	 
+	 var audioMuxer = new JMuxer({
+        node: 'audioPlayer',
+		flushingTime:1,
+		clearBuffer: true,
+        fps: 60,//可以不选,原先43
+		mode:'audio',
+        debug: false
+     });
+	 
+
+	 /*var costTime =  new Date().getTime() - curTime;
+	 if(costTime > 5)
+	 {
+		console.log("websocket接收延迟 %d ms", costTime);
+	 }*/
+	 
+	 curTime = new Date().getTime();	
+     var ws = new WebSocket(socketURL);
+     ws.binaryType = 'arraybuffer';
+	  
+	 //断开检测
+	 ws.onclose = function (e) {
+                alert("websocket连接断开");
+				console.log('websocket 断开: ' + e.code + ' ' + e.reason + ' ' + e.wasClean);
+				console.log(e);
+            }
+							
+	ws.addEventListener('open', function (event) {
+		console.log("发送配置帧");
+		ws.send(ConfigChannel("RK3923C1201900139"));
+	});
+	
+	ws.addEventListener('error', function (event) {
+		console.log("连接失败");
+	});
+	
+
+	/*setInterval(function()
+	{ 	
+		var audioData = 
+		{
+			audio: null,
+			video: null,
+			duration: 24
+		};
+				
+	    if(myAudio != null)
+		{	
+			if(audioBuffer.length < 1)
+			{			
+				if(audioBack.length > 0)
+				{
+					audioData.audio = audioBack[0];
+					audioMuxer.feed(audioData);
+					audioBack.shift();
+				}
+																	
+				return;
+			}
+			
+			if(audioBack.length > 10)
+			{
+				audioBack.shift();
+			}
+		
+			if(audioBuffer.length > 50)
+			{
+				console.log("当前大小 %d", audioBuffer.length);
+				audioBuffer = [];
+			}
+			else if(audioBuffer.length > 1)
+			{		    		   						
+				
+				var time = new Date().getTime();
+				audioData.audio = audioBuffer[0];
+				audioMuxer.feed(audioData);
+				
+				if(time - feedTime > 80)
+				{								
+					console.log("喂数据间隔 %d ms, 队列长度", time - feedTime, audioBuffer.length);
+				}
+				feedTime = time;
+				
+				audioBuffer.shift();
+			}
+		}
+	}, 1);*/
+	
+     ws.addEventListener('message',function(event) {
+		  var data = ParseProto(event.data);//JAVA服务器转发
+		  //console.log("收到数据");
+					
+		  var audioData = {
+			audio: data.audio,
+			video: null,
+			duration: data.duration
+		  };
+		  
+		  var videoData = {
+			audio: null,
+			video: data.video,
+			duration: data.duration
+		  };	  
+		 	 
+		
+		  if(myAudio.readyState == 2)
+		  {
+			requestTime = new Date().getTime();
+			isEnough = false;
+			console.log("数据存储不够,出现声音停止");
+			//myAudio.playbackRate = 2;
+		  }
+		  else if(myAudio.readyState == 4 && isEnough== false)
+		  {
+				var time = new Date().getTime();
+				isEnough = true;
+				console.log("填满耗时 %d ms, 填充帧数 %d, 填充延迟 %d ms", time - requestTime, requestCount, requestCount * 23);
+				requestCount = 0;
+				console.log("----接收到启动 %d ms---", time - delayTime);
+		  }
+		  
+		  if(data.audio != null)//喂音频
+		  {				
+			//audioBuffer.push(data.audio);
+			//audioBack.push(data.audio)			;
+			audioMuxer.feed(audioData);
+		  }		  
+		  
+		  if(data.video != null)//喂视频
+		  {
+			 if(isFeed)
+			 {
+				jmuxer.feed(data);
+			 }
+			 
+			 //jmuxer.feed(videoData);
+		  }
+		   	 	 	 	  
+     });
+	 
+	
+	myVideo.onmousedown = function(event)
+    {
+		//放在此处只是为了方便演示,实际使用中查找横竖屏只要刚连接上时调用一次就好。	
+		//var checkBuffer = GetScreenState();
+		//ws.send(checkBuffer);
+
+		if(!isFeed)
+		{
+			console.log("重新申请I帧");
+			requestTime = new Date().getTime();			
+			var buffer = RequestIFrame();
+			//var buffer = new Uint8Array([0x01]);
+			ws.send(buffer);
+		}
+		
+		//console.log("报文 %s", PrintArry(buffer));
+		
+	
+		if(event.button == 0)
+		{
+			var posX = event.offsetX * 1080 *1.0/myVideo.clientWidth;
+			var posY = event.offsetY * 1920 *1.0/myVideo.clientHeight;
+			var buffer = ExexuteMouseDown(posX.toString(), posY.toString());
+			ws.send(buffer);
+			isDrag = true;
+		}
+			
+    }
+	
+	myVideo.onmousemove = function(event)
+	{
+		if(isDrag && event.button == 0)
+		{
+			var posX = event.offsetX * 1080 *1.0/myVideo.clientWidth;
+			var posY = event.offsetY * 1920 *1.0/myVideo.clientHeight;
+			var buffer = ExexuteMouseMove(posX.toString(), posY.toString());
+			ws.send(buffer);
+			//console.log("移动位置 %d, %d", posX, posY);
+		}
+		
+	}
+	
+	myVideo.onmouseup = function(event)
+	{	
+		isDrag = false;
+		var posX = event.offsetX * 1080 *1.0/myVideo.clientWidth;
+		var posY = event.offsetY * 1920 *1.0/myVideo.clientHeight;
+		var buffer = ExexuteMouseUp(posX.toString(), posY.toString());
+		ws.send(buffer);
+		
+	}
+	
+	myVideo.onkeydown = function(event)
+	{	
+		ExexuteKeyDown(e.keyCode);
+	}
+	
+ }  
+
+function Back()
+{	
+	if(event.button == 2)
+	{
+		//ExexuteKeyDown(4);
+	}
+	ExexuteKeyDown(4);
+	window.event.returnValue=false;  
+    return false;  
+}
+ 
+</script>
+<script type="text/javascript" src="jmuxer.js"></script>
+</body>
+</html>

+ 415 - 0
screenAndroid/index.html

@@ -0,0 +1,415 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <meta name="description" content="jMuxer - a simple javascript mp4 muxer for non-standard streaming communications protocol">
+    <meta name="keywords" content="h264 player, mp4 player, mse, mp4 muxing, jmuxer, aac player">
+    <title>JMuxer demo</title>
+    <script async defer src="https://buttons.github.io/buttons.js"></script>
+    <style type="text/css">
+        .github-tools {
+            position: absolute;
+            top: 15px;
+            right: 15px;
+        }
+        a.h264-player {
+            font-size: 20px;
+            text-decoration: none;
+            color: #07568e;
+            margin-top: 10px;
+            display: block;
+        }
+        .gesture {
+            font-size: 15px;
+            color: #ad4903;
+            margin-top: 10px;
+        }
+</style>
+</head>
+<body>
+
+<h2>jMuxer Demo</h2>
+<p>Sample demo node server is running on heroku free hosting</p>
+<br /><br />
+<div class="github-tools">
+<!-- Place this tag where you want the button to render. -->
+
+</div>
+
+<div id="container" style="width: 600px; margin: 0 auto;"> 
+    <video width="70%"  disablePictureInPicture ="true"  autoplay poster="images/loader-thumb.jpg" id="player"></video>
+	<audio width="50%"  preload="auto" autoplay controls poster="images/loader-thumb.jpg" id="audioPlayer" ></audio>
+    <div class="gesture">If it does not play automatically, Click the `video play button` to initiate the video</div>
+</div>
+
+<body oncontextmenu="Back()">
+</body>
+
+<script src="helper.js" >
+</script>
+
+<script>
+	//隐藏控件 controls
+  var fpsCount = 0;
+  var requestCount = 0;
+  var timeCount = 0;
+  var isVisuable = true;
+  var isFeed = true;
+  var isDrag = false;
+  var shoudDrop = false;
+  var isEnough = true;
+  var ifCanPlay = false;
+  var isFinish = false;
+  
+  var delayTime = new Date().getTime();
+  var feedTime = new Date().getTime();
+  var readyTime = new Date().getTime();
+  var requestTime = new Date().getTime() ;
+  var curTime = new Date().getTime();
+  var requestTime = new Date().getTime();//记录离开时间
+  var myVideo = document.getElementById("player");
+  var myAudio = document.getElementById("audioPlayer");
+  var audioBuffer = [];
+  var audioBack = [];
+  
+  Module = {};
+  Module.onRuntimeInitialized = function() 
+  {
+	console.log("Wasm 加载成功!")
+	isFinish = true;
+  }
+ 
+  document.addEventListener("visibilitychange", () => {
+	
+    if (document.visibilityState == "visible") 
+	{
+		console.log("页面可见,继续喂视频");
+		//requestTime = new Date().getTime();	
+		isVisuable = true;
+    }
+	else
+	{
+		isVisuable = false;
+		isFeed = false;
+		myVideo.pause();
+	}
+	
+
+});  
+
+  
+  myVideo.play();
+  
+  myVideo.addEventListener('pause',function(){
+            //console.log("视频播放暂停");
+			isFeed = false;
+        });
+		
+  myAudio.addEventListener('canplay',function(){
+           console.log("缓冲区大小 %f", myAudio.buffered.end(0) - myAudio.buffered.start(0));
+        });
+		
+		/*function decodeAAC(data)
+		{
+			var retPtr = Module._malloc(4 * 5 * 1024);//接收的数据
+			var inputPtr = Module._malloc(4 * data.length);//输入数据
+			
+			for( i =0;i < data.length;i++)
+			{
+				Module.HEAPU8[(inputPtr)+i] = data[i];//转换为堆数据
+			}
+			
+			var pcmLen = Module._feedData(retPtr, inputPtr, data.length);
+			
+			if(pcmLen > 0)
+			{
+				//console.log("%d帧 aac 解码成功, %d", decodeCount, pcmLen);
+				var pcmData = new Uint8Array(pcmLen);		
+				for(i = 0;i < pcmLen;i++)
+				{
+					pcmData[i] = Module.HEAPU8[(retPtr)+i]
+				}
+				
+				player.feed(pcmData);
+			}
+			else
+			{
+				console.log("%d帧 aac 解码失败, %d", decodeCount, pcmLen);
+			}
+			
+			decodeCount++;
+			Module._free(inputPtr);
+			Module._free(retPtr);
+		}	*/
+		
+ 
+ //解协议
+ function ParseProto(data)
+ {
+	var temp = "";
+	var input = new Uint8Array(data),
+	duration,
+	video,
+	audio;
+	
+	if(input[0] == 0 && input[1] == 0 && input[2] == 0 && input[3] == 1)
+	{
+		// debugger
+		video = input;
+		duration = 24;
+		var nalType = input[4] &0x1f;//nalType == 0x07|| nalType == 0x08 || nalType == 0x05
+		
+		if(!isFeed)
+		{	
+			if(nalType == 0x05)
+			{
+				console.log("发现I帧");
+			}
+		
+			 if(nalType  == 0x05 && isVisuable)
+			 {
+				console.log("检测到I帧 %d,重新渲染, 耗时 %d ms", nalType , new Date().getTime() - requestTime);
+				isFeed = true;	
+			 }			 			 	
+		}
+		
+	}
+	else if(input[0] == 0xff)
+	{
+		if(!isEnough)
+		{
+			requestCount++;
+			//audioBuffer.push(input);
+		}
+		audio = input;
+		
+		if(new Date().getTime() - curTime > 100)
+		{
+			delayTime = new Date().getTime();
+			console.log("接收时间 %d ms", new Date().getTime() - curTime);
+		}
+		curTime = new Date().getTime();				
+		duration = 24;
+		//console.log("duration %d", duration);
+		
+	}
+	else if(input[0] == 0x68)
+	{	
+		if(input[23] == 0x05)//横竖屏标识
+		{
+			var state = CheckScreenDirection(input.slice(24, 24 + 8));
+			
+			if(state == 1)
+			{
+				console.log("安卓卡此时竖屏");
+				//竖屏处理
+			}
+			else
+			{
+				console.log("安卓卡此时横屏");
+				//横屏处理
+			}
+		}
+		
+		if(input[23] == 0x0b)
+		{
+			console.log("多端登陆");
+		}
+		//console.log("屏幕旋转 %s", PrintArry(input));
+	}
+
+	return {
+        audio: audio,
+        video: video,
+        duration: duration
+      };
+ }
+ 
+ window.onload = function() {
+    // var socketURL = 'wss://jmuxer-demo-server.herokuapp.com';
+	//socketURL = "ws://127.0.0.1:8080"
+	// socketURL = "ws://192.168.11.233:8080"
+	//socketURL = "ws://14.215.128.98:14112";
+	var socketURL = "ws://192.168.11.66:9101";
+	// socketURL = "ws://14.215.128.98:14077";
+	//socketURL = "wss://192.168.11.242:9104";
+
+	
+    var jmuxer = new JMuxer({
+        node: 'player',
+		flushingTime:15 ,
+        fps: 30,
+		mode:'video',
+        debug: false
+     });
+	 
+	 var audioMuxer = new JMuxer({
+        node: 'audioPlayer',
+		flushingTime:15,
+		clearBuffer: true,
+        fps: 60,//可以不选,原先43
+		mode:'audio',
+        debug: false
+     });
+		 
+	 curTime = new Date().getTime();	
+     var ws = new WebSocket(socketURL);
+     ws.binaryType = 'arraybuffer';
+	  
+	 //断开检测
+	 ws.onclose = function (e) {
+                alert("websocket连接断开");
+				console.log('websocket 断开: ' + e.code + ' ' + e.reason + ' ' + e.wasClean);
+				console.log(e);
+            }
+							
+	ws.addEventListener('open', function (event) {
+		console.log("发送配置帧");
+		ws.send(ConfigChannel("RK3923C1201900139"));
+	});
+	
+	ws.addEventListener('error', function (event) {
+		console.log("连接失败");
+	});
+	
+     ws.addEventListener('message',function(event) {
+		  var data = ParseProto(event.data);//JAVA服务器转发
+		  //console.log("收到数据");
+					
+		  var audioData = {
+			audio: data.audio,
+			video: null,
+			duration: data.duration
+		  };
+		  
+		  var videoData = {
+			audio: null,
+			video: data.video,
+			duration: data.duration
+		  };	  
+		 	 		
+		  if(myAudio.readyState == 2)
+		  {
+			requestTime = new Date().getTime();
+			isEnough = false;
+			console.log("数据存储不够,出现声音停止,时间差 %f", myAudio.buffered.end(0));
+			myAudio.pause();
+			//myAudio.playbackRate = 2;
+		  }
+		  else if(myAudio.readyState == 4 && isEnough== false)
+		  {
+				myAudio.play();
+				var time = new Date().getTime();
+				isEnough = true;
+				console.log("填满耗时 %d ms, 填充帧数 %d, 填充延迟 %d ms", time - requestTime, requestCount, requestCount * 23);
+			
+				console.log("----接收到启动 %d ms, 缓冲区 %f---", time - delayTime, myAudio.buffered.end(0) - myAudio.played.end(0));
+		  }
+		  
+		  if(data.audio != null)//喂音频
+		  {							
+			if(myAudio.buffered.length > 0 &&  myAudio.played.length > 0)
+			{
+				var bufferTime = myAudio.buffered.end(0) - myAudio.played.end(0);								
+				//console.log(" bufferTime %d", bufferTime);
+				
+				if(bufferTime > 1)
+				{
+					//console.log("丢掉一些包");
+					//return;
+				}
+			}
+			
+			audioMuxer.feed(audioData);			
+		  }		  
+		  
+		  if(data.video != null)//喂视频
+		  {
+			 if(isFeed)
+			 {
+				jmuxer.feed(data);
+			 }
+			 
+			 //jmuxer.feed(videoData);
+		  }
+		   	 	 	 	  
+     });
+	 
+	
+	myVideo.onmousedown = function(event)
+    {
+		//放在此处只是为了方便演示,实际使用中查找横竖屏只要刚连接上时调用一次就好。	
+		//var checkBuffer = GetScreenState();
+		//ws.send(checkBuffer);
+
+		if(!isFeed)
+		{
+			console.log("重新申请I帧");
+			requestTime = new Date().getTime();			
+			var buffer = RequestIFrame();
+			//var buffer = new Uint8Array([0x01]);
+			ws.send(buffer);
+		}
+		
+		//console.log("报文 %s", PrintArry(buffer));
+		
+	
+		if(event.button == 0)
+		{
+			var posX = event.offsetX * 1080 *1.0/myVideo.clientWidth;
+			var posY = event.offsetY * 1920 *1.0/myVideo.clientHeight;
+			var buffer = ExexuteMouseDown(posX.toString(), posY.toString());
+			ws.send(buffer);
+			isDrag = true;
+		}
+			
+    }
+	
+	
+	myVideo.onmousemove = function(event)
+	{
+		if(isDrag && event.button == 0)
+		{
+			var posX = event.offsetX * 1080 *1.0/myVideo.clientWidth;
+			var posY = event.offsetY * 1920 *1.0/myVideo.clientHeight;
+			var buffer = ExexuteMouseMove(posX.toString(), posY.toString());
+			ws.send(buffer);
+			//console.log("移动位置 %d, %d", posX, posY);
+		}
+		
+	}
+	
+	myVideo.onmouseup = function(event)
+	{	
+		isDrag = false;
+		var posX = event.offsetX * 1080 *1.0/myVideo.clientWidth;
+		var posY = event.offsetY * 1920 *1.0/myVideo.clientHeight;
+		var buffer = ExexuteMouseUp(posX.toString(), posY.toString());
+		ws.send(buffer);
+		
+	}
+	
+	myVideo.onkeydown = function(event)
+	{	
+		ExexuteKeyDown(e.keyCode);
+	}
+	
+ }  
+
+function Back()
+{	
+	if(event.button == 2)
+	{
+		//ExexuteKeyDown(4);
+	}
+	ExexuteKeyDown(4);
+	window.event.returnValue=false;  
+    return false;  
+}
+ 
+</script>
+<script type="text/javascript" src="jmuxer.js"></script>
+<!--<script type="text/javascript" src="aac.js"></script>-->
+
+</body>
+</html>

文件差異過大導致無法顯示
+ 2566 - 0
screenAndroid/jmuxer.js


文件差異過大導致無法顯示
+ 2563 - 0
screenAndroid/jmuxer.min.js


+ 3 - 0
screenAndroid/package-lock.json

@@ -0,0 +1,3 @@
+{
+  "lockfileVersion": 1
+}

+ 173 - 0
screenAndroid/temp.html

@@ -0,0 +1,173 @@
+
+
+
+
+
+
+
+
+<!DOCTYPE html>
+
+
+
+
+<html>
+<head>
+	<meta charset="utf-8"> 
+	<title>AAC &mdash; Audiocogs</title>
+	<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
+
+	<link rel="stylesheet" type="text/css" href="/css/all.min.css">
+	<link rel="shortcut icon" href="/favicon.ico">
+	<!--[if lt IE 9]>
+	<script src="/scripts/html5shiv.js"></script>
+	<![endif]-->
+
+	<link rel="alternate" type="application/rss+xml" title="Audiocogs Blog" href="/rss.xml">
+</head>
+<body class="codec">
+<section>
+	<header class="main">
+		<div class="inner">
+		<h1>
+			<div id="name">
+				<a href="/">Audiocogs</a>
+			</div>
+			<div id="social">
+				<a href="http://twitter.com/audiocogs"><img id="twitterbird" class="twitter" width="30" height="30" src="/images/white-twitter.png" alt="Audiocogs on twitter."></a>
+				<a href="https://github.com/audiocogs"><img id="white-octocat" class="github" width="30" height="30" src="/images/white-octocat.png" alt="Audiocogs on github."></a>
+			</div>
+		</h1>
+		</div>
+	</header>
+	<section id="content">
+		<div class="title-nav">
+			<ul>
+
+        <li><a href="/codecs">Codecs</a></li>
+
+        <li><a href="/codecs/mp3">MP3</a></li>
+        <li><a href="/codecs/alac">ALAC</a></li>
+        <li><a href="/codecs/flac">FLAC</a></li>
+        <li><a href="/codecs/aac">AAC</a></li>
+
+			</ul>
+		</div>
+
+		<article>
+			<header>
+				
+				<h1 id="article_title">AAC</h1>
+				
+				
+			</header>
+
+
+<link rel="stylesheet" href="/dgplayer/player.css" />
+
+<script src="/dgplayer/resources/classlist.js"></script>
+<script>
+var unsupported;
+if (!window.Audio || !('mozWriteAudio' in new Audio()) && !window.AudioContext && !window.webkitAudioContext) {
+    unsupported = true;
+    document.body.classList.add("unsupported");
+}
+</script>
+<div id="unsupported">
+We're really sorry about this, but it looks like your browser doesn't support an Audio API. Please
+try these demos in Chrome 15+ or Firefox 8+ or watch a <a href="http://vimeo.com/33919455">screencast</a>.
+</div>
+
+
+<p>Advanced Audio Coding (AAC) is a standardized, high quality lossy audio codec, designed as the successor to the MP3 format. AAC is now one of the most widely deployed audio codecs, and such names as the iTunes Store distribute music in the AAC format.</p>
+
+<p>AAC can be played in a limited number of browsers using the HTML5 audio element, however, some browsers do not support the codec for various reasons. <a href="https://github.com/ofmlabs/aac.js">AAC.js</a> is a JavaScript AAC decoder that enables decoding and playback of AAC files in all browsers supported by the <a href="https://github.com/ofmlabs/aurora.js">Aurora.js</a> audio framework.</p>
+
+
+<script src="/dgplayer/player.js"></script>
+<script src="/codecs/js/auroraplayer.js"></script>
+
+<div class="player" id="dgplayer" tabindex="0">
+    <div class="avatar">
+        <img src="/dgplayer/resources/fallback_album_art.png">
+    </div>
+
+    <span class="title">Unknown Title</span>
+    <span class="artist">Unknown Artist</span>
+
+    <div class="button"></div>
+
+    <div class="volume">
+        <img src="/dgplayer/resources/volume_high.png">
+        <div class="track">
+            <div class="progress"></div>
+            <div class="handle"></div>
+        </div>
+        <img src="/dgplayer/resources/volume_low.png">
+    </div>
+
+    <div class="seek">
+        <span>0:00</span>
+        <div class="track">
+            <div class="loaded"></div>
+            <div class="progress"></div>
+        </div>
+        <span>-0:00</span>
+    </div>
+    
+    <div class="file_button"></div>
+    <span class="file_description">Choose an AAC file on your computer</span>
+</div>
+
+<script src="/codecs/js/aurora.js"></script>
+<script src="/codecs/js/aac.js"></script>
+
+<script type="text/javascript">
+// Chrome doesn't support changing the sample rate, and uses whatever the hardware supports.
+// We cheat here.  Instead of resampling on the fly, we're currently just loading two different
+// files based on common hardware sample rates.
+var _sampleRate = (function() {
+    var AudioContext = (window.AudioContext || window.webkitAudioContext);
+    if (!AudioContext)
+        return 44100;
+    
+    return new AudioContext().sampleRate;
+}());
+
+(function(DGPlayer){
+    if (unsupported) return;
+    
+    DGPlayer.volume = 100;
+    
+    var player, onplay;
+    var url = '';
+    
+    DGPlayer.on('play', onplay = function(){
+        if (player)
+            player.disconnect();
+            
+        player = new DGAuroraPlayer(AV.Player.fromURL(url), DGPlayer);
+        DGPlayer.off('play', onplay);
+    });
+    
+    DGPlayer.on('file', function(file) {        
+        if (file) {
+            if (player)
+                player.disconnect();
+                
+            player = new DGAuroraPlayer(AV.Player.fromFile(file), DGPlayer);
+            DGPlayer.off('play', onplay);
+        }
+    });
+    
+}(DGPlayer(document.getElementById('dgplayer'))));
+</script>
+
+
+		</article>
+
+	</section>
+</section>
+</body>
+</html>
+

+ 48 - 1
screenIos/homeNew.html

@@ -185,6 +185,52 @@
 			var html = document.querySelector("html");
 			var clientWidth = html.getBoundingClientRect().width;
 			html.style.fontSize = clientWidth / 23.4375 + "px";
+
+			// var player = new PCMPlayer({
+			// 	encoding: '16bitInt',
+			// 	channels: 2,
+			// 	sampleRate: 44100,
+			// 	flushingTime: 22,
+			// 	debug: false
+			// });
+
+			// Module = {};
+			// Module.onRuntimeInitialized = function() {
+			// 	console.log("Wasm 加载成功!")
+			// 	isFinish = true;
+			// }
+
+			// function closeDecoder() //关闭解码器
+			// {
+			// 	Module._destroyDecoder();
+			// }
+
+			// function decodeAAC(data) {
+			// 	var retPtr = Module._malloc(4 * 5 * 1024); //接收的数据
+			// 	var inputPtr = Module._malloc(4 * data.length); //输入数据
+
+			// 	for (i = 0; i < data.length; i++) {
+			// 		Module.HEAPU8[(inputPtr) + i] = data[i]; //转换为堆数据
+			// 	}
+
+			// 	var pcmLen = Module._feedData(retPtr, inputPtr, data.length);
+
+			// 	if (pcmLen >= 0) {
+			// 		//console.log("%d帧 aac 解码成功, %d", decodeCount, pcmLen);
+			// 		var pcmData = new Uint8Array(pcmLen);
+			// 		for (i = 0; i < pcmLen; i++) {
+			// 			pcmData[i] = Module.HEAPU8[(retPtr) + i]
+			// 		}
+
+			// 		player.feed(pcmData);
+			// 	} else {
+			// 		console.log("%d帧 aac 解码失败, %d", decodeCount, pcmLen);
+			// 	}
+
+			// 	decodeCount++;
+			// 	Module._free(inputPtr);
+			// 	Module._free(retPtr);
+			// }
 			var app = new Vue({
 				el: '#homeapp',
 				data: {
@@ -254,6 +300,7 @@
 					});
 
 
+
 				},
 				methods: {
 					homeinfo(data) {
@@ -748,8 +795,8 @@
 										// client.onerror = function(evt) {
 										// 	// onError(evt) 
 										// };
-									}, 1)
 
+									}, 1)
 
 								} else {
 

文件差異過大導致無法顯示
+ 1 - 0
screenIos/pcm-player.min.js


+ 10 - 3
screenIos/websocket.js

@@ -1,7 +1,12 @@
-self.importScripts("helper.js");
-// var socketURL = "ws://192.168.11.66:9101";
-var socketURL = "ws://14.215.128.98:14102"
+self.importScripts("helper.js");  
+// self.importScripts("pcm-player.js");
+// self.importScripts("pcm-player.min.js");   
+var socketURL = "ws://192.168.11.66:9101";
+// var socketURL = "ws://14.215.128.98:14102"
 // socketURL = "ws://127.0.0.1:8081"
+
+
+
 var ws = new WebSocket(socketURL);
 ws.binaryType = 'arraybuffer';
 
@@ -16,6 +21,8 @@ ws.addEventListener('message', function(event) {
 	var input = new Uint8Array(event.data);
 
 	if (input[0] == 0xff) {
+		console.log("1111111")
+		decodeAAC(input);
 
 	} else {
 		self.postMessage(input);