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

【Purple Pi OH RK3566鸿蒙开发板】OpenHarmony音频播放应用,真实体验感爆棚!

本文转载于Purple Pi OH开发爱好者,作者ITMING 。

原文链接:https://bbs.elecfans.com/jishu_2376383_1_1.html

01注意事项

  • DevEco Studio 4.0 Beta2(Build Version: 4.0.0.400)

  • OpenHarmony SDK API 9

  • 创建工程类型选择Application

  • 修改entry/build-profile.json5配置文件中的targets>runtimeOS为OpenHarmony,然后进行Sync Now(同步)

02工程概述

PPI有声是一款基于OpenHarmony API 9 开发的,运行于Purple Pi 开发板(安装OpenHarmony标准系统)的音频播放应用程序。

03场景化

  • 智慧家居类(电子门铃,温湿度显示仪,屏显灯控开关等)

  • 智慧办公类(打卡机,大屏显示等)

  • 智慧教育类(电子班牌,校园大屏,电子讲台等)

04创建工程

图片

  • Project name:工程名称

  • Bundle name:包名

  • Save location:工程存储路径

  • Compile SDK:编译API版本

  • Compatible SDK:兼容的最新API版本

  • Module name:模块名称

  • Model:模型

  • Enable Super Visual:是否启用低代码开发

  • Device Type:设备类型

  • Node:nodejs路径

05媒体服务

媒体子系统为开发者提供一套简单且易于理解的接口,使得开发者能够方便接入系统使用系统的媒体资源。

媒体子系统包含了音视频相关媒体业务,提供以下常用共功能:

  • 音视频播放(AVPlayer)

  • 音视频录制(AVRecorder)

    5.1 AVPlayer概述

AVPlayer主要工作是将Audio/Video媒体资源(比如mp4/mp3/mkv/mpeg-ts等)转码为可供渲染的图像或可听见的模拟信号,并通过输出设备进行播放。

使用AVPlayer可以实现端到端播放原始媒体资源,播放对的全流程包含:创建AVPlayer,设置播放资源,设置播放参数 (音量/倍速/焦点模式),播放控制(播放/暂停/跳转/停止),重置,销毁资源。

开发过程中开发者可以通过AVPlayer的state属性主动获取当前状态或使用on('stateChange')方法监听状态变化。若应用在音频播放器处于错误状态时执行操作,系统可能会抛出异常或生成其他未定义的行为。

图片

主:当播放处于prepared/playing/paused/completed状态时,播放引擎处于工作状态,需要占用系统较多的运行内容。当客户端暂时不适用播放器时,调用reset()或release()回收内存资源。

5.2 开发步骤

  1. 导入media模块,调用createAVPlayer()方法创建AVPlayer实例,AVPlayer初始化idle状态。

  2. 设置业务监听事件,搭配全流程场景使用,如监听播放器state属性改变的stateChange;监听播放器错误信息的error;用于进度条,监听进度条长度,刷新资源时长的durationUpdate等。

  3. 设置资源:设置属性url,AVPlayer进入initialized状态

  4. 准备播放:调用prepare(),AVPlayer进入prepared状态,此时可以获取duration,设置音量。

  5. 音频播控:播放play(),暂停pause(),跳转seek(),停止stop()等操作。

  6. 调用reset()重置资源,AVPlayer重新进入idle状态,此时可更换播放源url。

  7. 调用release()销毁实例,AVPlayer进入released状态,退出播放。

06构建PPI有声

6.1 准备资源文件

  • 音频文件拷贝到resources/rawfile目录

  • 将拷贝到resources/base/mdiea目录

  • 音频播放背景图audio_bg.png

  • 音频播放旋转图audio.png

  • 暂停ic_pause.svg

  • 播放ic_play.svg

图片

6.2 构建UI页面

整个UI以Flex弹性布局为主,子组件以列方式排列,分别为可旋转的音频播放控件,播放进度条以及播放控制按钮组成。

6.2.1 可旋转的音频播放控件

使用Stack堆叠布局容器为主,将旋转控件置于背景图之上。

Stack({ alignContent: Alignment.Center }) {Image($r('app.media.audio_bg')).width(200).height(200)Image($r('app.media.audio')).width(100).height(100).backgroundColor(Color.White).borderRadius(50).rotate({ angle: this.angleNum }).animation({duration: this.duration,tempo: 1,curve: Curve.Linear,iterations: -1,playMode: PlayMode.Normal})}
6.2.2 进度条

播放进度由置于上部的播放时长和总时长,底部的播放进度条组成,包裹在Column列容器中。

Column({ space: 4 }) {Row() {Text(this.msToS(this.currentProgress)).fontSize(12).fontColor(0xc1c3c5)Text(this.msToS(this.duration)).fontSize(12).fontColor(0xc1c3c5)}.width('100%').justifyContent(FlexAlign.SpaceBetween)// 播放进度条Slider({value: this.currentProgress,min: 0,max: this.duration,style: SliderStyle.OutSet}).showTips(true).onChange((value: number, mode: SliderChangeMode) => {this.currentProgress = value;// 跳转到指定位置播放this.avPlayer.seek(value);})}.width('90%')
 

6.2.3 播放控件

播放控件通过当前AVPlayer的状态判断显示播放/暂停图标按钮。

Row({ space: 10 }) {if (this.state === 'playing') {// 暂停Image($r('app.media.ic_pause')).width(64).height(64).fillColor(0xff5722).onClick(() => {// 暂停播放this.avPlayer.pause().then(() => {this.angleNum = 0;})})} else {// 播放Image($r('app.media.ic_play')).width(64).height(64).fillColor(0x00aaee).onClick(async () => {if (this.avPlayer && this.avPlayer.state === "paused") {this.avPlayer.play().then(() => {this.angleNum = 360;})} else {await this.initAVPlayer();}})}}.width('100%').justifyContent(FlexAlign.Center)

6.3 实现音频播放

6.3.1 初始化AVPlayer

// 播放音频AVPlayer实例private avPlayer: media.AVPlayer = undefined;// 初始化AVPlayerasync initAVPlayer() {// 创建AVPlayer实例对象this.avPlayer = await media.createAVPlayer();// 创建状态机变化回调函数this.setAVPlayerCallback();await this.loadingResourceFile();}
6.3.2 加载HAP包资源文件
// 加载HAP包资源文件loadingResourceFile = async () => {// 通过UIAbilityContext的resourceManager成员的getRawFd接口获取媒体资源播放地址let context = getContext(this) as common.UIAbilityContext;let fileDir = await context.resourceManager.getRawFd("audio.wav");// 为fdSrc赋值触发initialized状态机上报this.avPlayer.fdSrc = fileDir;}
6.3.3 注册AVPlayer回调函数
// 注册AVPlayer回调函数setAVPlayerCallback = () => {// 状态机变化回调函数// state:表示当前播放状态// reason:表示当前播放状态的切换原因this.avPlayer.on('stateChange', async (state, reason) => {this.state = this.avPlayer.state;switch (state) {case 'initialized':this.avPlayer.prepare().then(() => {// 音频播放准备完毕后,获取音频总时长this.duration = this.avPlayer.duration;})break;case 'prepared':// 开始播放this.avPlayer.play().then(() => {// 设置图标开始旋转this.angleNum = 360;})break;}})// 播放错误回调函数this.avPlayer.on('error', (err) => {console.error(`Error happened. Cause: ${JSON.stringify(err)}`);})// 监听资源播放当前时间回调函数this.avPlayer.on('timeUpdate', (time: number) => {if (this.avPlayer.state === 'completed') {this.currentProgress = 0;this.duration = 0;this.angleNum = 0;} else {this.currentProgress = time;}})}
07效果预览

图片

图片

http://www.lryc.cn/news/168564.html

相关文章:

  • Android rom开发:9.0系统上实现4G wifi 以太网共存
  • 高速自动驾驶HMI人机交互
  • 【自然语言处理】关系抽取 —— SOLS 讲解
  • 周易算卦流程c++实现
  • 软件架构设计(十三) 构件与中间件技术
  • PyTorch深度学习实战——基于ResNet模型实现猫狗分类
  • 机器学习第六课--朴素贝叶斯
  • 基于Java+SpringBoot+Vue的图书借还小程序的设计与实现(亮点:多角色、点赞评论、借书还书、在线支付)
  • 【校招VIP】前端计算机网络之UDP相关
  • 前缀和实例4(和可被k整除的子数组)
  • Android获取系统读取权限
  • 输入学生成绩(最多不超过40),输入为负值时表示输入结束,统计成绩高于平均成绩的学生人数
  • 【力扣周赛】第 363 场周赛(完全平方数和质因数分解)
  • RocketMQ的介绍和环境搭建
  • 【web开发】7、Django(2)
  • Prometheus+Grafana可视化监控【Nginx状态】
  • R 语言的安装教程
  • uniapp-提现功能(demo)
  • Spring 篇
  • three.js简单3D图形的使用
  • spark withColumn的使用(笔记)
  • PTA:7-1 线性表的合并
  • Spring 的创建和日志框架的整合
  • 11-集合和学生管理系统
  • C语言进阶指针(3) ——qsort的实现
  • Rust源码分析——Rc 和 Weak 源码详解
  • 【网络编程】深入理解TCP协议二(连接管理机制、WAIT_TIME、滑动窗口、流量控制、拥塞控制)
  • 社区团购商城小程序v18.1开源独立版+前端
  • MATLAB入门-字符串操作
  • Kong Learning