WebRtc 视频流卡顿黑屏解决方案

发布于:2025-04-10 ⋅ 阅读:(38) ⋅ 点赞:(0)

 

// node webrtc视频转码服务
const url = "http://10.169.xx.xx:8000"
<video :ref="`videoRefs${index}`" :id="`videoRefs4_${index}`" :src="item" controls
                                    :key="item" autoplay muted @click="preventDefaultClick"
                                    v-for="(item, index) in streams"></video>
watch(() => props.doorMachineInfo,
    (newVal) => {
        nextTick(() => {
            if (Object.keys(newVal).length !== 0) {
                allDataInfo.value = newVal
                // console.log("子组件收到数据", allDataInfo.value)
                // 渲染实时监控webrtc
                if (allDataInfo.value.videoUrllist && allDataInfo.value.videoUrllist.length > 0) {
                    streams.value = allDataInfo.value.videoUrllist;
                    // streams.value = ["rtsp://10.172.1.2:16015/detect"];
                    setTimeout(() => {
                        streams.value?.forEach((stream, index) => {
                            const videoElement = proxy.$refs[`videoRefs${index}`][0]; // 通过 ref 获取视频元素
                            const webRtcServer = new WebRtcStreamer(videoElement, url);
                            const option = "rtptransport=tcp";
                            webRtcServer.connect(stream, null, option, null);
                            webRtcServers.value.push(webRtcServer); // 存储 WebRtcStreamer 实例
                        });
                    }, 1500)
                }
                // 回显摄像头下拉
                if (allDataInfo.value.cameraList && allDataInfo.value.cameraList.length > 0) {
                    camera.value = allDataInfo.value.cameraList[0].serialNumber;
                    // 门机对位监控webrtc
                    streams2.value = allDataInfo.value.cameraList[0].rtspVideoUrl;
                    const videoElement2 = proxy.$refs.videoRefs; // 通过 ref 获取视频元素 
                    const webRtcServer2 = new WebRtcStreamer(videoElement2, url);
                    webRtcServer2.connect(streams2.value);
                    webRtcServers2.value = webRtcServer2; // 存储 WebRtcStreamer 实例
                }
            } else {
                allDataInfo.value = {}
            }
        });
    }, { deep: true, immediate: true });

 rtptransport=tcp 的作用

rtptransport=tcp 是 RTSP 协议中的一种传输方式选项,用于指定视频流的传输协议。RTSP 支持两种主要的传输方式:UDP 和 TCP。通过设置 rtptransport=tcp,可以强制 RTSP 使用 TCP 作为底层传输协议。

1. RTSP 的两种传输方式
  • UDP(User Datagram Protocol)
    • 默认情况下,RTSP 使用 UDP 传输 RTP 数据包。
    • 优点:低延迟、适合实时性要求高的场景。
    • 缺点:UDP 是无连接的协议,可能会导致数据包丢失或乱序,尤其是在网络质量较差的情况下。
  • TCP(Transmission Control Protocol)
    • 当使用 rtptransport=tcp 时,RTSP 会通过 TCP 传输 RTP 数据包。
    • 优点:可靠性高,不会丢包或乱序,适合网络环境较差的场景。
    • 缺点:相比 UDP,TCP 的延迟较高,可能会影响实时性。
2. 为什么需要 rtptransport=tcp

在某些网络环境中,UDP 可能会出现以下问题:

  • 防火墙或 NAT 限制:许多防火墙默认会阻止 UDP 流量,而允许 TCP 流量。
  • 丢包或乱序:在不稳定或高延迟的网络中,UDP 数据包容易丢失或乱序,导致视频卡顿或无法播放。
  • 端口冲突:UDP 需要动态分配端口,可能会与网络中的其他服务发生冲突。

通过设置 rtptransport=tcp,可以避免上述问题,确保视频流能够稳定传输。

3. 代码中的作用

代码中:

javascript

const option = "rtptransport=tcp"; webRtcServer.connect(stream, null, option, null);

这段代码的作用是告诉 WebRtcStreamer 使用 TCP 而不是默认的 UDP 来传输 RTSP 视频流。这通常是为了提高视频流在网络环境较差情况下的稳定性。

4. 实际应用场景
  • 网络环境较差:当用户所在的网络环境不稳定(如高延迟、高丢包率)时,使用 TCP 可以减少视频卡顿。
  • 防火墙限制:如果用户的网络中有防火墙阻止了 UDP 流量,使用 TCP 可以绕过这些限制。
  • 移动网络:在移动网络环境下,TCP 的可靠性更高,适合视频监控等场景。
5. 注意事项
  • 延迟问题:由于 TCP 的可靠性和重传机制,可能会引入额外的延迟。如果你的应用对实时性要求非常高(如直播),需要权衡是否使用 TCP。
  • 服务器支持:确保 RTSP 服务器支持 rtptransport=tcp,否则可能会导致连接失败。
6. 总结

rtptransport=tcp 是为了在 RTSP 协议中强制使用 TCP 作为传输协议,从而提高视频流在网络环境较差或存在防火墙限制时的稳定性。在你的代码中,这一设置可以帮助解决因网络问题导致的视频卡顿或无法播放的问题。