uniapp视频播放器(h5+app)

关于uniapp视频播放器遇到的一些问题,mark下。

中途遇到了很多问题,如果有相同的伙伴遇到了类似的,欢迎交流

  • 官方的video播放器在app上不友好,有以下功能不支持。
  1. @loadedmetadata、@controlstoggle不支持

在这里插入图片描述

  1. 不支持外挂字幕,因为video在app上运行时,是采用的ijkplayer库来实现的,ijkplayer目前也不支持外挂字幕

在这里插入图片描述

  1. 使用subNVues或者cover-view来自定义绘制视频界面覆盖(因为cover-view不支持嵌套,所以最后采用使用subNVues)

在这里插入图片描述

  1. video在h5需要播放时采用的是html的video标签,但是不支持m3u8格式,最后采用的是dplayer播放器+hls来实现的m3u8播放(也可以通过m3u8格式转换后再进行播放)

我这边的想要的是自定义绘制视频界面,这样做的话就需要将video原有的control相关的功能重写(播放、暂停、快进、快退、全屏、音量等),全屏和非全屏两套样式,通过官方提供的uni.createVideoContext(videoId, this)可以获取到video的实例,然后通过实例调用video的api,比如play、pause等。

在这里插入图片描述

最终我这边实现后的播放器支持以下功能:

  1. app端自定义界面,播放、暂停、快进、快退、全屏、音量、选集、倍速、清晰度切换、手势(快进、后退、亮度调节、音量调节)。
  2. h5采用的是dplayer播放器+hls支持m3u8格式播放。
  3. 支持外挂字幕(SRT通过)
    下面说下具体的实现和遇到的问题:

1. 配置subNVues子窗体

  1. 这里注意的一点是path路径是从根目录开始的,不是对应的父窗体的相对路径。

  2. 文件格式一定是要nvue格式。

    配置完之后子窗体就会在对应的页面上显示。

在这里插入图片描述
在这里插入图片描述

2.配置video播放界面

  1. 因为我们需要自定义界面所以video的controls需设置为false

在这里插入图片描述

  1. 全屏和非全屏后界面有些许差异,比如全屏后才可以选集等其他功能,那需要设计出两套样式。

    通过ref拿到video实例

videoCTX = this.$refs.video

全屏和取消全屏事件

  // 全屏/退出全屏fullOrExitScreen() {if (this.fullScreenStatus) {videoCTX.exitFullScreen()} else {videoCTX.requestFullScreen()}},

3. 设置手势操作

手势操作分为向上向下向左向右四个方位

  • 向左向右:快进、后退
  • 屏幕左侧上下滑动:亮度调节
  • 屏幕右侧上下滑动:音量调节

使用touchStart、touchMove、touchend来实现此功能

touchStart时存储首次的坐标点

this.oldTouchs = e.changedTouches[0]

我这边定义的touchType为三种类型,currentTime进度、luminance亮度、volume音量

  1. 首先先判断是否为上下滑动,如果上下的话就只能是亮度和音量调节,接着获取屏幕的宽度,判断手势移动的x坐标是否大于屏幕宽度的1/2,如果是就为音量调节,否则为亮度调节。

在这里插入图片描述

  1. 如果为进度条的话则先保存当前进度,视频暂停,通过x轴移动的距离计算出当前进度,然后通过video的seek方法跳转到当前进度。

在这里插入图片描述

然后再touchEnd设置video进度

在这里插入图片描述

  1. 音量调节也是一样的 算出滑动的距离后通过plus.device.setVolume设置

在这里插入图片描述

  1. 亮度调节也是一样的 算出滑动的距离后通过plus.screen.setBrightness设置

在这里插入图片描述

4. 配置字幕

  1. 如果是VVT格式可以采用video中track标签实现,.vtt 格式文件属于 Web Video Text Tracks Format(WebVTT),是一种基于文本 UTF-8 编码的格式,为 Web 媒体元素提供字幕数据文件。WebVTT 的 MIME 格式是 text/vtt。
  2. 我这边项目中是用的是SRT格式的,但是video无法解析出来,所以想到的办法是将SRT字幕格式转换成js可以解析的json格式。

下面是SRT原格式

在这里插入图片描述

  1. 通过以下函数将数据转换为数组

    createSrtArr(srt) {let arr = srt.split(/\n\n|\r\r|\r\n\r\n/)let result = []arr.forEach(item => {let srtObj = {}let containArr = item.split(/\n/)if (containArr[1]) {//此处正则用于取出00:00:00,213 --> 00:00:00,213这种结构,防止可能存在于此行的x,y坐标对后续处理造成影响var reg = /^(\d{2}):(\d{2}):(\d{2})[\.,](\d{1,3}) --\> (\d{2}):(\d{2}):(\d{2})[\.,](\d{1,3})/glet regResult = reg.exec(containArr[1])if (regResult) {let timeSplit = regResult[0].split(' --> ')srtObj.from = this.getSeconds(timeSplit[0])srtObj.to = this.getSeconds(timeSplit[1])//这里的两个replace主要是将srt中可能携带的font标签转化为易用的span,当时遇到了如果是font标签的话没办法继承父元素的字体大小的问题,题外话:本次字母字体大小采用了媒体查询进行设置srtObj.htmlText = containArr.slice(2).join(`\n`).replace(/\<font/g, '<span').replace(/\<\/font/g,'</span')result.push(srtObj)}}})return result}
    

转换后的数据格式如下

在这里插入图片描述

  1. 通过currentTime时长和获取到的subtitlesArray字幕数组获取到对应时间的字幕。
  getSubtitle(currentTime, arr) {let left = 0;let right = arr.length - 1;while (left <= right) {let mid = Math.floor((left + right) / 2);if (currentTime >= arr[mid].from && currentTime <= arr[mid].to) {return arr[mid].htmlText;} else if (currentTime < arr[mid].from) {right = mid - 1;} else {left = mid + 1;}}return null; // 如果未找到匹配的时间段,则返回null或者其他您认为合适的值}

PS: 这个里有注意事项,因为我这边是需要兼容h5和app端,通过时长获取到的字幕数据有可能携带标签,所以需要富文本展示,h5和app上均需要做处理。

<!-- #ifdef H5 --><view class="subtitles" v-html='subtitles'></view><!-- #endif --><!-- #ifdef APP-PLUS --><rich-text class="subtitles" :nodes="nodes" :style="videoBox"><!-- #endif --></rich-text>
  const res = this.getSubtitle(value,this.subtitlesArray) || ''if (this.subtitlesArray.length) {// #ifdef APP-PLUSthis.nodes[0].children[0].text =res// #endif// #ifdef H5this.subtitles = res// #endif}

这里先简单记录下,因为时间有限,代码已上传到线上,有需要的伙伴可以下载下来参考下。
传送门

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/652631.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于自注意力机制的长短期记忆神经网络(LSTM-SelfAttention)的回归预测

提示&#xff1a;MATLAB版本需要R2023a以上 基于自注意力机制的长短期记忆神经网络&#xff08;LSTM-SelfAttention&#xff09;是一种用于时序数据预测的模型。这个模型结合了两个不同的结构&#xff0c;即长短期记忆网络&#xff08;LSTM&#xff09;和自注意力机制&#xff…

Python自学之路--003:PyCharm新建工程之后安装的Python第三方库找不到问题

目录 1、概述 2、问题原因 3、解决办法 3.1、.py文件通过.bat不能调用 3.2、通过调用之前PyCharm工程的解释器找到库 3.3、重新安装一遍或将库Copy到新工程的.venv里面 1、概述 通过PyCharm新建一个工程的时候发现&#xff0c;之前安装的python库没了&#xff0c;如下图。…

李廉洋:4.27黄金原油下周一行情分析及走势策略。

金价将出现六周来的首次单周下跌&#xff0c;因投资者在金价上涨数月后获利了结。自2月中旬的低点以来&#xff0c;金价已经上涨了约17%&#xff0c;尽管对美联储放松政策的预期正在减弱&#xff0c;但金价仍屡创新高。周五公布的最新通胀数据强化了高利率将暂时维持的观点。“…

SQLite尽如此轻量

众所周知&#xff0c;SQLite是个轻量级数据库&#xff0c;适用于中小型服务应用等&#xff0c;在我真正使用的时候才发现&#xff0c;它虽然轻量&#xff0c;但不知道它却如此轻量。 下载 官网&#xff1a; SQLite Download Page 安装 1、将下载好的两个压缩包同时解压到一个…

VirtualBox7.0.16的蓝屏大坑与ssh登陆ubuntu虚拟机的办法

背景&#xff1a; 安装了最新版的VirtualBox&#xff0c;装了ubuntu系统&#xff0c;在win10下通过ssh死活无法与ubuntu进行正常登陆控制。 然后开始了踩坑。 问题1&#xff1a;ssh登陆失败&#xff0c;但是主机能ping通ubuntu&#xff0c;反过来也能ping通&#xff0c;网络…

IDEA 中如何通过连接数据库自动生成代码

目录 1、IDEA 中安装 MyBatisX 插件 2、点击 IDEA 右侧的 database 数据库按钮&#xff0c;点击新建数据源 Data Source 3、编辑数据库连接信息 4、选择你要生成代码的数据库表 5、编辑你代码生成的基本路径以及一些配置项 6、选择annotation&#xff1a;mybatis-plus3&a…

时间序列预测:基于PyTorch框架的循环神经网络(RNN)实现销量预测

之前随手一写&#xff0c;没想到做预测的同学还挺多&#xff0c;但是之前那个效果并不好&#xff0c;于是在之前的基础上重新修改完善&#xff0c;到了现在这一步才感觉预测算是初步能应用。 上文地址&#xff1a;LSTM模型预测时间序列&#xff1a;根据历史销量数据预测商品未…

计算机视觉的应用29-卷积神经网络(CNN)中的变种:分组卷积、转置卷积、空洞卷积的计算过程

大家好&#xff0c;我是微学AI&#xff0c;今天给大家介绍一下计算机视觉的应用29-卷积神经网络(CNN)中的变种&#xff1a;分组卷积、转置卷积、空洞卷积的计算过程。分组卷积将输入通道分为几组&#xff0c;对每组独立进行卷积操作&#xff0c;以减少计算量和模型参数。转置卷…

未能启动VMware Authorization Service

错误信息 英文版&#xff1a; VMware Workstation failed to start the VMware Authorization Service. You can try manuallystarting the VMware Authorization Service. If thisproblem persists, contact VMware support. 中文版 VMware Workstation 未能启动VMware Aut…

计算机体系结构与OS管理

冯诺依曼体系结构 我们只看数字信号&#xff08;红色的线&#xff09;&#xff1a; 计算机数据的流动决定了计算机的效率&#xff0c;数据流动就是数据在不同地方的来回拷贝。 所以我们会采取让硬件设备直接与CPU链接的方式&#xff0c;所以就有了储存器了。储存器大大提升了效…

linux的SSH(远程登录)服务

目录 1.SSH远程管理 1.1 SSH的概述 1.2 OpenSSH服务器 1.3 SSH端口、配置文件 2.服务端重要配置 3.登录验证方式 3.1 密码验证 3.2 密钥对验证 4.使用 SSH 客户端程序 4.1 ssh 远程登录 4.2 scp 远程复制 4.3 sftp文件传输 5.创建使用密钥对 6.TCP Wrappers访问控…