解决 video.js ios 播放一会行一会不行
最近用video 进行m3u8视频文件播放,但是途中遇到了 安卓和电脑端都能打开,ios有时可以播放有时播放不了
出现问题原因:
ios拿到视频流前需要预加载视频,如果当前视频流还没有打开过,ios拿不到视频流的缓存,这时候ios会一直转圈直到报错
解决思路:
(1)先打开一个播放窗口,提前加载视频流
(2)判断当前video的 readyState 属性
(3)当readyState的状态码不等于0时,创建当前预览的video
html代码:
<!-- 视频播放 start--><div class="monitor-preview__video"><div id="videoBox" style="width: 94vw; height: 25vh;"><videoid="VideoPreview"class="video-js vjs-default-skin vjs-big-play-centered"controlsstyle='width: 100%;height: 100%;'x5-video-player-fullscreen="true"webkit-playsinlinex5-playsinlineplaysinlinex-webkit-airplay="allow"><source :src="this.formData.path" type="application/x-mpegURL"></video></div></div><!-- 视频播放 end--><!-- ios 直接打开视频预览有问题,所以这里搞一个播放预加载界面start--><div id="copyVideoBox" v-show="false"><videoid="copyVideoPreview"class="video-js vjs-default-skin vjs-big-play-centered"controlspreload="metadata"style='width: 0;height: 0;'x5-video-player-fullscreen="true"webkit-playsinlinex5-playsinlineplaysinlinex-webkit-airplay="allow"autoplay><source :src="this.formData.path" type="application/x-mpegURL"></video></div><!-- 取一个预加载界面end-->
js代码:
/*** @param device 设备信息* 切换视频*/async checkDevice (device) {if (device && device.sysCameraCode) {this.formData.deviceName = device.cameraNameconst queryParams = {sysCameraCode: device.sysCameraCode,apiPath: window.location.origin}const videoRes = await this.$api.monitorPerm.preview(queryParams)this.formData.path = videoRes.result.previewUrlthis.prepareVideo ()}},/*** 预加载视频信息* ios 直接打开视频预览有问题,所以这里搞一个播放预加载界面start*/prepareVideo () {const isIos = navigator.userAgent.toLowerCase().match(/cpu iphone os (.*?) like mac os/)if (!isIos) {this.reloadVideoDom()return}// 清空旧的预览信息this.clearVideoDom()if (this.formData.copyVideo) {this.formData.copyVideo.dispose()}this.formData.copyVideo = nullconst videoBox = document.getElementById('copyVideoBox')const VideoPreview = document.getElementById('copyVideoPreview')if (VideoPreview) {videoBox.removeChild(VideoPreview)}videoBox.innerHTML = '<video\n' +' id="copyVideoPreview"\n' +' class="video-js vjs-default-skin vjs-big-play-centered"\n' +' controls\n' +' preload="metadata"\n' +' style=\'width: 100%;height: 100%;\'\n' +' x5-video-player-fullscreen="true"\n' +' webkit-playsinline\n' +' x5-playsinline\n' +' playsinline\n' +' x-webkit-airplay="allow"\n' +' autoplay\n' +' >\n' +` <source src="${this.formData.path}" type="application/x-mpegURL">\n` +' </video>'const path = this.formData.paththis.$nextTick(() => {this.formData.copyVideo = this.$videojs('copyVideoPreview', {bigPlayButton: true,textTrackDisplay: false,posterImage: false,errorDisplay: true,controlBar: true,html5: {hls: {overrideNative: false},nativeVideoTracks: true,nativeAudioTracks: true,nativeTextTracks: true}}, function () {this.src({src: path,type: 'application/x-mpegURL'})this.play()})// 监控预加载视频状态,状态不等于0创建预览domthis.$nextTick(() => {this.formData.time = setInterval(() => {const myVid = this.formData.copyVideo.readyState()console.log('myVid', myVid)if (myVid !== 0) {clearInterval(this.formData.time)this.reloadVideoDom()}}, 1000)})})},/*** 创建当前需要预览的视频dom*/reloadVideoDom () {this.clearVideoDom()const videoBox = document.getElementById('videoBox')videoBox.innerHTML = '<video\n' +' id="VideoPreview"\n' +' class="video-js vjs-default-skin vjs-big-play-centered"\n' +' controls\n' +' preload="metadata"\n' +' style=\'width: 100%;height: 100%;\'\n' +' x5-video-player-fullscreen="true"\n' +' webkit-playsinline\n' +' x5-playsinline\n' +' playsinline\n' +' x-webkit-airplay="allow"\n' +' autoplay\n' +' >\n' +` <source src="${this.formData.path}" type="application/x-mpegURL">\n` +' </video>'const path = this.formData.paththis.$nextTick(() => {this.formData.video = this.$videojs('VideoPreview', {bigPlayButton: true,textTrackDisplay: false,posterImage: false,errorDisplay: true,controlBar: true,html5: {hls: {overrideNative: false},nativeVideoTracks: true,nativeAudioTracks: true,nativeTextTracks: true}}, function () {this.src({src: path,type: 'application/x-mpegURL'})this.play()})})},/*** 清空当前预览dom*/clearVideoDom () {if (this.formData.video) {this.formData.video.dispose()}this.formData.video = nullconst videoBox = document.getElementById('videoBox')const VideoPreview = document.getElementById('VideoPreview')if (VideoPreview) {videoBox.removeChild(VideoPreview)}}
问题到这里就解决了
相关文章:
解决 video.js ios 播放一会行一会不行
最近用video 进行m3u8视频文件播放,但是途中遇到了 安卓和电脑端都能打开,ios有时可以播放有时播放不了 出现问题原因: ios拿到视频流前需要预加载视频,如果当前视频流还没有打开过,ios拿不到视频流的缓存,…...
排序分析(Ordination analysis)及R实现
在生态学、统计学和生物学等领域,排序分析是一种用于探索和展示数据结构的多元统计技术。这种分析方法通过将多维数据集中的样本或变量映射到低维空间,以便更容易理解和可视化数据之间的关系。排序分析常用于研究物种组成、生态系统结构等生态学和生物学…...
Tomcat主配置文件(server.xml)详解
前言 Tomcat主配置文件(server.xml)是Tomcat服务器的主要配置文件,文件位置在conf目录下,它包含了Tomcat的全局配置信息,包括监听端口、虚拟主机、安全配置、连接器等。 目录 1 server.xml组件类别 2 组件介绍 3 se…...
Python实现简单的区块链,实现共识算法、Merkle Tree(默克尔树)、冲突解决、添加交易等功能
Python实现简单的区块链 记录自己假期所学相关内容 文章中的内容,开源代码地址见文末。 文章目录 Python实现简单的区块链1、分模块实现简单的单节点区块链1.1 Transaction类1.2 DaDaMessage类1.3 Block类1.4 Dada_BlockCoin类1.5 主函数BlockChainApp类1.6 主函数…...
深入理解 Java 虚拟机(JVM)从入门到精通
目录 一、JVM内存结构1、堆(Heap)(1)特点(2)堆内存分配(3)晋升到老年代的方式(4)堆内存检验方式2、虚拟机栈(VM Stack)(1&…...
哔哩哔哩自动评论软件,其成果展示与开发流程和代码分享
先来看实操成果,↑↑需要的同学可看我名字↖↖↖↖↖,或评论888无偿分享 一、背景介绍 随着互联网的发展,哔哩哔哩作为国内最大的弹幕视频网站之一,吸引了越来越多的用户。为了更好地推广自己的作品,许多UP主希望能够通…...
Qt OpenCV 学习(一):环境搭建
对应版本 Qt 5.15.2OpenCV 3.4.9MinGW 8.1.0 32-bit 1. OpenCV 下载 确保安装 Qt 时勾选了 MinGW 编译器 本文使用 MinGW 编译好的 OpenCV 库,无需自行编译 确保下载的 MinGW 和上述安装 Qt 时勾选的 MinGW 编译器位数一致,此处均为 x86/32-bit下载地址…...
Redis——某马点评day02——商铺缓存
什么是缓存 添加Redis缓存 添加商铺缓存 Controller层中 /*** 根据id查询商铺信息* param id 商铺id* return 商铺详情数据*/GetMapping("/{id}")public Result queryShopById(PathVariable("id") Long id) {return shopService.queryById(id);} Service…...
prometheus|云原生|轻型日志收集系统loki+promtail的部署说明
一, 日志聚合的概念说明 日志------ 每一个程序,服务都应该有保留日志,日志的作用第一是记录程序运行的情况,在出错的时候能够记录错误情况,简单来说就是审计工作,例如nginx服务的日志,kuber…...
MySQL 临时数据空间不足导致SQL被killed 的问题与扩展
开头还是介绍一下群,如果感兴趣PolarDB ,MongoDB ,MySQL ,PostgreSQL ,Redis, Oceanbase, Sql Server等有问题,有需求都可以加群群内,可以解决你的问题。加群请联系 liuaustin3 ,(共1730人左右 1 2 3 4 5࿰…...
文心一言大模型应用开发入门
本文重点介绍百度智能云平台、文心一言、千帆大模型平台的基本使用与接入流程及其详细步骤。 注册文心一言 请登录文心一言官方网站 https://yiyan.baidu.com/welcome 点击登录;图示如下: 请注册文心一言账号并点击登录,图示如下࿱…...
C++新经典模板与泛型编程:SFINAE替换失败并不是一个错误
替换失败并不是一个错误(SFINAE) SFINAE是一个英文简称,全称为Substitution Failure is not an Error,翻译成中文就是“替换失败并不是一个错误”。 SFINAE可以看作C语言的一种特性或模板设计中要遵循的一个重要原则,…...
基于若依的ruoyi-nbcio流程管理系统支持支持定时边界事件和定时捕获事件
更多ruoyi-nbcio功能请看演示系统 gitee源代码地址 前后端代码: https://gitee.com/nbacheng/ruoyi-nbcio 演示地址:RuoYi-Nbcio后台管理系统 1、定时边界事件 <template><div class"panel-tab__content"><!--目前只处理定…...
递归-极其优雅的问题解决方法(Java)
递归的定义 大名鼎鼎的递归,相信你即使没接触过也或多或少听过,例如汉诺塔问题就是运用了递归的思想,对于一些学过c语言的同学来说,它可能就是噩梦,因为我当时就是这么认为的(不接受反驳doge) …...
VSCode搭建STM32开发环境
1、下载安装文件 链接:https://pan.baidu.com/s/1WnpDTgYBobiZaXh80pn5FQ 2、安装VSCodeUserSetup-x64-1.78.2.exe软件 3、 在VSCode中安装必要的插件 3、配置Keil Assistant插件 4、在环境变量中部署mingw64编译环境...
解决CentOS下PHP system命令unoconv转PDF提示“Unable to connect or start own listener“
centos系统下,用php的system命令unoconv把word转pdf时提示Unable to connect or start own listene的解决办法 unoconv -o /foo/bar/public_html/upload/ -f pdf /foo/bar/public_html/upload/test.docx 2>&1 上面这个命令在shell 终端能执行成功,…...
软件测试外包干了2个月,技术进步2年。。。
先说一下自己的情况,本科生,18年通过校招进入北京某软件公司,干了接近2年的功能测试,今年国庆,感觉自己不能够在这样下去了,长时间呆在一个舒适的环境会让一个人堕落!而我已经在一个企业干了2年的功能测试&…...
Linux-网络服务和端口
域名:便于人们记忆和使用的标识符 www.baidu.com域名解析:将域名转换为与之对应的 IP 地址的过程 nameserver 8.8.8.8ip地址:网络设备的唯一数字标识符 域名ip地址localhost127.0.0.1 网络服务和端口 网络服务端口ftp21ssh22http80https…...
Kubernetes权威指南:从Docker到Kubernetes实践全接触(第5版)读书笔记 目录
完结状态:未完结 文章目录 前言第1章 Kubernetes入门 11.1 了解Kubernetes 2 附录A Kubernetes核心服务配置详解 915总结 前言 提示:这里可以添加本文要记录的大概内容: Kubernetes权威指南:从Docker到Kubernetes实践全接触&…...
阿里云Arthas使用——通过watch命令查看类的返回值 捞数据出来
前言 Arthas 是一款线上监控诊断产品,通过全局视角实时查看应用 load、内存、gc、线程的状态信息,并能在不修改应用代码的情况下,对业务问题进行诊断,包括查看方法调用的出入参、异常,监测方法执行耗时,类…...
JavaSec-RCE
简介 RCE(Remote Code Execution),可以分为:命令注入(Command Injection)、代码注入(Code Injection) 代码注入 1.漏洞场景:Groovy代码注入 Groovy是一种基于JVM的动态语言,语法简洁,支持闭包、动态类型和Java互操作性,…...
《Qt C++ 与 OpenCV:解锁视频播放程序设计的奥秘》
引言:探索视频播放程序设计之旅 在当今数字化时代,多媒体应用已渗透到我们生活的方方面面,从日常的视频娱乐到专业的视频监控、视频会议系统,视频播放程序作为多媒体应用的核心组成部分,扮演着至关重要的角色。无论是在个人电脑、移动设备还是智能电视等平台上,用户都期望…...
Docker 运行 Kafka 带 SASL 认证教程
Docker 运行 Kafka 带 SASL 认证教程 Docker 运行 Kafka 带 SASL 认证教程一、说明二、环境准备三、编写 Docker Compose 和 jaas文件docker-compose.yml代码说明:server_jaas.conf 四、启动服务五、验证服务六、连接kafka服务七、总结 Docker 运行 Kafka 带 SASL 认…...
【第二十一章 SDIO接口(SDIO)】
第二十一章 SDIO接口 目录 第二十一章 SDIO接口(SDIO) 1 SDIO 主要功能 2 SDIO 总线拓扑 3 SDIO 功能描述 3.1 SDIO 适配器 3.2 SDIOAHB 接口 4 卡功能描述 4.1 卡识别模式 4.2 卡复位 4.3 操作电压范围确认 4.4 卡识别过程 4.5 写数据块 4.6 读数据块 4.7 数据流…...
ESP32 I2S音频总线学习笔记(四): INMP441采集音频并实时播放
简介 前面两期文章我们介绍了I2S的读取和写入,一个是通过INMP441麦克风模块采集音频,一个是通过PCM5102A模块播放音频,那如果我们将两者结合起来,将麦克风采集到的音频通过PCM5102A播放,是不是就可以做一个扩音器了呢…...
苍穹外卖--缓存菜品
1.问题说明 用户端小程序展示的菜品数据都是通过查询数据库获得,如果用户端访问量比较大,数据库访问压力随之增大 2.实现思路 通过Redis来缓存菜品数据,减少数据库查询操作。 缓存逻辑分析: ①每个分类下的菜品保持一份缓存数据…...
土地利用/土地覆盖遥感解译与基于CLUE模型未来变化情景预测;从基础到高级,涵盖ArcGIS数据处理、ENVI遥感解译与CLUE模型情景模拟等
🔍 土地利用/土地覆盖数据是生态、环境和气象等诸多领域模型的关键输入参数。通过遥感影像解译技术,可以精准获取历史或当前任何一个区域的土地利用/土地覆盖情况。这些数据不仅能够用于评估区域生态环境的变化趋势,还能有效评价重大生态工程…...
Swagger和OpenApi的前世今生
Swagger与OpenAPI的关系演进是API标准化进程中的重要篇章,二者共同塑造了现代RESTful API的开发范式。 本期就扒一扒其技术演进的关键节点与核心逻辑: 🔄 一、起源与初创期:Swagger的诞生(2010-2014) 核心…...
浪潮交换机配置track检测实现高速公路收费网络主备切换NQA
浪潮交换机track配置 项目背景高速网络拓扑网络情况分析通信线路收费网络路由 收费汇聚交换机相应配置收费汇聚track配置 项目背景 在实施省内一条高速公路时遇到的需求,本次涉及的主要是收费汇聚交换机的配置,浪潮网络设备在高速项目很少,通…...
C++ 设计模式 《小明的奶茶加料风波》
👨🎓 模式名称:装饰器模式(Decorator Pattern) 👦 小明最近上线了校园奶茶配送功能,业务火爆,大家都在加料: 有的同学要加波霸 🟤,有的要加椰果…...
