Uncaught (in promise) DOMException: The play() request was interrupted by a new

一、异常错误

WebRTC 是一种用于实时通信的开放式标准,可以让您通过浏览器进行视频和音频通信。使用 WebRTC 技术可以让您实现低延迟的视频通信,从而解决摄像头延迟的问题。

在使用 HTML5 音频或视频时,有时会遇到 DOMException 错误,错误信息为 The play() request was interrupted by a new load request. 这个错误通常发生在当你试图在一个媒体文件正在加载的时候播放另一个媒体文件时。

html 复制代码
mse-controller.js:110 Uncaught (in promise) DOMException: The play() request was interrupted by a new load request.

二、原因

解决这个问题的方法很简单,只需要在播放新的媒体文件之前,先停止当前正在播放的媒体文件,等待当前正在加载的媒体文件加载完成,再播放新的媒体文件即可。

另外,在刷新摄像头请求时,如果没有清理旧的定时器,会导致多个定时器同时在运行,最终导致页面卡住。为了解决这个问题,可以将定时器的 ID 存储在一个全局变量中,然后在每次刷新请求时,先清理旧的定时器,再创建新的定时器。

改变之前的代码如下:

java 复制代码
function register() {
        $.ajax({
            url: '/dev-api/system/config/configKey/camera.request.ip',
            beforeSend: function (request) {
                request.setRequestHeader("Authorization", "Bearer " + getCookie("Admin-Token"));
            },
            success: (res) => {
                console.log(res);
                $.ajax({
                    url: `http://${res.msg}:800/index/api/addStreamProxy`,
                    data: {
                        "secret": `035c73f7-bb6b-4889-a715-d9eb2d1925cc`,
                        "vhost": `${res.msg}`,
                        "app": "live",
                        "stream": getParams("orderNum"),
                        "url": "rtsp://admin:" + `${getParams("password")}@${getParams("ip")}`
                    },
                });
                start(res.msg)
            }
        });
    }
    function start(configIP) {
        if (flvjs.isSupported()) {
            var videoElement = document.getElementById('videoElement');
            var flvPlayer = flvjs.createPlayer({
                type: 'flv',
                url: `http://${configIP}:800/live/${getParams("orderNum")}.flv`
            });
            flvPlayer.attachMediaElement(videoElement);
            flvPlayer.load();
            flvPlayer.play();

            setInterval(() => {
                // 停止播放
                flvPlayer.unload();
                flvPlayer.detachMediaElement();
                // 重新播放
                start(configIP)
            }, 5000);
        }
    }

三、解决方法

优化后的代码如下,在代码中,我们定义了一个全局变量 timerId,用来存储定时器的 ID。在每次刷新请求时,我们先清理旧的定时器,然后再创建新的定时器。这样就可以避免多个定时器同时在运行导致页面卡顿的问题。

java 复制代码
var timerId; // 全局变量,存储定时器ID

function register() {
    $.ajax({
        url: '/dev-api/system/config/configKey/camera.request.ip',
        beforeSend: function (request) {
            request.setRequestHeader("Authorization", "Bearer " + getCookie("Admin-Token"));
        },
        success: (res) => {
            console.log(res);
            $.ajax({
                url: `http://${res.msg}:800/index/api/addStreamProxy`,
                data: {
                    "secret": `035c73f7-bb6b-4889-a715-d9eb2d1925cc`,
                    "vhost": `${res.msg}`,
                    "app": "live",
                    "stream": getParams("orderNum"),
                    "url": "rtsp://admin:" + `${getParams("password")}@${getParams("ip")}`
                },
            });
            start(res.msg)
        }
    });
}

function start(configIP) {
    if (flvjs.isSupported()) {
        var videoElement = document.getElementById('videoElement');
        var flvPlayer = flvjs.createPlayer({
            type: 'flv',
            url: `http://${configIP}:800/live/${getParams("orderNum")}.flv`
        });
        flvPlayer.attachMediaElement(videoElement);
        flvPlayer.load();
        flvPlayer.play();

        // 清理旧的定时器
        if (timerId) {
            clearInterval(timerId);
        }

        // 创建新的定时器
        timerId = setInterval(() => {
            // 停止播放
            flvPlayer.unload();
            flvPlayer.detachMediaElement();
            // 重新播放
            start(configIP)
        }, 5000);
    }
}

总结一下,解决 DOMException 错误的方法就是在播放新的媒体文件之前,先停止当前正在播放的媒体文件,等待当前正在加载的媒体文件加载完成,再播放新的媒体文件。而解决摄像头延迟的问题,就是在每次刷新请求时,清理旧的定时器,再创建新的定时器。这样就可以避免多个定时器同时在运行导致页面卡顿的问题。

相关推荐
葫芦和十三12 小时前
图解 MongoDB 15|journal 与持久化:写入怎么不丢,崩溃怎么恢复
后端·mongodb·面试
葫芦和十三12 小时前
图解 MongoDB 16|压缩:snappy、zstd 和 zlib 的取舍
后端·mongodb·面试
苍何13 小时前
终于找到免费开源TTS模型,克隆声音不要钱,本地电脑也能跑
后端
用户5936087414013 小时前
Spring AI 集成 DeepSeek 原生供应商并实现think模式
后端
追逐时光者13 小时前
别再满网找零散工具了,腾讯 QQ 浏览器这个“帮小忙”工具箱真能省时间
前端·后端
心静自然凉80013 小时前
Linux网络核心知识+bonding主备模式配置
后端
爻渡15 小时前
异步编程演进史:从回调到Promise再到Async/Await
后端·程序员
要阿尔卑斯吗16 小时前
企业级 RAG 系统的文件标签管理:三层架构与层级优化实战
后端
要阿尔卑斯吗16 小时前
Agent开发之为什么有了LangChain4j框架,我们却不能直接使用它?——桥接层设计详解
后端
用户77139702070616 小时前
从CMD到PowerShell:一个.NET开发者的命令行进化之路
后端