需求: 使用websocket在网页上展示实时视频流
最近发现有的网站上,显示的视频流很丝滑,而且在多路情况下不会出现页面卡死。 总结了一下所使用的技术。
之前的处理
后端推消息,把数据转为json字符串,通过websocket推给前端, 图片使用base64编码
{
"channel": "camera_1",
"url": "data:image/png;base64,iV"
}
前端接收到数据后,解码,使用img 标签展示 图片base64
优化处理
客户端的传输方式改为 ArrayBuffer方式。将channel、图片文件流等信息拼接为二进制数据。 通过websocket推送给前端
举例:
channel频道: camera_1 占两个字节;
图片: file文件流 占128字节
字节顺序 Little-endian
前端读取为ArrayBuffer, 通过视图操作,取出图片的二进制流,生成Blob对象
读取blob对象, 返回 URL格式的字符串(base64编码)以表示所读取文件的内容
前端img 标签 src 赋值为 base64 字符串,显示视频流图片。
优点:
- 将二进制数据转成Base64编码,再进行处理。 不仅速度慢,而且容易出错。 Blob对象,允许直接操作二进制数据。
- javaScript 通信的时有大量的实时的数据交互,用文本格式需要进行格式转化,二进制则省去转化时间
- 前端ArrayBuffer 分配一段可以存放数据的连续内存区域,有垃圾回收机制。ArrayBuffer对象代表储存二进制数据的一段内存,它不能直接读写,只能通过视图DataView进行操作。
优化了客户端浏览器性能,防止出现页面卡死的情况。 - ArrayBuffer的创建速度几乎是Array的四倍以上;读操作快了一倍。另外IE相比Chrome简直慢成鬼了。看来不同配置,不同浏览器差别还是非常大的
- 二进制相比base64, 数据大小减小了 三分之一。 img标签则会找到相应的内存地址,直接读取数据并将图像显示到页面中。