2025年6月8日 星期日 乙巳(蛇)年 三月十二 设为首页 加入收藏
rss
您当前的位置:首页 > 计算机 > 编程开发 > JavaScript

处理海康H5视频流中断与取流失败的解决方案

时间:02-13来源:作者:点击数:39
城东书院 www.cdsy.xyz

前言

在现代Web应用中,视频流的稳定性和可靠性是用户体验的重要组成部分。尤其是在使用海康威视的H5视频流时,流中断和取流失败的问题时常出现,给用户带来不便。本文将通过分析Vue 3中与海康H5视频流相关的代码,探讨如何有效处理这些问题,并提供相应的解决方案。

代码分析与解决方案

1. 视频流控制

在Vue 3中,我们通过定义点击事件来控制视频流的切换。以下是左侧和右侧视频切换的代码片段:

  • const leftVideoClick = () => {
  •    videoType.value = videoType.value - 1;
  •    if (videoType.value < 1) {
  •        videoLeft.value = false;
  •        return;
  •   }
  •    videoLeft.value = true;
  •    updateTitle(videoType.value);
  •    getvideo(videoType.value);
  • };
  • const rightVideoClick = () => {
  •    videoType.value = videoType.value + 1;
  •    if (videoType.value > 3) {
  •        videoRight.value = false;
  •        return;
  •   }
  •    videoRight.value = true;
  •    updateTitle(videoType.value);
  •    getvideo(videoType.value);
  • };

在这段代码中,我们通过videoType来控制当前视频的类型,并在点击左右按钮时更新视频流。若videoType超出范围,则相应的按钮会被禁用。

2. 获取视频流

获取视频流的逻辑在getvideo函数中实现。该函数会根据当前的videoType请求视频数据,并随机选择四条唯一记录:

  • const getvideo = (type) => {
  •    let params1 = { type: type };
  •    const getRandomUniqueVideos = (results, count) => {
  •        const shuffled = results.sort(() => 0.5 - Math.random());
  •        return [...new Set(shuffled.slice(0, count))];
  •   };
  •    
  •    getHomeVideo(params1).then((res) => {
  •        // 加载状态设置
  •        video1Loading.value = true;
  •        video2Loading.value = true;
  •        video3Loading.value = true;
  •        video4Loading.value = true;
  •        const results = res.data.results;
  •        const selectedVideos = getRandomUniqueVideos(results, 4);
  •        // 分别赋值给视频 URL 和名称
  •        const [video1, video2, video3, video4] = selectedVideos;
  •        video1Url.value = video1.url;
  •        video1Name.value = video1.equipmentName;
  •        // 其他视频赋值...
  •   });
  • };

在获取视频流时,我们使用了getHomeVideo函数来请求数据,并通过getRandomUniqueVideos函数随机选择四条视频记录。此时,我们还设置了加载状态,以便在视频加载时给用户反馈。

3. 处理流中断与取流失败

错误码及其描述

错误码 描述
0x12f900001 接口调用参数错误
0x12f900002 不在播放状态
0x12f900003 仅回放支持该功能
0x12f900004 普通模式不支持该功能
0x12f900005 高级模式不支持该功能
0x12f900006 高级模式的解码库加载失败
0x12f900008 url格式错误
0x12f900009 取流超时错误
0x12f900010 设置或者是获取音量失败,因为没有开启音频的窗口
0x12f900011 设置的音量不在1-100范围
0x12f910000 websocket连接失败,请检查网络是否通畅,URL是否正确
0x12f910010 取流失败
0x12f910011 流中断,电脑配置过低,程序卡主线程都可能导致流中断
0x12f910014 没有音频数据
0x12f910015 未找到对应websocket,取流套接字被动关闭的报错
0x12f910016 websocket不在连接状态
0x12f910017 不支持智能信息展示
0x12f910018 websocket长时间未收到message
0x12f910019 wss连接失败,原因:端口尚未开通、证书未安装、证书不安全
0x12f910020 单帧回放时不能暂停
0x12f910021 已是最大倍速
0x12f910022 已是最小倍速
0x12f910023 ws/wss连接超时,默认6s超时时间,原因:网络异常,网络不通
0x12f910026 jsdecoder1.0解码报错视频编码格式不支持
0x12f910027 后端取流超时,主动关闭连接(设备突然离线或重启,网络传输超时20s)
0x12f910028 设置的缓冲区大小无效,大小0-510241024,不在该范围的报错
0x12f910029 普通模式的报错,码流异常导致黑屏,尝试重新取流
0x12f910031 普通模式下播放卡主会出现
0x12f910032 码流编码格式普通模式下不支持,可切换高级模式尝试播放
0x12f920015 未调用停止录像,再次调用开始录像
0x12f920016 未开启录像调用停止录像接口错误
0x12f920017 紧急录像目标格式不支持,非ps/mp4
0x12f920018 紧急录像文件名为null
0x12f930010 内存不足
0x12f930011 首帧显示之前无法抓图,请稍后重试
0x12f950000 采集音频失败,可能是在非https域下使用对讲导致
0x12f950001 对讲不支持这种音频编码格式

在视频播放过程中,流中断和取流失败是常见的问题。我们通过设置插件的回调函数来处理这些错误:

  • myPlugins.value.JS_SetWindowControlCallback({
  •    windowEventSelect: function (iWndIndex) {
  •        console.log('windowSelect callback: ', iWndIndex);
  •   },
  •    pluginErrorHandler: function (iWndIndex, iErrorCode, oError) {
  •        console.log('pluginError callback: ', iWndIndex, iErrorCode, oError);
  •        if (iErrorCode == 0x12f910011) {  // 流中断
  •            console.log('流中断,尝试重新连接或重新加载视频流');
  •            reloadVideo(1);
  •       } else if (iErrorCode == 0x12f910010) {
  •            updateTitle(videoType.value);
  •            getvideo(videoType.value);
  •       } else {
  •            console.log('其他错误:', oError);
  •       }
  •   },
  • });

pluginErrorHandler中,我们根据错误代码判断错误类型。如果是流中断(错误代码0x12f910011),则调用reloadVideo函数重新加载视频流;如果是取流失败(错误代码0x12f910010),则更新视频标题并重新获取视频流。

4. 重新加载视频流

reloadVideo函数负责重新加载指定索引的视频流:

  • const reloadVideo = (indx) => {
  •    index.value = '1';
  •    if (indx == 1) {
  •        if (myPlugins.value && myPlugins.value.JS_Stop) {
  •            myPlugins.value.JS_Stop().then(() => {
  •                nextTick(() => {
  •                                        setTimeout(() => {
  •                        myPlugins.value.JS_Play(video1Url.value, { playURL: video1Url.value, mode: mode.value }, index.value).then(
  •                           () => { video1Loading.value = false; }, // 成功操作
  •                           (e) => {
  •                                video1Loading.value = false;
  •                                ElMessage.error('监控视频异常');
  •                           } // 失败操作
  •                       );
  •                   }, 500);
  •               });
  •           });
  •       }
  •   } else if (indx == 2) {
  •        if (myPlugins2.value && myPlugins2.value.JS_Stop) {
  •            myPlugins2.value.JS_Stop().then(() => {
  •                nextTick(() => {
  •                    setTimeout(() => {
  •                        myPlugins2.value.JS_Play(video2Url.value, { playURL: video2Url.value, mode: mode.value }, index.value).then(
  •                           () => { video2Loading.value = false; },
  •                           (e) => {
  •                                video2Loading.value = false;
  •                                ElMessage.error('监控视频异常');
  •                           }
  •                       );
  •                   }, 500);
  •               });
  •           });
  •       }
  •   } else if (indx == 3) {
  •        if (myPlugins3.value && myPlugins3.value.JS_Stop) {
  •            myPlugins3.value.JS_Stop().then(() => {
  •                nextTick(() => {
  •                    setTimeout(() => {
  •                        myPlugins3.value.JS_Play(video3Url.value, { playURL: video3Url.value, mode: mode.value }, index.value).then(
  •                           () => { video3Loading.value = false; },
  •                           (e) => {
  •                                video3Loading.value = false;
  •                                ElMessage.error('监控视频异常');
  •                           }
  •                       );
  •                   }, 500);
  •               });
  •           });
  •       }
  •   } else if (indx == 4) {
  •        if (myPlugins4.value && myPlugins4.value.JS_Stop) {
  •            myPlugins4.value.JS_Stop().then(() => {
  •                nextTick(() => {
  •                    setTimeout(() => {
  •                        myPlugins4.value.JS_Play(video4Url.value, { playURL: video4Url.value, mode: mode.value }, index.value).then(
  •                           () => { video4Loading.value = false; },
  •                           (e) => {
  •                                video4Loading.value = false;
  •                                ElMessage.error('监控视频异常');
  •                           }
  •                       );
  •                   }, 500);
  •               });
  •           });
  •       }
  •   }
  • };

reloadVideo函数中,我们通过JS_Stop停止当前的视频流,并使用JS_Play方法重新加载和播放相应的视频流。在重新加载时,我们使用nextTicksetTimeout确保视频流能够正常加载,并在加载失败时给出错误提示。

5. 解决方案总结

在海康H5视频流的使用中,流中断和取流失败是常见的问题。为了保证视频流的稳定性和可靠性,以下是一些常见的解决方案:

  1. 流中断处理 :当检测到流中断时,通过重新加载视频流来恢复播放。使用pluginErrorHandler中的错误码来判断是否为流中断(0x12f910011),并调用reloadVideo重新加载视频流。
  2. 取流失败处理 :当取流失败时,通常需要重新请求视频数据并更新视频源。在错误回调中,我们根据错误代码(0x12f910010)重新获取视频数据并更新播放内容。
  3. 视频加载提示 :在加载视频时,通过v-loading指令显示加载状态,确保用户在视频加载过程中不会产生困惑。
  4. 视频切换 :通过左侧和右侧的按钮来切换视频,并确保当视频类型超出范围时禁用按钮,避免产生不必要的操作。

通过以上方法,能够有效地处理视频流中断和取流失败问题,提升视频播放的稳定性和用户体验。

结论

在Web应用中,视频流的稳定性至关重要,尤其是在使用海康H5视频流时。通过合理的错误处理和流管理策略,可以大大降低流中断和取流失败对用户体验的影响。本文通过Vue 3框架中的示例代码,展示了如何使用回调函数处理视频流错误,并通过重新加载视频流解决常见问题。借助这些策略,开发者能够为用户提供更加稳定和流畅的视频播放体验。

城东书院 www.cdsy.xyz
方便获取更多学习、工作、生活信息请关注本站微信公众号城东书院 微信服务号城东书院 微信订阅号
推荐内容
相关内容
栏目更新
栏目热门
本栏推荐