HarmonyOS ArkTS Video组件的使用(七)

概述

在手机、平板或是智慧屏这些终端设备上,媒体功能可以算作是我们最常用的场景之一。无论是实现音频的播放、录制、采集,还是视频的播放、切换、循环,亦或是相机的预览、拍照等功能,媒体组件都是必不可少的。以视频功能为例,在应用开发过程中,我们需要通过ArkUI提供的Video组件为应用增加基础的视频播放功能。借助Video组件,我们可以实现视频的播放功能并控制其播放状态。常见的视频播放场景包括观看网络上的较为流行的短视频,也包括查看我们存储在本地的视频内容。

Video组件用法介绍

Video组件参数介绍

Video组件的接口表达形式为:

Video(value: {src?: string | Resource, currentProgressRate?: number | string |PlaybackSpeed, previewUri?: string |PixelMap | Resource, controller?: VideoController})

其中包含四个可选参数,src、currentProgressRate、previewUri和controller。

  • src表示视频播放源的路径,可以支持本地视频路径和网络路径。使用网络地址时,如https,需要注意的是需要在module.json5文件中申请网络权限。在使用本地资源播放时,当使用本地视频地址我们可以使用媒体库管理模块medialibrary来查询公共媒体库中的视频文件,示例代码如下:
import mediaLibrary from '@ohos.multimedia.mediaLibrary';async queryMediaVideo() {let option = {// 根据媒体类型检索selections: mediaLibrary.FileKey.MEDIA_TYPE + '=?',// 媒体类型为视频selectionArgs: [mediaLibrary.MediaType.VIDEO.toString()]};let media = mediaLibrary.getMediaLibrary(getContext(this));// 获取资源文件const fetchFileResult = await media.getFileAssets(option);// 以获取的第一个文件为例获取视频地址let fileAsset = await fetchFileResult.getFirstObject();this.source = fileAsset.uri
}

为了方便功能演示,示例中媒体资源需存放在resources下的rawfile文件夹里。

  • currentProgressRate表示视频播放倍速,其参数类型为number,取值支持0.75,1.0,1.25,1.75,2.0,默认值为1.0倍速;
  • previewUri表示视频未播放时的预览图片路径;
  • controller表示视频控制器。

参数的具体描述如下表:

在这里插入图片描述
下面我们通过具体的例子来说明参数的使用方法,我们选择播放本地视频,视频未播放时的预览图片路径也为本地,代码实现如下:

@Component
export struct VideoPlayer {private source: string | Resource;private controller: VideoController;private previewUris: Resource = $r('app.media.preview');...build() {Column() {Video({src: this.source,previewUri: this.previewUris,controller: this.controller})...VideoSlider({ controller: this.controller })}}
}

效果如下:

在这里插入图片描述

Video组件属性介绍

除了支持组件的尺寸设置、位置设置等通用属性外,Video组件还支持是否静音、是否自动播放、控制栏是否显示、视频显示模式以及单个视频是否循环播放五个私有属性。

在这里插入图片描述

其中,objectFit 中视频显示模式包括Contain、Cover、Auto、Fill、ScaleDown、None 6种模式,默认情况下使用ImageFit.Cover(保持宽高比进行缩小或者放大,使得图片两边都大于或等于显示边界),其他效果(如自适应显示、保持原有尺寸显示、不保持宽高比进行缩放等)可以根据具体使用场景/设备来进行选择。

在Codelab示例中体现了controls、autoplay和loop属性的配置,示例代码如下:

@Component
export struct VideoPlayer {private source: string | Resource;private controller: VideoController;...build() {Column() {Video({controller: this.controller}).controls(false) //不显示控制栏 .autoPlay(false) // 手动点击播放 .loop(false) // 关闭循环播放 ...}}
}

Video组件回调事件介绍

Video组件能够支持常规的点击、触摸等通用事件,同时也支持onStart、onPause、onFinish、onError等事件,具体事件的功能描述见下表:

在这里插入图片描述
在Codelab中我们以更新事件、准备事件、失败事件以及点击事件为回调为例进行演示,代码实现如下:

Video({ ... }).onUpdate((event) => {this.currentTime = event.time;this.currentStringTime = changeSliderTime(this.currentTime); //更新事件 }).onPrepared((event) => {prepared.call(this, event); //准备事件 }).onError(() => {prompt.showToast({duration: COMMON_NUM_DURATION, //播放失败事件 message: MESSAGE});...})

其中,onUpdate更新事件在播放进度变化时触发,从event中可以获取当前播放进度,从而更新进度条显示事件,比如视频播放时间从24秒更新到30秒。onError事件在视频播放失败时触发,在CommonConstants.ets中定义了常量类MESSAGE,所以在视频播放失败时会显示“请检查网络”。

const MESSAGE: string = '请检查网络'  

自定义控制器的组成与实现

自定义控制器的组成

Video组件的原生控制器样式相对固定,当我们对页面的布局色调的一致性有所要求,或者在拖动进度条的同时需要显示其百分比进度时,原生控制器就无法满足需要了。如下图右侧的效果需要使用自定义控制器实现,接下来我们看一下自定义控制器的组成。

在这里插入图片描述

为了实现自定义控制器的进度显示等功能,我们需要通过Row容器实现控制器的整体布局,然后借由Text组件来显示视频的播放起始时间、进度时间以及视频总时长,最后通过滑动进度条Slider组件来实现视频进度条的效果,代码如下:

@Component
export struct VideoSlider {...build() {Row(...) {Image(...)Text(...)Slider(...)Text(...)}...}
}

自定义控制器的实现

自定义控制器容器内嵌套了视频播放时间Text组件、滑动器Slider组件以及视频总时长Text组件 3个横向排列的组件,其中Text组件在之前的基础组件课程中已经有过详细介绍,这里就不再进行赘述。需要强调的是两个Text组件显示的时长是由Slider组件的onChange(callback: (value: number, mode: SliderChangeMode) => void)回调事件来进行传递的,而Text组件的数值与视频播放进度数值value则是通过@Provide与 @Consume装饰器进行的数据联动,实现效果可见图片下方黑色控制栏部分,具体代码步骤及代码如下:

获取/计算视频时长

export function prepared(event) {this.durationTime = event.duration;let second: number = event.duration % COMMON_NUM_MINUTE;let min: number = parseInt((event.duration / COMMON_NUM_MINUTE).toString());let head = min < COMMON_NUM_DOUBLE ? `${ZERO_STR}${min}` : min;let end = second < COMMON_NUM_DOUBLE ? `${ZERO_STR}${second}` : second;this.durationStringTime = `${head}${SPLIT}${end}`;...
};

设置进度条参数及属性

Slider({value: this.currentTime,min: 0,max: this.durationTime,step: 1,style: SliderStyle.OutSet
}).blockColor($r('app.color.white')).width(STRING_PERCENT.SLIDER_WITH).trackColor(Color.Gray).selectedColor($r('app.color.white')).showSteps(true).showTips(true).trackThickness(this.isOpacity ? SMALL_TRACK_THICK_NESS : BIG_TRACK_THICK_NESS).onChange((value: number, mode: SliderChangeMode) => {...})

计算当前进度播放时间及添加onUpdate回调

最后,在我们播放视频时还需要更新显示播放的时间进度,也就是左侧的Text组件。在视频开始播放前,播放时间默认为00:00,随着视频播放,时间需要不断更新为当前进度时间。所以左侧的Text组件我们不仅需要读取时间,还需要为其添加数据联动。这里,我们就是通过为Video组件添加onUpdate事件来实现的,在视频播放过程中会不断调用changeSliderTime方法获取当前的播放时间并进行计算及单位转化,从而不断刷新进度条的值,也就是控制器左侧的播放进度时间Text组件。

Video({...})....onUpdate((event) => {this.currentTime = event.time;this.currentStringTime = changeSliderTime(this.currentTime)}) 
export function changeSliderTime(value: number): string {let second: number = value % COMMON_NUM_MINUTE;let min: number = parseInt((value / COMMON_NUM_MINUTE).toString());let head = min < COMMON_NUM_DOUBLE ? `${ZERO_STR}${min}` : min;let end = second < COMMON_NUM_DOUBLE ? `${ZERO_STR}${second}` : second;let nowTime = `${head}${SPLIT}${end}`;return nowTime;
}; 

指定视频播放进度及添加onChange事件回调

如需手动进行进度条的拖动,则需要在Slider组件中指定播放进度,并为Slider组件添加onChange事件回调。Slider滑动时就会触发该事件回调,从而实现将视频定位到进度条当前刷新位置,完成时长组件渲染与视频播放进度数据联动。

Slider({...}).onChange((value: number, mode: SliderChangeMode) => {sliderOnchange.call(this, value, mode);})
export function sliderOnchange(value: number, mode: SliderChangeMode) {this.currentTime = parseInt(value.toString());this.controller.setCurrentTime(parseInt(value.toString()), SeekMode.Accurate);...
};

到这里我们就实现了自定义控制器的构建,两个Text组件显示的时长是由Slider组件的onChange回调事件来进行传递的,而Text组件的数值与视频播放进度数值value则通过是onUpdate与onChange事件并借由@Provide @Consume装饰器进行的数据联动。

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

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

相关文章

C 语言嵌套结构体

C 语言嵌套结构体 C为我们提供了将一个结构嵌套在另一个结构中的功能&#xff0c;从而创建复杂的数据类型。例如&#xff0c;我们可能需要在结构中存储实体员工的地址。而地址也可以包含其他信息&#xff0c;例如街道编号&#xff0c;城市&#xff0c;地区和密码。因此&#x…

CVE-2022-21661

简介 CVE-2022-21661是一个与WordPress相关的漏洞&#xff0c;涉及到SQL注入问题。该漏洞主要源于WordPress的WQ_Tax_Query类中的clean_query函数&#xff0c;可能允许攻击者通过控制传递给该函数的数据来控制生成的SQL查询&#xff0c;从而执行任意的SQL代码。 当WordPress的…

【ROS 2 进阶-MoveIt!】MoveIt!中的关键节点

所有内容请查看&#xff1a;博客学习目录_Howe_xixi的博客-CSDN博客 原文档链接&#xff1a;Docs

自动驾驶轨迹预测学习笔记

目录 VectorNet&#xff1a;自动驾驶轨迹预测 CVPR2023 轨迹预测冠军方案 QCNeXt VectorNet&#xff1a;自动驾驶轨迹预测 VectorNet&#xff1a;自动驾驶轨迹预测 - 知乎 CVPR2023 轨迹预测冠军方案 QCNeXt CVPR2023 轨迹预测冠军方案&#xff01;QCNeXt&#xff1a;新一代…

什么是索引下推

索引下推介绍 索引下推&#xff08;INDEX CONDITION PUSHDOWN&#xff0c;简称 ICP&#xff09;是在 MySQL 5.6 针对扫描二级索引的一项优化改进。总的来说是通过把索引过滤条件下推到存储引擎&#xff0c;来减少 MySQL 存储引擎访问基表的次数以及 MySQL 服务层访问存储引擎的…

持续格式刷

双击格式刷即可

专访|OpenTiny 开源社区 常浩:完成比完美更重要

前言 2023年已过大半&#xff0c;备受关注的 OpenTiny*开源之夏活动也顺利结项。开源之夏由中国科学院软件研究所发起的计划&#xff0c;目的在于鼓励在校学生积极参与开源软件的开发维护&#xff0c;推动优秀开源软件社区的繁荣发展。该活动联合各大开源社区&#xff0c;聚焦…

令人赞叹的花里胡哨的代码雨动画效果

【点我-这里送书】 本人详解 作者:王文峰,参加过 CSDN 2020年度博客之星,《Java王大师王天师》 公众号:JAVA开发王大师,专注于天道酬勤的 Java 开发问题中国国学、传统文化和代码爱好者的程序人生,期待你的关注和支持!本人外号:神秘小峯 山峯 转载说明:务必注明来源(…

element emitter broadcast向下广播 dispatch向上分派

emitter 项目使用element的emitter.js&#xff0c;做个使用记录 function broadcast(componentName, eventName, params) {this.$children.forEach(child > {const name child.$options.name;if (name componentName) {child.$emit.apply(child, [eventName].concat(para…

pytorch训练出现的bug

训练过后发现.csv文件左侧出现了几列unname和一列0&#xff0c;1&#xff0c;2。这个时候在训练就会从unname那一列开始训练。我们需要把这几列删除&#xff0c;之后再重新训练

华清远见嵌入式学习——网络编程——作业3

目录 作业要求&#xff1a;基于UDP的TFTP文件传输 代码 下载功能效果图​编辑 上传功能效果图 思维导图 模拟面试题和答案&#xff08;定期更新&#xff09; 作业要求&#xff1a;基于UDP的TFTP文件传输 完成文件的上传和下载功能 代码 #include<myhead.h>//实现…

前端Math属性方法汇总集锦

Description of Math Math 是一个内置对象&#xff0c;它拥有一些数学常数属性和数学函数方法。Math 不是一个函数对象。 Math 用于 Number 类型。它不支持 BigInt。 与其他全局对象不同的是&#xff0c;Math 不是一个构造器。Math 的所有属性与方法都是静态的。引用圆周率的写…

『heqingchun-Ubuntu系统+x86架构+编译安装ffmpeg+带有nvidia硬件加速』

Ubuntu系统x86架构编译安装ffmpeg带有nvidia硬件加速 一、准备文件 注&#xff1a;可直接下载我上传的CSDN资源&#xff0c;然后直接跳到"一"中的第"3"项"将文件按以下顺序存放"。 ffmpeg源码&#xff1a;音视频开发ffmpeg编译所需资源文件 其…

Pgsql常用命令

Postgresql数据库常用命令 1、连接数据库, 默认的用户和数据库是postgres psql -h host -p port -U user -d dbname 2、执行sql文件 psql -h ${PGHOST} -p ${PGPORT} -U ${PGUSER} -d safe_browser -f xxxx.sql \i /xxxxx/xxx/xxxxxx.sql 3、切换数据库,相当于mysql的use d…

Ajax技

Ajax的特点 异步提交&#xff1a;Ajax采用异步通信方式&#xff0c;能够在页面无需重新加载的情况下向服务器发送请求并接收响应数据&#xff0c;提升了用户体验。无需插件&#xff1a;Ajax是基于标准浏览器的Javascript和XMLHttpRequest对象实现的&#xff0c;无需安装插件或…

打开和关闭conda,激活和关闭conda,详解退出conda环境

Python编程技巧&#xff1a;详解退出conda环境 https://www.python100.com/html/110499.html # 创建虚拟环境~/anaconda3/bin/conda create -n name python3.6 # 激活虚拟环境 source ~/anaconda3/bin/activate name # 查看所有环境 conda env list # 激活虚拟环境 conda activ…

使用JVS低代码表单引擎高效管理文件,实现个性化需求

在数字化、信息化的时代&#xff0c;文件上传与管理功能已经成为了各类应用系统的标配。无论是在办公自动化、项目管理还是内容管理系统中&#xff0c;我们都希望能轻松、高效地完成文件的上传、查看和管理。JVS低代码表单引擎提供了文件类组件。无论是文件类型、大小的限制&am…

ubuntu Setforeground 前台应用切换

场景分析 有这样一个系统&#xff0c;一个服务主进程用于接收指令&#xff0c;其它服务是独立的gui 程序&#xff0c;服务进程根据命令将对应的gui 程序切换到前台。 windows 平台有Setforeground 这个api&#xff0c;可以根据进程ID&#xff0c;将某个应用的窗口切换到前台。…

SpringBoot整合Redis,redis连接池和RedisTemplate序列化

SpringBoot整合Redis 1、SpringBoot整合redis1.1 pom.xml1.2 application.yml1.3 配置类RedisConfig&#xff0c;实现RedisTemplate序列化1.4 代码测试 2、SpringBoot整合redis几个疑问&#xff1f;2.1、Redis 连接池讲解2.2、RedisTemplate和StringRedisTemplate 3、RedisTemp…

UniApp打包教程:使用HBuilder X和AppUploader完成原生App云打包和上架指南“

​ 目录 uniapp进行打包 使用上架工具appuplode进行发包 1.登录appuploder软件 2.登陆开发者App Store后台 uniapp进行打包 在HBuilder X编辑器中打开需要打包的项目&#xff0c;然后点击上面菜单栏中 发行 > 原生App-云打包&#xff0c;对以下弹出的弹窗进行内容填写 ​…