当前位置: 首页 > news >正文

鸿蒙4.0实战教学—基础ArkTS(简易视频播放器)

构建主界面

主界面由视频轮播模块和多个视频列表模块组成,效果图如图:

VideoData.ets中定义的视频轮播图数组SWIPER_VIDEOS和视频列表图片数组HORIZONTAL_VIDEOS。

// VideoData.ets
import { HorizontalVideoItem } from './HorizontalVideoItem';
import { SwiperVideoItem } from './SwiperVideoItem';export const SWIPER_VIDEOS: SwiperVideoItem[] = [new SwiperVideoItem($r('app.media.banner1')),new SwiperVideoItem($r('app.media.banner2')),new SwiperVideoItem($r('app.media.banner3'))
];export const HORIZONTAL_VIDEOS: HorizontalVideoItem[] = [new HorizontalVideoItem(1, $r('app.media.video_list0'), '视频1'),new HorizontalVideoItem(2, $r('app.media.video_list1'), '视频2'),new HorizontalVideoItem(3, $r('app.media.video_list2'), '视频3')
];

IndexSwiper.ets文件中定义的轮播图子组件SwiperVideo,点击轮播图片,页面跳转到视频播放页面,并携带本地视频flag,效果图如图:

// IndexSwiper.ets
@Component
export struct SwiperVideo {build() {Column() {Swiper() {ForEach(SWIPER_VIDEOS, (item: SwiperVideoItem) => {SwiperItem({ imageSrc: item.image, source: $rawfile('videoTest.mp4') })}, (item: SwiperVideoItem) => JSON.stringify(item))}.autoPlay(true)}// 样式设置...}
}@Component
struct SwiperItem {private imageSrc: Resource = $r('app.string.empty');private source: Resource = $r('app.string.empty');private paramItem: ParamItem = new ParamItem();...build() {// 跳转一:使用Navigator组件跳转到视频播放界面Navigator({ target: SECOND_PAGE, type: NavigationType.Push }) {Image(this.imageSrc).borderRadius(MARGIN_FONT_SIZE.FIRST_MARGIN)}.params(this.paramItem)}
}

IndexModule.ets文件中定义的视频列表图片子组件VideoModule,点击子组件中的图片,页面跳转到视频播放页面,并携带网络视频flag,效果图如图:

// IndexModule.ets
@Component
export struct VideoModule {private moduleName: string = '';build() {Column() {// 视频列表上方的文本信息...// 视频列表组件List({ space: MARGIN_FONT_SIZE.FIRST_MARGIN }) {ForEach(HORIZONTAL_VIDEOS, (item: HorizontalVideoItem) => {ListItem() {HorizontalItem({imageSrc: item.image,source: NET,videoName: item.name})}}, (item: HorizontalVideoItem) => JSON.stringify(item))}// 设置列表横向排列.listDirection(Axis.Horizontal)}// 样式设置...}
}@Component
struct HorizontalItem {private imageSrc: Resource = $r('app.string.empty');private source: string = '';private videoName: string = '';build() {// 跳转二:使用route跳转到视频播放界面Column() {Image(this.imageSrc).width(MARGIN_FONT_SIZE.SEVENTH_MARGIN).height(MARGIN_FONT_SIZE.SIXTH_MARGIN).onClick(() => {router.pushUrl({url: SECOND_PAGE,params: { source: this.source }});})...}.justifyContent(FlexAlign.Center)}
}

在SimpleVideoIndex.ets主界面中引用SwiperVideo和VideoModule子组件。

// SimpleVideoIndex.ets
@Entry
@Component
struct SimpleVideoIndex {build() {Column({ space: MARGIN_FONT_SIZE.FOURTH_MARGIN }) {// 视频轮播组件SwiperVideo()List() {ForEach(LIST, (item: string) => {ListItem() {VideoModule({ moduleName: item }).margin({ top: MARGIN_FONT_SIZE.FIRST_MARGIN })}}, (item: string) => JSON.stringify(item))}.listDirection(Axis.Vertical).margin({ top: MARGIN_FONT_SIZE.THIRD_MARGIN })}...}
}

构建视频播放界面

VideoPlayer.ets其中定义了视频播放子组件VideoPlayer ,onPrepared回调方法中可以获取视频总时长,onUpdate回调方法中可实时获取到视频播放的当前时间戳,onFinish是视频播放结束后的回调方法,onError是视频播放出错的回调方法。

// VideoPlayer.ets
@Component
export struct VideoPlayer {private source: string | Resource = '';private controller: VideoController = new VideoController();private previewUris: Resource = $r('app.media.preview');@Provide currentTime: number = 0;@Provide durationTime: number = 0;@Provide durationStringTime: string = START_TIME;@Provide currentStringTime: string = START_TIME;@Consume isPlay: boolean;@Consume isOpacity: boolean;@Consume flag: boolean;@Consume isLoading: boolean;@Consume progressVal: number;build() {Column() {Video({src: this.source,previewUri: this.previewUris,controller: this.controller}).width(ALL_PERCENT).height(STRING_PERCENT.NINETY_PERCENT).controls(false).autoPlay(false).objectFit(ImageFit.Contain).loop(false).onUpdate((event) => {if (event) {this.currentTime = event.time;this.currentStringTime = changeSliderTime(this.currentTime);}}).onPrepared((event) => {this.prepared(event?.duration);}).onFinish(() => {this.finish();}).onError(() => {prompt.showToast({duration: COMMON_NUM_DURATION,message: MESSAGE});})VideoSlider({ controller: this.controller })}}...
}

在自定义组件VideoPlayer底部使用了自定义子组件VideoSlider,VideoSlider自定义组件中显示和控制视频播放进度,效果图如图:

// VideoPlaySlider.ets
@Component
export struct VideoSlider {@Consume isOpacity: boolean;private controller: VideoController = new VideoController();@Consume currentStringTime: string;@Consume currentTime: number;@Consume durationTime: number;@Consume durationStringTime: string;@Consume isPlay: boolean;@Consume flag: boolean;@Consume isLoading: boolean;@Consume progressVal: number;build() {Row({ space: MARGIN_FONT_SIZE.FIRST_MARGIN }) {...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) => {this.sliderOnchange(value, mode);})...}.opacity(this.isOpacity ? DEFAULT_OPACITY : 1)...}...
}

在VideoController.ets中的视频控制和回调的相关方法。

// VideoControll.ets
export function changeSliderTime(value: number): string {let second: number = value % COMMON_NUM_MINUTE;let min: number = 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;
}

在SimpleVideoPlay.ets播放界面,引用VideoPlayer子组件,并在视频播放页面使用堆叠容器,在视频播放画面中心堆叠控制、视频加载图标,效果图如图:

// SimpleVideoPlay.ets
@Entry
@Component
struct Play {// 取到Index页面跳转来时携带的source对应的数据。private source: string = (router.getParams() as Record<string, Object>).source as string;private startIconResource: Resource = $r('app.media.ic_public_play');private backIconResource: Resource = $r('app.media.ic_back');@Provide isPlay: boolean = false;@Provide isOpacity: boolean = false;controller: VideoController = new VideoController();@Provide isLoading: boolean = false;@Provide progressVal: number = 0;@Provide flag: boolean = false;...onPageHide() {this.controller.pause();}build() {Column() {// 顶部返回以及标题...Stack() {// 不同的播放状态渲染不同得控制图片if (!this.isPlay && !this.isLoading) {Image(this.startIconResource).width(MARGIN_FONT_SIZE.FIFTH_MARGIN).height(MARGIN_FONT_SIZE.FIFTH_MARGIN)// 同一容器中兄弟组件显示层级关系,z值越大,显示层级越高 用于控制图片在视频上。.zIndex(STACK_STYLE.IMAGE_Z_INDEX)}if (this.isLoading) {Progress({value: STACK_STYLE.PROGRESS_VALUE,total: STACK_STYLE.PROGRESS_TOTAL,type: ProgressType.ScaleRing}).color(Color.Grey).value(this.progressVal).width(STACK_STYLE.PROGRESS_WIDTH).style({strokeWidth: STACK_STYLE.PROGRESS_STROKE_WIDTH,scaleCount: STACK_STYLE.PROGRESS_SCALE_COUNT,scaleWidth: STACK_STYLE.PROGRESS_SCALE_WIDTH}).zIndex(STACK_STYLE.PROGRESS_Z_INDEX)}VideoPlayer({source: this.source,controller: this.controller}).zIndex(0)}}.height(ALL_PERCENT).backgroundColor(Color.Black)}
}

本文主要是对鸿蒙开发中基础ArkTS语言的运用实操,更多的鸿蒙开发实操技术学习,可以前往主页学习更多的鸿蒙核心技术。下面是分享一份鸿蒙开发技术学习路线(略缩图)

高清完整版保存主页找我

最后

使用ArkTS语言实现视频播放器,主要包括主界面和视频播放界面,效果图如下:

相关文章:

鸿蒙4.0实战教学—基础ArkTS(简易视频播放器)

构建主界面 主界面由视频轮播模块和多个视频列表模块组成&#xff0c;效果图如图&#xff1a; VideoData.ets中定义的视频轮播图数组SWIPER_VIDEOS和视频列表图片数组HORIZONTAL_VIDEOS。 // VideoData.ets import { HorizontalVideoItem } from ./HorizontalVideoItem; impo…...

4. 深入 Python 流程控制

​​​​​​ 4. 深入 Python 流程控制 除了前面介绍的 while 语句&#xff0c;Python 还从其它语言借鉴了一些流程控制功能&#xff0c;并有所改变。 4.1. if 语句 也许最有名的是 if 语句。例如: >>> x int(raw_input("Please enter an integer: "))…...

2000-2022年上市公司股票流动性指标数据/股票流动性Amihud(原始数据+计算代码+计算结果)

2000-2022年上市公司股票流动性指标数据/股票流动性Amihud&#xff08;原始数据计算代码计算结果&#xff09; 1、时间&#xff1a;2000-2022年 3、指标&#xff1a;证券代码_没有单位、交易日期_没有单位、日个股交易金额_元、考虑现金红利再投资的日个股回报率_没有单位、交…...

Unity 数据存储PlayerPrefs管理类

Unity 数据存储PlayerPrefs管理类 Unity 数据存储PlayerPrefs管理类实现存取实体类对象存储格式为Json格式Singleton.csInventoryEntity.csDataManager.cs用法如下 Unity 数据存储PlayerPrefs管理类 实现存取实体类对象 存储格式为Json格式 源码如下&#xff1a; Singleton…...

一篇文章学会如何使用 NestJS 过滤器处理系统全局异常情况

前言 在实际的应用开发中&#xff0c;你或许遇到过异常处理机制不统一或错误信息展示混乱的现象。为了解决这些问题&#xff0c;NestJS提供了一个优雅的解决方案&#xff1a;过滤器&#xff08;Filter&#xff09;。本文将从实际出发&#xff0c;向你介绍NestJS过滤器的基本概…...

ubuntu 守护进程 supervisor

# 安装 apt-get install supervisor# 检查 echo_supervisord_conf# 查看配置文件所在位置 # [include] # files /etc/supervisor/conf.d/*.conf ps -ef | grep supervisorcd /etc/supervisor/conf.d/lscat frp.conf[program:frp] command /data/work/frp/frpc -c /data/work/…...

SparkStreaming_window_sparksql_reids

1.5 window 滚动窗口滑动窗口 window操作就是窗口函数。Spark Streaming提供了滑动窗口操作的支持&#xff0c;从而让我们可以对一个滑动窗口内的数据执行计算操作。每次掉落在窗口内的RDD的数据&#xff0c;会被聚合起来执行计算操作&#xff0c;然后生成的RDD&#xff0c;会…...

爬虫工作量由小到大的思维转变---<第二十四章 Scrapy的`统计数据`收集stats collection ---12月26日补>

前言: 前两篇是讲的数据诊断分析,还有一篇深挖解决内存泄漏的文章,目前我还没整理汇编出来;但是,想到分析问题的时候,忽然觉得爬虫的数据统计好像也挺重要;于是,心血来潮准备来插一篇这个------让大家对日常scrapy爬的数据,做到心里有数!不必自己去搅破脑汁捣腾日志,敲计算器了…...

Kafka:本地设置

这是设置 Kafka 将数据从 Elasticsearch 发布到 Kafka 主题的三部分系列的第一部分;该主题将被 Neo4j 使用。第一部分帮助您在本地设置 Kafka。第二部分将讨论如何设置Elasticsearch将数据发布到Kafka主题。最后 将详细介绍如何使用连接器订阅主题并使用数据。 Kafka Kafka 是…...

.NetCore NPOI 读取excel内容及单元格内图片

由于数据方提供的数据在excel文件中不止有文字内容还包含图片信息&#xff0c;于是编写相关测试代码&#xff0c;读取excel文件内容及图片信息. 本文使用的是 NPOI-2.6.2 版本&#xff0c;此版本持.Net4.7.2;.NetStandard2.0;.NetStandard2.1;.Net6.0。 测试文档内容&#xf…...

TCP/UDP协议

1. 请解释TCP和UDP的主要区别。 TCP和UDP都是位于传输层的协议&#xff0c;具有不同的特点和应用场景。以下是它们的主要区别&#xff1a; 连接方式&#xff1a;TCP是面向连接的协议&#xff0c;这意味着在数据传输之前需要先建立连接。这通常通过三次握手来建立连接&#xff…...

3D 渲染如何帮助电商促进销售?

在线工具推荐&#xff1a; 3D数字孪生场景编辑器 - GLTF/GLB材质纹理编辑器 - 3D模型在线转换 - Three.js AI自动纹理开发包 - YOLO 虚幻合成数据生成器 - 三维模型预览图生成器 - 3D模型语义搜索引擎 3D 渲染图像因其高转化率而成为亚马逊卖家的最新趋势。它是电子商务平…...

使用栈求表达式的值【数据结构】

中缀表达式转后缀表达式 转换流程&#xff1a; 初始化一个运算符栈。自左向右扫描中缀表达式&#xff0c;当扫描到操作数时直接连接到后缀表达式上。当扫描到操作符时&#xff0c;和运算符栈栈顶的操作符进行比较。如果比栈顶运算符高&#xff0c;则入栈。如果比栈顶运算符低…...

{MySQL}索引事务和JDBC

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、索引1.1索引是什么1.2作用1.3代码 二、事务2.1什么是事务2.2使用 三.JDBC总结 前言 接着上次&#xff0c;继续讲下MySQL 提示&#xff1a;以下是本篇文章正…...

Qt designer界面和所有组件功能的详细介绍(全!!!)

PyQt5和Qt designer的详细安装教程&#xff1a;https://blog.csdn.net/qq_43811536/article/details/135185233?spm1001.2014.3001.5501 目录 1. 界面介绍2. Widget Box 常用组件2.1 Layouts&#xff08;布局&#xff09;2.2 Spacers&#xff08;间隔器&#xff09;2.3 Item V…...

mysql_存储过程

举例子 createdefiner root% procedure insert_batch_test(IN START int(10), IN max_num int(10)) BEGINDECLAREi INT DEFAULT 0;SET autocommit 0;REPEATSET i i 1;INSERT INTO test (std, score)VALUES (CEILING(RAND() * 10 100), CEILING(RAND() * 50 50));UNTIL i …...

uboot学习及内核更换_incomplete

官方文档 在前面 文章目录 uboot常见命令学习环境变量网络控制台uboot标准启动其他 升级uboot或内核bin和uimg以及booti和bootm的区别制作uImage更换内核更换uboot后续计划 uboot常见命令学习 环境变量 Environment Variables环境变量 autostart 如果值为yes&#xff0c;则会…...

KVM 自动化脚本的使用及热/冷迁移

一、介绍 目录结构介绍 [rootkvm-server kvm]# tree -L 2 . ├── control # 控制脚本目录 │ ├── KVMInstall.sh # kvm服务安装脚本 │ ├── VMHost.sh # kvm虚拟机克隆脚本 │ └── VMTemplate.sh # kvm模板机安装脚本 ├── mount # 此目录保持为空&…...

Unity中Shader裁剪空间推导(在Shader中使用)

文章目录 前言一、在Shader中使用转化矩阵1、在顶点着色器中定义转化矩阵2、用 UNITY_NEAR_CLIP_VALUE 区分平台矩阵3、定义一个枚举用于区分当前是处于什么相机 二、我们在DirectX平台下&#xff0c;看看效果1、正交相机下2、透视相机下3、最终代码 前言 在上一篇文章中&…...

ES的使用(Elasticsearch)

ES的使用&#xff08;Elasticsearch&#xff09; es是什么&#xff1f; es是非关系型数据库&#xff0c;是分布式文档数据库&#xff0c;本质上是一个JSON 文本 为什么要用es? 搜索速度快&#xff0c;近乎是实时的存储、检索数据 怎么使用es? 1.下载es的包&#xff08;环境要…...

Cursor实现用excel数据填充word模版的方法

cursor主页&#xff1a;https://www.cursor.com/ 任务目标&#xff1a;把excel格式的数据里的单元格&#xff0c;按照某一个固定模版填充到word中 文章目录 注意事项逐步生成程序1. 确定格式2. 调试程序 注意事项 直接给一个excel文件和最终呈现的word文件的示例&#xff0c;…...

ffmpeg(四):滤镜命令

FFmpeg 的滤镜命令是用于音视频处理中的强大工具&#xff0c;可以完成剪裁、缩放、加水印、调色、合成、旋转、模糊、叠加字幕等复杂的操作。其核心语法格式一般如下&#xff1a; ffmpeg -i input.mp4 -vf "滤镜参数" output.mp4或者带音频滤镜&#xff1a; ffmpeg…...

DIY|Mac 搭建 ESP-IDF 开发环境及编译小智 AI

前一阵子在百度 AI 开发者大会上&#xff0c;看到基于小智 AI DIY 玩具的演示&#xff0c;感觉有点意思&#xff0c;想着自己也来试试。 如果只是想烧录现成的固件&#xff0c;乐鑫官方除了提供了 Windows 版本的 Flash 下载工具 之外&#xff0c;还提供了基于网页版的 ESP LA…...

UR 协作机器人「三剑客」:精密轻量担当(UR7e)、全能协作主力(UR12e)、重型任务专家(UR15)

UR协作机器人正以其卓越性能在现代制造业自动化中扮演重要角色。UR7e、UR12e和UR15通过创新技术和精准设计满足了不同行业的多样化需求。其中&#xff0c;UR15以其速度、精度及人工智能准备能力成为自动化领域的重要突破。UR7e和UR12e则在负载规格和市场定位上不断优化&#xf…...

保姆级教程:在无网络无显卡的Windows电脑的vscode本地部署deepseek

文章目录 1 前言2 部署流程2.1 准备工作2.2 Ollama2.2.1 使用有网络的电脑下载Ollama2.2.2 安装Ollama&#xff08;有网络的电脑&#xff09;2.2.3 安装Ollama&#xff08;无网络的电脑&#xff09;2.2.4 安装验证2.2.5 修改大模型安装位置2.2.6 下载Deepseek模型 2.3 将deepse…...

面向无人机海岸带生态系统监测的语义分割基准数据集

描述&#xff1a;海岸带生态系统的监测是维护生态平衡和可持续发展的重要任务。语义分割技术在遥感影像中的应用为海岸带生态系统的精准监测提供了有效手段。然而&#xff0c;目前该领域仍面临一个挑战&#xff0c;即缺乏公开的专门面向海岸带生态系统的语义分割基准数据集。受…...

tomcat入门

1 tomcat 是什么 apache开发的web服务器可以为java web程序提供运行环境tomcat是一款高效&#xff0c;稳定&#xff0c;易于使用的web服务器tomcathttp服务器Servlet服务器 2 tomcat 目录介绍 -bin #存放tomcat的脚本 -conf #存放tomcat的配置文件 ---catalina.policy #to…...

抽象类和接口(全)

一、抽象类 1.概念&#xff1a;如果⼀个类中没有包含⾜够的信息来描绘⼀个具体的对象&#xff0c;这样的类就是抽象类。 像是没有实际⼯作的⽅法,我们可以把它设计成⼀个抽象⽅法&#xff0c;包含抽象⽅法的类我们称为抽象类。 2.语法 在Java中&#xff0c;⼀个类如果被 abs…...

协议转换利器,profinet转ethercat网关的两大派系,各有千秋

随着工业以太网的发展&#xff0c;其高效、便捷、协议开放、易于冗余等诸多优点&#xff0c;被越来越多的工业现场所采用。西门子SIMATIC S7-1200/1500系列PLC集成有Profinet接口&#xff0c;具有实时性、开放性&#xff0c;使用TCP/IP和IT标准&#xff0c;符合基于工业以太网的…...

k8s从入门到放弃之HPA控制器

k8s从入门到放弃之HPA控制器 Kubernetes中的Horizontal Pod Autoscaler (HPA)控制器是一种用于自动扩展部署、副本集或复制控制器中Pod数量的机制。它可以根据观察到的CPU利用率&#xff08;或其他自定义指标&#xff09;来调整这些对象的规模&#xff0c;从而帮助应用程序在负…...