解决 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、线程的状态信息,并能在不修改应用代码的情况下,对业务问题进行诊断,包括查看方法调用的出入参、异常,监测方法执行耗时,类…...
MySQL 隔离级别:脏读、幻读及不可重复读的原理与示例
一、MySQL 隔离级别 MySQL 提供了四种隔离级别,用于控制事务之间的并发访问以及数据的可见性,不同隔离级别对脏读、幻读、不可重复读这几种并发数据问题有着不同的处理方式,具体如下: 隔离级别脏读不可重复读幻读性能特点及锁机制读未提交(READ UNCOMMITTED)允许出现允许…...
MySQL用户和授权
开放MySQL白名单 可以通过iptables-save命令确认对应客户端ip是否可以访问MySQL服务: test: # iptables-save | grep 3306 -A mp_srv_whitelist -s 172.16.14.102/32 -p tcp -m tcp --dport 3306 -j ACCEPT -A mp_srv_whitelist -s 172.16.4.16/32 -p tcp -m tcp -…...
OPENCV形态学基础之二腐蚀
一.腐蚀的原理 (图1) 数学表达式:dst(x,y) erode(src(x,y)) min(x,y)src(xx,yy) 腐蚀也是图像形态学的基本功能之一,腐蚀跟膨胀属于反向操作,膨胀是把图像图像变大,而腐蚀就是把图像变小。腐蚀后的图像变小变暗淡。 腐蚀…...
Fabric V2.5 通用溯源系统——增加图片上传与下载功能
fabric-trace项目在发布一年后,部署量已突破1000次,为支持更多场景,现新增支持图片信息上链,本文对图片上传、下载功能代码进行梳理,包含智能合约、后端、前端部分。 一、智能合约修改 为了增加图片信息上链溯源,需要对底层数据结构进行修改,在此对智能合约中的农产品数…...
VM虚拟机网络配置(ubuntu24桥接模式):配置静态IP
编辑-虚拟网络编辑器-更改设置 选择桥接模式,然后找到相应的网卡(可以查看自己本机的网络连接) windows连接的网络点击查看属性 编辑虚拟机设置更改网络配置,选择刚才配置的桥接模式 静态ip设置: 我用的ubuntu24桌…...
人机融合智能 | “人智交互”跨学科新领域
本文系统地提出基于“以人为中心AI(HCAI)”理念的人-人工智能交互(人智交互)这一跨学科新领域及框架,定义人智交互领域的理念、基本理论和关键问题、方法、开发流程和参与团队等,阐述提出人智交互新领域的意义。然后,提出人智交互研究的三种新范式取向以及它们的意义。最后,总结…...
腾讯云V3签名
想要接入腾讯云的Api,必然先按其文档计算出所要求的签名。 之前也调用过腾讯云的接口,但总是卡在签名这一步,最后放弃选择SDK,这次终于自己代码实现。 可能腾讯云翻新了接口文档,现在阅读起来,清晰了很多&…...
Golang——7、包与接口详解
包与接口详解 1、Golang包详解1.1、Golang中包的定义和介绍1.2、Golang包管理工具go mod1.3、Golang中自定义包1.4、Golang中使用第三包1.5、init函数 2、接口详解2.1、接口的定义2.2、空接口2.3、类型断言2.4、结构体值接收者和指针接收者实现接口的区别2.5、一个结构体实现多…...
CVPR2025重磅突破:AnomalyAny框架实现单样本生成逼真异常数据,破解视觉检测瓶颈!
本文介绍了一种名为AnomalyAny的创新框架,该方法利用Stable Diffusion的强大生成能力,仅需单个正常样本和文本描述,即可生成逼真且多样化的异常样本,有效解决了视觉异常检测中异常样本稀缺的难题,为工业质检、医疗影像…...
react菜单,动态绑定点击事件,菜单分离出去单独的js文件,Ant框架
1、菜单文件treeTop.js // 顶部菜单 import { AppstoreOutlined, SettingOutlined } from ant-design/icons; // 定义菜单项数据 const treeTop [{label: Docker管理,key: 1,icon: <AppstoreOutlined />,url:"/docker/index"},{label: 权限管理,key: 2,icon:…...
