uniapp视频播放器(h5+app)

news/2024/5/17 10:55:44

关于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.mrgr.cn/p/75785337

相关文章

mysql连接不上,服务中找不到mysql

分析 因为太久没使用mysql,服务自动删除了解决 注册/安装服务 win+x,a,以管理员打开powershell(或者使用cmd,随你) # 注意此处需要引号,因为有空格 # 1. cd到mysql的可执行文件,如果记不得或者像我一样懒,直接everything搜索mysqld.exe即可 cd C:\Program Files\MySQL\My…

星趴解包教程

目录#1 提取资源文件#2 解密#3 读取资源#4 导出资源#4.1 导出单个 / 少量资源#4.2 按种类导出资源#5 资源去重(可选) 本篇文章偏小白向,有一定基础的可以选择性阅读 本文仅供学习交流使用,请勿用于商业用途。更新至 2024.5.2, 星趴版本号 v1.2.3_20240430_123a#1 提取资源文…

快速了解Django:核心概念解析与实践指南

title: 快速了解Django&#xff1a;核心概念解析与实践指南 date: 2024/5/1 20:31:41 updated: 2024/5/1 20:31:41 categories: 后端开发 tags: Django核心路由系统视图系统ORM管理中间件Web框架登录装饰器 第一章&#xff1a;Django简介 背景和发展历程&#xff1a; Djan…

站立会议和燃尽图10

站立会议和燃尽图10 一、小组情况 组长:李宏威 组员:董泽豪 队名:隐约雷名 二、Scrum例会 时间:2024年4月29日 出席人员:李宏威,董泽豪 要求1 工作照片要求2 时间跨度 2024年4月29日 7:00 至 2024年4月29日 7:20 共计 20 分钟 要求3 地点 石家庄铁道大学 要求4 立会内容包…

【深耕 Python】Data Science with Python 数据科学(17)Scikit-learn机器学习(二)

写在前面 关于数据科学环境的建立&#xff0c;可以参考我的博客&#xff1a; 【深耕 Python】Data Science with Python 数据科学&#xff08;1&#xff09;环境搭建 往期数据科学博文一览&#xff1a; 【深耕 Python】Data Science with Python 数据科学&#xff08;2&…

站立会议和燃尽图09

站立会议和燃尽图09 一、小组情况 组长:李宏威 组员:董泽豪 队名:隐约雷名 二、Scrum例会 时间:2024年4月21日 出席人员:李宏威,董泽豪 要求1 工作照片要求2 时间跨度 2024年4月28日 7:00 至 2024年4月28日 7:20 共计 20 分钟 要求3 地点 石家庄铁道大学 要求4 立会内容包…

vulnhub靶场之FunBox-1

一.环境搭建 1.靶场描述 Boot2Root ! This is a reallife szenario, but easy going. You have to enumerate and understand the szenario to get the root-flag in round about 20min. This VM is created/tested with Virtualbox. Maybe it works with vmware. If you n…

重定义大语言模型的记忆能力:对抗性压缩如何挑战现有测量法

DeepVisionary 每日深度学习前沿科技推送&顶会论文分享&#xff0c;与你一起了解前沿深度学习信息&#xff01; Rethinking LLM Memorization through the Lens of Adversarial Compression 引言&#xff1a;探索大型语言模型的记忆能力 在当今信息时代&#xff0c;大型…

Elasticsearch:理解近似最近邻 (ANN) 算法

作者&#xff1a;来自 Elastic Elastic Platform Team 如果你是在互联网出现之前长大的&#xff0c;你会记得找到新喜好并不总是那么容易。我们是在无意中听到收音机里的新乐队时发现他们的&#xff0c;是因为忘了换频道偶然看到一个新电视节目的&#xff0c;也是几乎完全依据游…

jsrpc获取瑞数请求后缀和cookie

jsrpc获取瑞数请求后缀和cookie 记得加入我们的学习群:961566389 点击链接加入群聊:https://h5.qun.qq.com/s/62P0xwrCNO 1.分析xhr 每次请求都能看到会携带一个请求后缀uB04BPdr:以及每次请求都会更换cookie下的mEsoE3ffu2LGP:这两个就是需要逆向的参数。 2.调试 因为使用j…

spring boot3单模块项目工程搭建-下(个人开发模板)

⛰️个人主页: 蒾酒 &#x1f525;系列专栏&#xff1a;《spring boot实战》 目录 写在前面 上文衔接 常用依赖介绍以及整合 web组件 测试组件 样板代码生成 数据库连接器 常用工具包 面向切面编程 ORM框架 数据连接池 接口测试、文档导出 缓存中间件 参数校…

[转帖]华为鲲鹏930归来,ARM成为服务器趋势

https://zhuanlan.zhihu.com/p/675438893 今年8月,Mate60搭载的麒麟9000S归来,12月3日,笔记本L420搭载了麒麟9006C也已经上市;当年数据中心CPU领域叱咤风云的鲲鹏920,什么时候推出下一代? 2023年12月29日,华为云鲲鹏通用计算增强型实例kC2正式开启公测。官方产品鲲鹏92…

Gradformer: 通过图结构归纳偏差提升自注意力机制的图Transformer

这是4月刚刚发布在arxiv上的论文,介绍了一种名为“Gradformer”的新型图Transformer,它在自注意力机制中引入了指数衰减掩码。以下是主要创新点:指数衰减掩码: Gradformer在其自注意力模块中集成了衰减掩码。该掩码随着图结构中节点之间的距离减小而呈指数递减。这种设计使…

Ubuntu 20.04下安装Samba(Cifs/Smb)

接上一篇,本篇记录一下Ubuntu下Samba的安装配置,windows下的共享目录的设置有很多文章,这里就不说了。Samba是在Linux和UNIX系统上实现SMB协议的一个免费软件,我们可以使用apt安装,也可以去官网下载软件或者源码:apt安装如果是使用apt,那么安装就方便很多了:  #安装s…

从零开始安装 stable diffusion webui v1.9.3 (windows10)

从零开始安装 stable diffusion webui v1.9.3 (windows10) CUDA 安装 CUDA 12.1 | https://developer.nvidia.com/cuda-toolkit-archive CUDNN 8.x | https://developer.nvidia.com/rdp/cudnn-archive 安装路径 F:/CUDA/v12.1 安装git git官网 | https://git-scm.com/ 安…

树莓派点亮LED灯

简介 使用GPIO Zero library 的 Python库实现点亮LED灯。接线 树莓派引脚参考图如下&#xff1a; LED正极 接GPIO17 LED负极 接GND 权限 将你的用户加到gpio组中&#xff0c; 否则无法控制GPIO sudo usermod -a -G gpio 代码 from gpiozero import LED from time impor…

《自动机理论、语言和计算导论》阅读笔记:p215-p351

《自动机理论、语言和计算导论》学习第 11 天,p215-p351总结,总计 37 页。 一、技术总结 1.constrained problem 2.Fermats lats theorem Fermats Last Theorem states that no three positive integers a, b and c satisfy the equation a^n + b^n = c^n for any integer v…

018、Python+fastapi,第一个Python项目走向第18步:ubuntu24.04 安装cuda和pytorch环境

一、说明 我们安装了pytorch环境之后&#xff0c;会用yolo v9 来测试一下&#xff0c;看8g 显存能不能跑下来&#xff0c;上次用无影云电脑&#xff0c;4cpu8g内存直接爆了&#xff0c;云电脑也死机了&#xff0c;提示一直占用内存不释放&#xff0c;我自己的云电脑不能占用内…

在UI界面中播放视频_unity基础开发教程

在UI界面中播放视频_unity基础开发教程 前言操作步骤结语 前言 之前我写过一篇在场景中播放视频的文章&#xff0c;但是在开发中有时候也会在UI的界面中播放视频&#xff0c;这期我们做一下在UI的界面中播放视频。 操作步骤 首先在场景中创建一个Raw Image&#xff0c;UI->…

Akima算法

测量数据的内插已有各种方法,如线性内插、多项式内插、样条函数插值等,但这里的Akima插值法具有独特的优点。线性内插只顾及其附近两点的影响。多项式内插时,低阶多项式由于参数较少,内插精度很低,而使用高阶多项式又会使解不稳定,出现“龙格”现象,即内插函数在插值点与实际数…