网页中播放RTSP(4) WebSocket学习

 

1.一般通信

参考:C#版Websocket实例

用WPF实现了一下服务端,和一般的TCP通信一样。

最早以前实现过Unity(Webgl平台)里面用WebSocket连接C#的TCP服务端的功能。

网页中的WebSocket是浏览器本身支持的功能。

本来担心cors问题,结果发现:“webSocket本身不存在跨域问题,所以我们可以利用webSocket来进行非同源之间的通信。”

Unity里面的WebSocket直接使用BestHttp插件里面的场景测试。

打包到网页(webgl)中也没问题。

发现有个socket.io:

socket.io是对websocket的分装。因为不是所有的浏览器都可以支持websocket。如果浏览器支持websocket,那么socket.io就等同于websocket。socket.io还用到了其它的技术来模拟websocket,所以当你是用socket.io的时候,不管浏览器是否支持websocket,你都可以实现异步操作。当然如果你的客户端是用了socket.io,server端也必须对应使用。

 

2.获取图片、视频

H5Stream里面的ws的地址:

ws://localhost:8085/api/v1/h5swsapi?token=token1&profile=main&session=c1782caf-b670-42d8-ba90-2244d0b0ee83

用该地址在上面的网页中测试,结果:

收到一串的object Blob对象(evt.data)。

改造上面的简单发送字符串的服务端,添加发送图片和视频,本质上都是发送byte[]。

发现,发送的bytes内容不会被分开,发送、接收都是一个块。

接收图片,参考:Image Transmission between a HTML5 WebSocket Server and a Web Client

function drawImage(data){
            var imageWidth = 883, imageHeight = 549; // hardcoded width & height. 
            var byteArray = new Uint8Array(data);
            
            var canvas = document.createElement('canvas');
            canvas.height = imageWidth;
            canvas.width = imageHeight;
            var ctx = canvas.getContext('2d');
            
            var imageData = ctx.getImageData(0, 0, imageWidth, imageHeight); // total size: imageWidth * imageHeight * 4; color format BGRA
            var dataLen = imageData.data.length;
            for (var i = 0; i < dataLen; i++)
            {
                imageData.data[i] = byteArray[i];
            }
            ctx.putImageData(imageData, 0, 0);
            
            // create a new element and add it to div
            var image = document.createElement('img');
            image.width = imageWidth;
            image.height = imageHeight;
            image.src = canvas.toDataURL();
            
            var div = document.getElementById('imgDev1');
            div.appendChild(image);
        }

1.获取数据大小

使用上面参考的代码,不行

var byteArray = new Uint8Array(evt.data);

length=byteArray.length;

这个length是0。????

在其他地方(https://oomake.com/question/3732628)看到个data.size,再打印一下,发现evt.data就是个Blob对象。

2.读取Blob内容

参考:https://stackoverflow.com/questions/21338263/how-to-read-blob-data-from-a-websocket-which-is-not-an-image

 if(data instanceof Blob){ //[object Blob]
                    length=data.size;
                    var reader = new FileReader();
                    reader.onload = () => {
                        console.log("Result length: " + reader.result.length);
                        console.log("Result content: " + reader.result);
                    };
                    reader.readAsText(data);
                }

通过FileReader的readAsText()读取,能够看出这是一个png图片和一个H.264视频文件。

改为前面的H5Stream的ws地址,结果

前面3次收到的数据量都是31,24,723,第4次是6w多,后面都是1w多。

改成readAsArrayBuffer

if(data instanceof Blob){ //[object Blob]
                    length=data.size;
                    var reader = new FileReader();
                    reader.onload = () => {
                        console.log(reader);
                        console.log(reader.result);
                        console.log("Result length: " + reader.result.byteLength);
                        console.log("Result content: " + reader.result);
                        console.log(reader.result[0]);//读不出来
                        var byteArray = new Uint8Array(reader.result);
                        console.log(byteArray);
                        console.log(byteArray[0]);

                        //drawImage(reader.result);//转换成图像
                    };
                    reader.readAsArrayBuffer(data);
                    //reader.readAsArrayBuffer(data);
                }

3.转换图片

经过FileReader.readAsArrayBuffer能够和上面的drawImage接上了,但是,结果不如意。

本来怀疑是长宽和图片一样,结果还是不行。总之,这个作者(Image Transmission between a HTML5 WebSocket Server and a Web Client)写的代码可能有问题,可能以前那时是可以的吧。

用他评论里面的代码测试了一下,可以

function drawImage(data){
            var bytes = new Uint8Array(data);
            var binary= "";
            var len = bytes.byteLength;
            for (var i = 0; i < len; i++) {
            binary += String.fromCharCode( bytes[ i ] )
            }
            var img = document.getElementById("img1");
            img.src = "https://img-blog.csdnimg.cn/2022010705184285717.png"+window.btoa( binary );//png,jpg都没有关系
        }
<body>
    <form id="sendForm">
        <input id="sendText" placeholder="Text to send" />
    </form>
    <pre id="incomming"></pre>
    <div>
        <div id="imgDev1"></div>
    </div>
     <img src="" id="img1"/>
    
</body>

另外查到一段代码

<img src="" id="img"/>
<script>
    ws = new WebSocket("ws://192.168.0.171:1235");
    ws.onopen = function () {
        alert("连接成功");
        ws.send('tom');
        alert("给服务端发送一个字符串:tom");
    }
    ws.onmessage = function (e) {
        document.getElementById('img').src = 'data:image/gif;'+e.data;
    }
</script>

结果不行

我的代码是

ws.onmessage = function (evt) {
                count=count+1;
                if(count>10){
                    console.log('close!!:'+count);
                    ws.close();
                }
                //console.log(evt);
                var data=evt.data;
                console.log(data);
                var length=data.length;
                if(data instanceof Blob){ //[object Blob]
                    length=data.size;
                    document.getElementById('img1').src = 'data:image/png;'+data;
                }
                inc.innerHTML += "receive:"+data 
                +'   type:'+typeof(data)
                +'   length:'+length
                + '<br/>';
            };

整理一下,下面的代码就行一个下午的成果。学习以一下websocket,从Blob中读取图片。

ws.onmessage = function (evt) {
                count=count+1;
                if(count>10){
                    console.log('close!!:'+count);
                    ws.close();
                }
                //console.log(evt);
                var data=evt.data;
                console.log(data);
                var length=data.length;
                if(data instanceof Blob){ //[object Blob]
                    length=data.size;
                    loadImage('img1',data);
                }
                inc.innerHTML += "receive:"+data 
                +'   type:'+typeof(data)
                +'   length:'+length
                + '<br/>';
            };
        function getImageString(arrayBuffer){
            var bytes = new Uint8Array(arrayBuffer);
            var binary= "";
            var len = bytes.byteLength;
            for (var i = 0; i < len; i++) {
            binary += String.fromCharCode( bytes[ i ] )
            }
            var src="https://img-blog.csdnimg.cn/2022010705184285717.png"+window.btoa( binary );//png,jpg都没有关系
            return src;
        }

        function loadImage(imgId,data){
            var reader = new FileReader();
            reader.onload = () => {
                var img = document.getElementById(imgId);
                img.src = getImageString(reader.result);
            };
            reader.readAsArrayBuffer(data);
        }

-----------------------------------------------------------------------------------------

前面的Image Transmission between a HTML5 WebSocket Server and a Web Client没看仔细,少了一段代码

ws.binaryType = "arraybuffer";

改一下,兼容设置和不设置binaryType。

//To receive the image as ArrayBuffer on the client side, you have to specify the binaryType after creating a WebSocket:
            ws.binaryType = "arraybuffer";//有了这个,就不用FileReader读取Blob的内容了。
            // when data is comming from the server, this metod is called
            ws.onmessage = function (evt) {
                count=count+1;
                if(count>10){
                    console.log('close!!:'+count);
                    ws.close();
                }
                //console.log(evt);
                var data=evt.data;
                console.log(data);
                var length=data.length;
                if(data instanceof Blob){ //[object Blob]
                    length=data.size;
                    loadImage('img1',data);
                } else if(data instanceof ArrayBuffer){ //加上ws.binaryType = "arraybuffer";
                    length=data.byteLength;
                    var img = document.getElementById('img1');
                    img.src = getImageString(data);
                }
                inc.innerHTML += "receive:"+data 
                +'   type:'+typeof(data)
                +'   length:'+length
                + '<br/>';
            };

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值