You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

浏览器中高效渲染MJPEG流的最优实现方案问询

浏览器中高效渲染MJPEG流的最优实现方案问询

我现在的应用可以高效地渲染多组MP4(H.264格式)的摄像头流(并排显示),核心是通过给video元素喂分片MP4的方式实现的。

现在我要给老旧IP摄像头添加MJPEG支持——这些设备没法输出H.264,但浏览器渲染MJPEG的开销比预期高很多,我正在找最极致的高效实现方式。

当前的测试方案

后端(Node.js,通过子进程实现)

我用FFmpeg拉取MJPEG-RTSP流,只保留MJPEG流本身,把其他所有通道(数据/字幕、音频)都静音/禁用了。然后通过Socket.IO把输出推出去:

const IOptions = {
    path: '/streams/' + cameraID
}

数据处理的逻辑是:

Spawned.stdio[x].on('data', function (data) {
    let frame = Buffer.from(data).toString('base64')
    socket.emit('canvas', frame)
})

前端

目前我是创建新的Image对象,然后绘制到Canvas上:

let socket = io('/', { path: '/streams/camtitle' })
socket.on('canvas', function (data) {
    try {
        const canvas = document.getElementById('mjpegCanvas')
        const context = canvas.getContext('2d')
        const imageObj = new Image()
        imageObj.src = "data:image/jpeg;base64," + data
        imageObj.onload = function () {
            context.height = imageObj.height
            context.width = imageObj.width
            context.drawImage(imageObj, 0, 0, context.width, context.height)
        }
    } catch (e) { console.log('Canvas Drawing Error:' + e) }
})

遇到的性能问题

这个方案在VGA分辨率(640x480,低帧率)下,客户端的CPU核心负载在8%到29%之间波动,但用户肯定会期望更高分辨率和帧率的支持,所以这个性能表现不够理想。

我查了5天相关资料,看到资深开发者提到:在JavaScript里频繁创建对象的开销很大,还可能触发频繁的垃圾回收,这可能是性能瓶颈之一。

我的疑问

  • 有没有更好的方式处理或者复用Image对象?我以为自己已经在复用const imageObj了,但会不会背后还有额外的开销?
  • 我在Stack Overflow上看到有人直接用img标签渲染MJPEG流,写法类似:
<img src="http://[some ip]:[port]/mjpg"> 

还有人直接把img的src指向一个.jpg结尾的路由。但这两种方式对我当前的MJPEG流都不起作用,我也搞不懂这种方式是怎么工作的——难道不需要拆分帧或者处理分隔符吗?我想测试这种方案做性能对比,但不清楚问题出在哪。

我自己的优化思路

我正在后端实现一个帧差分测试功能:只发送像素变化量达到一定阈值的帧,想看看这种方式能降低多少客户端开销,但不确定后端的计算成本会不会太高。

求建议

非常希望得到任何优化建议,或者指向正确方向的实用资源。优先考虑原生JavaScript实现(不用库和模块),但其他方案也可以考虑。服务器端的修改建议也完全接受——目前所有实现都还在实验阶段。

备注:内容来源于stack exchange,提问作者IoT-Practitioner

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.14 11:18:03