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.mzph.cn/diannao/4069.shtml

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

相关文章

Linux实验一:Linux环境及编程工具

目录 一、实验目的二、实验内容三、参考代码四、实验步骤步骤1. 编辑源代码test1.c步骤2. 编译源代码test1.c步骤3. 调试test1步骤4. 重新编译运行test1.c 五、实验结果六、实验总结 一、实验目的 1、掌握Linux C开发过程中的基本概念&#xff1b; 2、掌握如vim&#xff0c;GC…

keepalived检测Nginx高可用

node1 192.168.136.55 node2 192.168.136.56 两台机器都安装dnf install keepalived nginx [rootnode1 ~]# echo "web test page, ip is hostname -I." > /usr/share/nginx/html/index.html [rootnode2 ~]# echo "web test page, ip is hostname -I."…

【ARMv9 DSU-120 系列 4 -- Utility bus 详细介绍 1】

请阅读【Arm DynamIQ™ Shared Unit-120 专栏 】 文章目录 DSU-120 Utility bus事务类型访问大小事务长度安全状态总结缓存控制(ARCACHEU 或 AWCACHEU)突发类型(ARBURSTU 或 AWBURSTU)锁定信号(ARLOCKU 或 AWLOCKU)Utility bus acceptance capabilities

【科学研究】农村出身:一种复杂的情感结构

::: block-1 “时问桫椤”是一个致力于为本科生到研究生教育阶段提供帮助的不太正式的公众号。我们旨在在大家感到困惑、痛苦或面临困难时伸出援手。通过总结广大研究生的经验&#xff0c;帮助大家尽早适应研究生生活&#xff0c;尽快了解科研的本质。祝一切顺利&#xff01;—…

LeetCode 面试题 17.08 —— 马戏团人塔

阅读目录 1. 题目2. 解题思路3. 代码实现 1. 题目 2. 解题思路 首先&#xff0c;我们对人的身高按照从小到大排序&#xff0c;特别注意&#xff0c;对于身高相等的人&#xff0c;要按照体重从高到低排序。这时候&#xff0c;序列已经满足了在上面的人要比下面的人矮一点&#…

在开发软件以便未来本地化到其他语言时需要考虑的事项

我们准备了一份关于开发软件以便未来本地化到其他语言时需要考虑的事项的简要指南。这非常重要&#xff0c;因为您的软件在其他国家市场上的销售可能会带来比本国市场更多的收入。 在开发软件时考虑到未来本地化到其他语言的一些重要方面包括&#xff1a; 设计多语言支持&…

有什么因素会影响IP稳定性?

IP稳定性指的是IP地址在一段时间内保持不变的能力&#xff0c;对于网络连接的安全性和可靠性至关重要。以下是一些可能影响IP稳定性的主要因素&#xff1a; 网络服务提供商&#xff08;ISP&#xff09;的政策&#xff1a;不同的ISP对于IP地址的管理和使用有不同的政策。一些IS…

代码随想录算法训练营第7天 | 454. 四数相加 II | 383. 赎金信 | 15. 三数之和 | 18. 四数之和

454. 四数相加 II 题意 找出四个数组中元素和为0的次数 解 class Solution { public:int fourSumCount(vector<int>& nums1, vector<int>& nums2, vector<int>& nums3, vector<int>& nums4) {unordered_map<int, int> map;i…

springboot+thymeleaf实现一个简单的监听在线人数功能

功能步骤&#xff1a; 1. 当用户访问登录页面时&#xff0c;Logincontroller的showLoginForm方法被调用&#xff0c;返回登录页面的视图名字。 2. 用户提交表单&#xff0c;调用LoginController的login方法。 3.login方法 4.登录验证通过&#xff0c;home方法会被调用&#xf…

C++解方程组的库

解决多元多次方程组的问题&#xff0c;你可以考虑以下几个C库&#xff1a; Eigen: Eigen库是一个高性能的C模板库&#xff0c;用于线性代数运算。它提供了强大的矩阵运算功能&#xff0c;可以用来解多元一次方程组。对于多次方程组&#xff0c;你可能需要结合Eigen和一些数值优…

深入解读CSS高级选择器

CSS选择器是网页样式设计的核心组成部分&#xff0c;它们使开发者能够精准定位页面上的元素并施加相应的样式。在众多选择器中&#xff0c;高级选择器因其强大的定位能力和灵活性备受青睐。接下来&#xff0c;我们将逐一详解这些高级选择器&#xff0c;并通过实例代码加深理解。…

VMware 中将 Rocky Linux 设置为图形界面

在 VMware 中将 Rocky Linux 设置为图形界面的步骤如下&#xff1a; 安装 Rocky Linux&#xff1a;首先&#xff0c;在 VMware 中创建一个新的虚拟机&#xff0c;并按照常规步骤安装 Rocky Linux。确保在安装过程中选择安装图形界面的选项。 启动 Rocky Linux&#xff1a;完成…

C++笔试强训day7

目录 1.字符串中找出连续最长的数字串 2.岛屿数量 3.拼三角 1.字符串中找出连续最长的数字串 链接 我的思路很简洁&#xff0c;就是双指针遍历&#xff0c;然后不断更新左位置left和右位置right和长度len。 然后我写代码的时候代码思路没跟上原本思路&#xff0c;直接把所有…

HTTP网络协议,接口请求的内容类型 content-type(2024-04-27)

1、简介 Content-Type&#xff08;内容类型&#xff09;&#xff0c;一般是指网页中存在的 Content-Type&#xff0c;用于定义网络文件的类型和网页的编码&#xff0c;决定浏览器将以什么形式、什么编码读取这个文件&#xff0c;这就是经常看到一些 PHP 网页点击的结果却是下载…

OSI七层模型、TCP/IP五层模型理解(个人解读,如何理解网络模型)

OSI七层模型 七层模型&#xff0c;亦称OSI&#xff08;Open System Interconnection&#xff09;。参考模型是国际标准化组织&#xff08;ISO&#xff09;制定的一个用于计算机或通信系统间互联的标准体系&#xff0c;一般称为OSI参考模型或七层模型。它是一个七层的、抽象的模…

航片卫星影像局部几何纠偏-道路错位校正

原图道路错位如下图所示&#xff1a; 局部几何纠偏结果如下图所示&#xff1a; 操作视频教程&#xff1a; MCM智拼图软件V8.5-局部位置纠偏-几何校正-PS联动_哔哩哔哩_bilibili

11 c++版本的贪吃蛇

前言 呵呵 这大概是 大学里面的 c 贪吃蛇了吧 有一些 面向对象的理解, 但是不多 最近 因为想要 在单片机上面移植一下 贪吃蛇, 所以 重新拿出了一下 这份代码 然后 将它更新为 c 版本, 还是 用了一些时间 这里 具体的实现 就不赘述, 仅仅是 发一下代码 以及 具体的使用…

数据结构中的栈和队列(附实际案例代码)

1.栈和队列的定义和特点 栈&#xff08;Stack&#xff09;和队列&#xff08;Queue&#xff09;是两种基本的数据结构&#xff0c;它们都属于线性表&#xff0c;即数据元素的存储和访问都是线性的。但它们之间也存在着一些区别。 1.1栈的特点 栈是一种后进先出&#xff08;LI…

pandas数据分析综合练习50题 - 地区房价分析

数据源 我们将使用一个公开的数据集&#xff0c;“纽约市Airbnb开放数据集”。这个数据集包含了纽约市Airbnb的上万条房源信息&#xff0c;包括价格、位置、房东信息和评论数量等字段。 获取方式1 - 本文资源文件下载 可在文章绑定资源中下载。 获取方式2 - 网页下载 直接…

上位机图像处理和嵌入式模块部署(树莓派4b用skynet实现进程通信)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 前面我们说过&#xff0c;在工业系统上面一般都是使用多进程来代替多线程。这后面&#xff0c;主要的原因还是基于安全的考虑。毕竟一个系统里面&a…