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

使用RTSPtoWeb+WebRTC无法同时接收监控摄像头音视频求助

解决RTSPtoWeb WebRTC无法同时接收音视频的问题

核心修复点

  • 不要每次收到轨道就替换video.srcObject,而是将所有音视频轨道合并到同一个MediaStream中
  • 确保同时添加音频和视频收发器

修改后的完整代码

<!doctype html>
<html>
<head>
    <title>Camera Monitor</title>
</head>
<body>
    <script>
        // Create video element
        const video = document.createElement('video')
        video.id = 'camera_video'
        video.style = 'max-width:100%; max-height:100%'
        video.muted = false  // 取消静音以便测试音频
        video.controls = true
        document.body.appendChild(video)

        document.addEventListener('DOMContentLoaded', () => {
            function startPlay(video, url) {
                const connection = new RTCPeerConnection({ sdpSemantics: 'unified-plan' })
                // 同时添加音频和视频收发器
                connection.addTransceiver('video', { direction: 'recvonly' })
                connection.addTransceiver('audio', { direction: 'recvonly' })
                const channel = connection.createDataChannel('RTSPtoWeb')

                // 初始化一个空的MediaStream用于合并音视频轨道
                const mediaStream = new MediaStream()
                video.srcObject = mediaStream

                connection.ontrack = e => {
                    console.log(`Received track: ${e.track.kind}`)
                    // 将收到的轨道添加到统一的MediaStream中
                    mediaStream.addTrack(e.track)
                    // 第一次收到轨道时自动播放
                    if (!video.paused) return
                    video.play().catch(err => console.error('Play failed:', err))
                }

                connection.onnegotiationneeded = async () => {
                    const offer = await connection.createOffer()
                    await connection.setLocalDescription(offer)
                    fetch(url, {
                        method: 'POST',
                        body: new URLSearchParams({ data: btoa(connection.localDescription.sdp) })
                    })
                    .then(response => response.text())
                    .then(data => {
                        try {
                            connection.setRemoteDescription(
                                new RTCSessionDescription({ type: 'answer', sdp: atob(data) })
                            )
                        } catch (e) {
                            console.warn(e)
                        }
                    })
                }

                channel.onopen = () => {
                    console.log(`${channel.label} data channel opened`)
                }

                channel.onclose = () => {
                    console.log(`${channel.label} data channel closed`)
                    startPlay(video, url)
                }

                channel.onmessage = e => console.log(e.data)
            }

            const video = document.querySelector('#camera_video')
            const url = 'http://<ip_address>:8083/stream/camera/channel/0/webrtc'
            startPlay(video, url)
        })
    </script>
</body>
</html>

额外检查项

  1. 确认RTSPtoWeb配置:检查你的RTSPtoWeb配置文件(通常是config.json),确保对应摄像头的流配置中开启了音频转发,例如:
"streams": {
    "camera": {
        "url": "rtsp://your_camera_rtsp_url",
        "audio": true,  // 确保这个值为true
        "video": true
    }
}
  1. 浏览器兼容性:确保使用支持Unified Plan SDP的现代浏览器(Chrome、Firefox、Edge等),Unified Plan是同时传输多轨道的标准。

问题原因解释

之前的代码中,每次ontrack事件触发时都会将video.srcObject设置为当前收到的流。如果先收到视频流,后续收到音频流时会替换成仅含音频的流;反之则替换成仅含视频的流。通过将所有轨道合并到同一个MediaStream,可以保证音视频轨道同时存在于视频元素的源对象中,从而实现同步播放。

内容的提问来源于stack exchange,提问作者ragnarok

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 17:15:19