HarmonyOS开发案例:【视频播放器】

介绍

基于video、swiper和slider组件,实现简单的视频播放器,可支持海报轮播、视频播放等功能。

相关概念

  • [video组件]:视频播放组件。
  • [swiper组件]:滑动容器,提供切换子组件显示的能力。
  • [slider组件]:滑动z条组件,用来快速调节设置值,如音量、亮度等。

环境搭建

软件要求

  • [DevEco Studio]版本:DevEco Studio 3.1 Release及以上版本。
  • OpenHarmony SDK版本:API version 9及以上版本。

硬件要求

  • 开发板类型:[润和RK3568开发板]。
  • OpenHarmony系统:3.2 Release及以上版本。

环境搭建

完成本篇Codelab我们首先要完成开发环境的搭建,本示例以RK3568开发板为例,参照以下步骤进行:

  1. [获取OpenHarmony系统版本]:标准系统解决方案(二进制)。以3.2 Release版本为例:

  2. 搭建烧录环境。

    1. [完成DevEco Device Tool的安装]
    2. [完成RK3568开发板的烧录]
  3. 搭建开发环境。

    1. 开始前请参考[工具准备],完成DevEco Studio的安装和开发环境配置。
    2. 开发环境配置完成后,请参考[使用工程向导]创建工程(模板选择“Empty Ability”)。
    3. 工程创建完成后,选择使用[真机进行调测]。
    4. 鸿蒙开发指导文档:gitee.com/li-shizhen-skin/harmony-os/blob/master/README.md点击或者复制转到。

搜狗高速浏览器截图20240326151450.png

代码结构解读

本篇Codelab只对核心代码进行讲解,对于完整代码,我们会在gitee中提供。、

HarmonyOS与OpenHarmony鸿蒙文档籽料:mau123789是v直接拿

├──entry/src/main/js                          // 代码区
│  └──MainAbility   
│     ├──common
│     │  ├──constant
│     │  │  └──commonConstants.js             // 公共常量类
│     │  ├──images                            // 图片文件
│     │  └──video
│     │     └──video.mp4                      // 视频文件
│     ├──i18n
│     │  ├──en-US.json	                      // 英文国际化
│     │  └──zh-CN.json	                      // 中文国际化
│     ├──pages
│     │  ├──homePage
│     │  │  ├──homePage.css                   // 主页面样式
│     │	 │  ├──homePage.hml                   // 主页面
│     │	 │  └──homePage.js                    // 主页面逻辑
│     │  └──videoPage
│     │     ├──videoPage.css                  // 播放页面样式
│     │	    ├──videoPage.hml                  // 播放页面
│     │	    └──videoPage.js                   // 播放页面逻辑
│     └──app.js                               // 程序入口
└──entry/src/main/resource                    // 应用静态资源目录

主页面

主页面分为轮播图区域和滑动图区域两部分,效果如图所示:

轮播图使用swiper组件自动播放轮播图片,点击图片跳转到视频播放页面。

<!-- homePage.hml -->
<div class="container"><swiper class="swiper" id="swiper" index="0" autoplay='true' indicator="true"loop="true" digital="false"><image class="swiper-img" src="{{ swiperVideos[0] }}" onclick="playVideo"></image><image class="swiper-img" src="{{ swiperVideos[1] }}" onclick="playVideo"></image><image class="swiper-img" src="{{ swiperVideos[2] }}" onclick="playVideo"></image></swiper>...
</div>
// homePage.js
export default {data: {swiperVideos: [],...},// 初始化数据onInit() {...},// 跳转到视频播放页面playVideo() {router.push({url: CommonConstants.PLAY_PAGE});},
};

滑动图区域分为最近播放和为你推荐两部分,使用List组件进行纵向排列;最近播放和为你推荐中的图片使用List组件进行横向排列,可滑动图片,点击图片跳转到播放页面。

<!-- homePage.hml -->
<div class="container">...<div class="horizontal-area"><list class="todo-wrapper"><list-item for="{{ horizontal_description }}" class="todo-item" clickeffect="false"><div class="horizontal-area-div"><text class="horizontal-area-description">{{ $item }}</text><list class="todo-wrapper"><list-item for="{{ horizontal_videos }}" clickeffect="false" class="todo-item"><div class="image-area" onclick="playVideo"><image src="{{ $item.image }}"></image><text>{{ $item.name }}</text></div></list-item></list></div></list-item></list></div>
</div>
// homePage.js
export default {data: {...horizontal_description: [],horizontal_videos: []},// 初始化数据onInit() {...},// 跳转到视频播放页面playVideo() {router.push({url: CommonConstants.PLAY_PAGE});},
};

视频播放页面

视频播放页面主要分为标题栏、视频播放区域和进度条三个部分,效果如图所示:

标题栏包括返回图标和“视频”字样。

<!-- videoPage.hml -->
<div class="container"><div class="title"><image src="{{ playIcons.backSrc }}" onclick="back"></image><text>{{ $t('strings.play') }}</text></div>...
</div>
// videoPage.js
export default {data: {playIcons: {},...},// 初始化数据onInit() {this.playIcons = CommonConstants.PLAY_ICONS;...},...
};

当视频暂停时,视频区域展示暂停图标;当视频播放时,视频区域暂停图标隐藏,效果如图所示:

<!-- videoPage.hml -->
<div class="container">...<video id="video" ...></video><image class="play-image" show="{{ !isPlay }}" src="{{ playIcons.publicPlayIcon }}"></image>...
</div>
// videoPage.js
export default {data: {playIcons: {},...src: '',...isPlay: false,...},// 初始化数据onInit() {this.playIcons = CommonConstants.PLAY_ICONS;this.src = CommonConstants.VIDEO_SRC;},...
};

进度条分为播放/暂停图标和进度条(进度条左边为当前视频播放时间,进度条右边为视频总时长)两部分。

<div class="container">...<div class="progress"><div class="image-div"><image src="{{ isPlay ? playIcons.pauseIcon : playIcons.playIcon }}" onclick="startOrPause"></image></div><div class="slider-div"><text class="now-time">{{ nowTime }}</text><slider min="{{ sliderMin }}" max="{{ sliderMax }}" value="{{ sliderValue }}"mode="outset" onchange="change"></slider><text class="duration-time">{{ durationTime }}</text></div></div>
</div>
// videoPage.js
export default {data: {playIcons: {},...sliderMin: 0,sliderMax: 100,sliderValue: 0,nowTime: '00:00',duration: 0,durationTime: '00:00',isPlay: false,secondUnit: 60,zero: '0',initTime: '00:00',paddingLen: 2,milliSeconds: 1000,...},// 初始化数据onInit() {this.playIcons = CommonConstants.PLAY_ICONS;...},...
};

视频播放逻辑

视频播放器可设置是否静音播放、视频路径、是否自动播放、是否显示控制栏、是否循环播放等属性。

<!-- index.hml -->
<video id="video"muted="{{ muted }}"src="{{ src }}"autoplay="{{ autoplay }}"controls="{{ controlShow }}"loop="{{ loop }}"...
>
</video>
// index.js
data: {...videoId: 'video', // 播放器idmuted: false, // 是否静音播放src: '', // 视频地址autoplay: true, // 是否自动播放controlShow: false, // 是否显示控制栏loop: false, // 是否循环播放...
},

视频加载完成后获取视频总时长,当视频开始播放后获取视频当前播放时间(单位:秒)并更新进度条的值;拖动进度条可设置视频播放位置,点击播放/暂停图标可对视频进行控制。

<!-- index.hml -->
<video id="video"...onprepared="prepared"onstart="start"onpause="pause"onfinish="finish"ontimeupdate="timeUpdate">
</video>
...
<div class="progress"><div class="imageDiv"><image src="{{ isPlay ? playIcons.pauseIcon : playIcons.playIcon }}" onclick="startOrPause"></image></div><div class="sliderDiv">...<slider min="{{ sliderMin }}" max="{{ sliderMax }}" value="{{ sliderValue }}"mode="outset" onchange="change"></slider>...</div>
</div>
// index.js
...
// 视频准备完成
prepared(event) {this.duration = event.duration;this.durationTime = this.secondToTime(event.duration);
},// 视频开始播放
start() {this.isPlay = true;
},
// 视频暂停播放
pause() {this.isPlay = false;
},// 视频播放完成
finish() {setTimeout(() => {this.nowTime = this.initTime;this.sliderValue = this.sliderMin;}, this.milliSeconds);
},// 播放进度变化
timeUpdate(event) {if ((this.currentTime != -1) && (this.currentTime !== event.currenttime)) {return;}this.currentTime = -1;let currSliderValue = event.currenttime / this.duration * this.sliderMax;this.sliderValue = ((this.sliderValue > currSliderValue) ? this.sliderValue : currSliderValue);let currTime = this.sliderValue * this.duration / this.sliderMax;this.nowTime = this.secondToTime(Math.round(currTime));
},// 暂停或播放
startOrPause() {if (this.isPlay) {this.$element(this.videoId).pause();} else {this.$element(this.videoId).start();}
},// 拖动进度条
change(event) {this.sliderValue = event.progress;this.currentTime = Math.round(this.duration * event.progress / this.sliderMax);this.$element(this.videoId).setCurrentTime({currenttime: this.currentTime});
},
...

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

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

相关文章

秋招之路 面经

这里参考一位很厉害的前辈所分享的他的嵌入式软件工程师秋招之路&#xff0c;自己详细的读了一下他的经历以及他的分享的秋招面试和项目经验的总结。 我的嵌入式软件工程师秋招之路&#xff08;文末送福利&#xff09;_嵌入式软件工程师 刷leetcode-CSDN博客 如何在面试中介绍…

针对窗口数量多导致窗口大小显示受限制的问题,使用滚动条控制窗口

建议&#xff1a;首先观察结果展示&#xff0c;判断是否可以满足你的需求。 目录 1. 问题分析 2. 解决方案 2.1 界面设计 2.2 生成代码 2.3 源码实现 3. 结果展示 1. 问题分析 项目需要显示的窗口数量颇多&#xff0c;主界面中&#xff0c;如果一次性显示全部窗口&#x…

Web3钱包开发获取测试币-Base Sepolia(二)

Web3钱包开发获取测试币-Base Sepolia(二) ![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/b0c0ac86b04a496087471388532bc54a.png) 基于上篇 Web3钱包开发获取测试币-Polygon Mumbai(一) &#xff1a;https://suwu150.blog.csdn.net/article/details/137949473 我…

MyBatis 框架学习(I)

MyBatis 框架学习(I) 文章目录 MyBatis 框架学习(I)1. 介绍2. 准备&测试3. MyBatis 注解基础操作3.1 日志输出3.2 Insert 操作3.3 Delete 操作3.4 Update 操作3.5 Select 操作 总结 1. 介绍 之前我们学习过利用JDBC操作数据库进行项目开发&#xff0c;但我们发现它操作起来…

扫描工具nmap

介绍 说到黑客&#xff0c;知识就是力量。您对目标系统或网络的了解越多&#xff0c;可用的选项就越多。因此&#xff0c;在进行任何利用尝试之前&#xff0c;必须进行适当的枚举。 假设我们获得了一个 IP&#xff08;或多个 IP 地址&#xff09;来执行安全审计。在我们做任何…

究竟该怎么寄快递才能安全无误的送到手中呢?

最近&#xff0c;小编上班了发现有同事在吐槽快递送到手中的时间很晚了&#xff0c;比预计的时间差了很多&#xff0c;并且产品也有不同程度的损坏。这就让我们很是恼火了&#xff0c;但是细细研究后才发现有一部分的原因竟然是我们的原因才导致的寄快递出现了很多纰漏。 首先…

使用JavaScript创建数组,并对其进行冒泡排序

JavaScript创建数组方式 字面量方式&#xff1a;使用方括号 [] 来创建数组&#xff0c;并在方括号内按顺序列出数组元素。 let arr [1, 2, 3, 4, 5]; Array() 构造函数方式&#xff1a;使用 new Array() 构造函数来创建数组&#xff0c;并传入数组元素作为参数。 let arr ne…

如何使用ChatGPT仿写一篇学术论文

点击下方▼▼▼▼链接直达AIPaperPass &#xff01; AIPaperPass - AI论文写作指导平台 目录 1.仿写的目的 2.根据专业方向搜集合适的文献 3.总结想要仿写的文献 4.使用ChatGPT一步一步仿写 5.书籍介绍 AIPaperPass智能论文写作平台 深入地阅读和分析你研究领域的相关文…

汽车IVI中控开发入门及进阶(十六):carplay认证

现在有些中控采用高通的芯片如8155、8295等,实现多屏互动等,但是也有一些车型走低成本方案,比如能够实现HiCar、CarLife或者苹果Apple的Carplay等能进行手机投屏就好了。 能实现CarPlay功能通过Carplay认证,也就成了一些必须的过程,国产车规级中控芯片里,开阳有一款ARK1…

PLC_博图系列☞P_TRIG:扫描 RLO 的信号上升沿

PLC_博图系列☞P_TRIG&#xff1a;扫描 RLO 的信号上升沿 文章目录 PLC_博图系列☞P_TRIG&#xff1a;扫描 RLO 的信号上升沿背景介绍P_TRIG&#xff1a; 扫描 RLO 的信号上升沿说明参数示例 关键字&#xff1a; PLC、 西门子、 博图、 Siemens 、 P_TRIG 背景介绍 这是一…

10.Godot Input与自定义单例的使用

单例 单例是一个可以在任何一个脚本中对其进行直接访问的对象&#xff0c;分为内置单例与自定义单例。每个单例都是独一无二的对象。内置单例不是节点&#xff0c;主要成员是各类 Server&#xff0c;开发者可以使用它们直接控制游戏程序的图形与音效等内容。此外&#xff0c;还…

实现Spring底层机制(阶段1—编写自己的Spring容器,扫描包,得到bean的Class对象)

环境搭建抛出问题 1.环境搭建 1.创建maven项目 2.导入依赖 <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.org/POM/4.0.0 http://maven.ap…

代码随想录第43天|1049.最后一块石头的重量II 494. 目标和

1049.最后一块石头的重量II 1049. 最后一块石头的重量 II - 力扣&#xff08;LeetCode&#xff09; 代码随想录 (programmercarl.com) 动态规划之背包问题&#xff0c;这个背包最多能装多少&#xff1f;LeetCode&#xff1a;1049.最后一块石头的重量II_哔哩哔哩_bilibili 有…

AI-数学-高中-39空间向量-2空间向量法(法向量)

原作者视频&#xff1a;【空间向量】【一数辞典】2空间向量法&#xff08;重要&#xff09;_哔哩哔哩_bilibili 法向量&#xff08;高中阶段所有与面的关系&#xff0c;都可以通过法向量去证明和解答&#xff09;&#xff1a; 是空间解析几何的一个概念&#xff0c;垂直于平面…

京东商品详情数据采集API接口|附京东商品数据返回PHP多语言高并发

京东获得JD商品详情 API 返回值说明 item_get-获得JD商品详情 API测试 注册开通 jd.item_get 公共参数 名称类型必须描述keyString是调用key&#xff08;必须以GET方式拼接在URL中&#xff09;secretString是调用密钥api_nameString是API接口名称&#xff08;包括在请求地址…

AI时代,操作系统交互的革命性变革

AI时代对操作系统交互的影响 对于2024年的智能手机厂商们来说&#xff0c;在冲击高端市场的路上有一场绝对输不起的硬仗&#xff0c;那就是AI大模型的落地之战。 OpenAI的ChatGPT引爆了全球AIGC&#xff08;生成式人工智能&#xff09;热潮&#xff0c;短短一年时间里&#xff…

新手小白,在数学建模的过程中应该怎么分工?

大家知道&#xff0c;数学建模竞赛是需要一个团队的三个人在三天或四天的时间内&#xff0c;完成模型建立&#xff0c;编程实现和论文写作的任务&#xff0c;对许多第一次参加建模或者建模经验比较欠缺的团队来说&#xff0c;是时间紧任务重的&#xff0c;那么怎么办呢&#xf…

Java学习笔记26(枚举和注解)

1.枚举和注解 1.1 枚举 ​ 1.枚举(enumeration) ​ 2.枚举是一组常量的集合 ​ 3.枚举属于一种特殊的类&#xff0c;里面只包含一组有限的特定的对象 1.枚举应用案例 ​ 1.不需要提供setXxx方法&#xff0c;因为枚举对象值通常为只读 ​ 2.对枚举对象/属性使用final st…

C语言实现三子棋游戏(可以改变为四子棋或者多子棋版)

目录 游戏介绍 游戏框架 游戏基本逻辑的介绍 游戏具体功能实现 初始化棋盘 打印棋盘 玩家下棋 电脑下棋 判断输赢 行和列&#xff1a; 对角线&#xff1a; 平局&#xff1a; 游戏继续&#xff1a; 游戏完整代码 test.c game.c game.h 游戏介绍 三子棋游戏或者…

浏览器不兼容的问题和通用解决方案

大家好&#xff0c;我是咕噜铁蛋&#xff0c;今天我想和大家聊聊一个在我们日常上网过程中经常遇到的问题——浏览器不兼容。这个问题看似微小&#xff0c;但却常常让我们在浏览网页、使用在线应用时感到困扰。接下来&#xff0c;我将详细分析浏览器不兼容的原因&#xff0c;并…