【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 开发步骤
-
导入media模块,调用
createAVPlayer()方法创建AVPlayer实例,AVPlayer初始化idle状态。 -
设置业务监听事件,搭配全流程场景使用,如监听播放器state属性改变的
stateChange;监听播放器错误信息的error;用于进度条,监听进度条长度,刷新资源时长的durationUpdate等。 -
设置资源:设置属性url,AVPlayer进入initialized状态
-
准备播放:调用prepare(),AVPlayer进入prepared状态,此时可以获取duration,设置音量。
-
音频播控:播放play(),暂停pause(),跳转seek(),停止stop()等操作。
-
调用reset()重置资源,AVPlayer重新进入idle状态,此时可更换播放源url。
-
调用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效果预览


相关文章:
【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 创建工程类型选择Appli…...
Android rom开发:9.0系统上实现4G wifi 以太网共存
framework层修改网络优先级,4G > wifi > eth 修改patch如下: diff --git a/frameworks/base/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java b/frameworks/base/services/core/java/com/android/server/connectivit…...
高速自动驾驶HMI人机交互
概述 目的 本文档的目的是描述高速自动驾驶功能涉及的HMI显示需求技术规范和设计说明。 范围 术语及缩写 设计与实验标准 设计标准 设计标准-非法规类设计标准-法规类 HMI交互需求 CL4功能界面 HMI显示器[伊1] 中应包含CL4功能设置界面,提供给用户进行设置操作或显…...
【自然语言处理】关系抽取 —— SOLS 讲解
SOLS 论文信息 标题:Speaker-Oriented Latent Structures for Dialogue-Based Relation Extraction 作者:Guoshun Nan, Guoqing Luo, Sicong Leng, Yao Xiao, Wei Lu 发布时间与更新时间:2021.09.11 主题:自然语言处理、关系抽取、对话场景、跨语句、DialogRE、GCN arXiv:…...
周易算卦流程c++实现
代码 #include<iostream> using namespace std; #include<vector> #include<cstdlib> #include<ctime> #include<Windows.h>int huaYiXiangLiang(int all, int& left) {Sleep(3000);srand(time(0));left rand() % all 1;while (true) {if…...
软件架构设计(十三) 构件与中间件技术
中间件的定义 其实中间件是属于构件的一种。是一种独立的系统软件或服务程序,可以帮助分布式应用软件在不同技术之间共享资源。 我们把它定性为一类系统软件,比如我们常说的消息中间件,数据库中间件等等都是中间件的一种体现。一般情况都是给应用系统提供服务,而不是直接…...
PyTorch深度学习实战——基于ResNet模型实现猫狗分类
PyTorch深度学习实战——基于ResNet模型实现猫狗分类 0. 前言1. ResNet 架构2. 基于预训练 ResNet 模型实现猫狗分类相关链接 0. 前言 从 VGG11 到 VGG19,不同之处仅在于网络层数,一般来说,神经网络越深,它的准确率就越高。但并非…...
机器学习第六课--朴素贝叶斯
朴素贝叶斯广泛地应用在文本分类任务中,其中最为经典的场景为垃圾文本分类(如垃圾邮件分类:给定一个邮件,把它自动分类为垃圾或者正常邮件)。这个任务本身是属于文本分析任务,因为对应的数据均为文本类型,所以对于此类任务我们首先…...
基于Java+SpringBoot+Vue的图书借还小程序的设计与实现(亮点:多角色、点赞评论、借书还书、在线支付)
图书借还管理小程序 一、前言二、我的优势2.1 自己的网站2.2 自己的小程序(小蔡coding)2.3 有保障的售后2.4 福利 三、开发环境与技术3.1 MySQL数据库3.2 Vue前端技术3.3 Spring Boot框架3.4 微信小程序 四、功能设计4.1 主要功能描述 五、系统实现5.1 小…...
【校招VIP】前端计算机网络之UDP相关
考点介绍 UDP是一个简单的面向消息的传输层协议,尽管UDP提供标头和有效负载的完整性验证(通过校验和),但它不保证向上层协议提供消息传递,并且UDP层在发送后不会保留UDP 消息的状态。因此,UDP有时被称为不可…...
前缀和实例4(和可被k整除的子数组)
题目: 给定一个整数数组 nums 和一个整数 k ,返回其中元素之和可被 k 整除的(连续、非空) 子数组 的数目。 子数组 是数组的 连续 部分。 示例 1: 输入:nums [4,5,0,-2,-3,1], k 5 输出:7 …...
Android获取系统读取权限
第一步在Androidifest.xml文件中加上授权语句 <uses-permission android:name"android.permission.WRITE_EXTERNAL_STORAGE"/><uses-permission android:name"android.permission.READ_EXTERNAL_STORAGE"/>并且在Application标签下添加 androi…...
输入学生成绩(最多不超过40),输入为负值时表示输入结束,统计成绩高于平均成绩的学生人数
#include<stdio.h> #define N 40 int scanfscore(int score[N]) {int i -1;do {i;printf("输入学生成绩:");scanf("%d", &score[i]);} while (score[i] > 0);return i; } int average(int score[N], int n) {int j 0;int k 0;double sum …...
【力扣周赛】第 363 场周赛(完全平方数和质因数分解)
文章目录 竞赛链接Q1:100031. 计算 K 置位下标对应元素的和竞赛时代码写法2——手写二进制中1的数量 Q2:100040. 让所有学生保持开心的分组方法数(排序后枚举分界)竞赛时代码 Q3:100033. 最大合金数(二分答…...
RocketMQ的介绍和环境搭建
一、介绍 我也不知道是啥,知道有什么用、怎么用就行了,说到mq(MessageQueue)就是消息队列,队列是先进先出的一种数据结构,但是RocketMQ不一定是这样,简单的理解一下,就是临时存储的…...
【web开发】7、Django(2)
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 一、部门列表二、部门管理(增删改)三、用户管理过渡到modelform组件四、modelform实例:靓号操作五、自定义分页组件六、datepick…...
Prometheus+Grafana可视化监控【Nginx状态】
文章目录 一、安装Docker二、安装Nginx(Docker容器方式)三、安装Prometheus四、安装Grafana五、Pronetheus和Grafana相关联六、安装nginx_exporter七、Grafana添加Nginx监控模板 一、安装Docker 注意:我这里使用之前写好脚本进行安装Docker,如果已经有D…...
R 语言的安装教程
一、下载相关软件 1、R 下载 官网:R: The R Project for Statistical Computing 找到中国镜像,下载快 历史版本点击这里 2、Rtools 下载 进入镜像后,点击这里 然后选择与上面下载的R版本相对应的版本即可 3、Rstudio 下载 官网࿱…...
uniapp-提现功能(demo)
页面布局 提现页面 有一个输入框 一个提现按钮 一段提现全部的文字 首先用v-model 和data内的数据双向绑定 输入框逻辑分析 输入框的逻辑 为了符合日常输出 所以要对输入框加一些条件限制 因为是提现 所以对输入的字符做筛选,只允许出现小数点和数字 这里用正则实现的小数点…...
Spring 篇
1、什么是 Spring? Spring是一个轻量级的IOC和AOP容器框架。是为Java应用程序提供基础性服务的一套框架,目的是用于简化企业应用程序的开发,它使得开发者只需要关心业务需求。常见的配置方式有三种:基于XML的配置、基于注解的配置…...
观成科技:隐蔽隧道工具Ligolo-ng加密流量分析
1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具,该工具基于TUN接口实现其功能,利用反向TCP/TLS连接建立一条隐蔽的通信信道,支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式,适应复杂网…...
【网络】每天掌握一个Linux命令 - iftop
在Linux系统中,iftop是网络管理的得力助手,能实时监控网络流量、连接情况等,帮助排查网络异常。接下来从多方面详细介绍它。 目录 【网络】每天掌握一个Linux命令 - iftop工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景…...
【android bluetooth 框架分析 04】【bt-framework 层详解 1】【BluetoothProperties介绍】
1. BluetoothProperties介绍 libsysprop/srcs/android/sysprop/BluetoothProperties.sysprop BluetoothProperties.sysprop 是 Android AOSP 中的一种 系统属性定义文件(System Property Definition File),用于声明和管理 Bluetooth 模块相…...
EtherNet/IP转DeviceNet协议网关详解
一,设备主要功能 疆鸿智能JH-DVN-EIP本产品是自主研发的一款EtherNet/IP从站功能的通讯网关。该产品主要功能是连接DeviceNet总线和EtherNet/IP网络,本网关连接到EtherNet/IP总线中做为从站使用,连接到DeviceNet总线中做为从站使用。 在自动…...
Element Plus 表单(el-form)中关于正整数输入的校验规则
目录 1 单个正整数输入1.1 模板1.2 校验规则 2 两个正整数输入(联动)2.1 模板2.2 校验规则2.3 CSS 1 单个正整数输入 1.1 模板 <el-formref"formRef":model"formData":rules"formRules"label-width"150px"…...
优选算法第十二讲:队列 + 宽搜 优先级队列
优选算法第十二讲:队列 宽搜 && 优先级队列 1.N叉树的层序遍历2.二叉树的锯齿型层序遍历3.二叉树最大宽度4.在每个树行中找最大值5.优先级队列 -- 最后一块石头的重量6.数据流中的第K大元素7.前K个高频单词8.数据流的中位数 1.N叉树的层序遍历 2.二叉树的锯…...
项目部署到Linux上时遇到的错误(Redis,MySQL,无法正确连接,地址占用问题)
Redis无法正确连接 在运行jar包时出现了这样的错误 查询得知问题核心在于Redis连接失败,具体原因是客户端发送了密码认证请求,但Redis服务器未设置密码 1.为Redis设置密码(匹配客户端配置) 步骤: 1).修…...
sipsak:SIP瑞士军刀!全参数详细教程!Kali Linux教程!
简介 sipsak 是一个面向会话初始协议 (SIP) 应用程序开发人员和管理员的小型命令行工具。它可以用于对 SIP 应用程序和设备进行一些简单的测试。 sipsak 是一款 SIP 压力和诊断实用程序。它通过 sip-uri 向服务器发送 SIP 请求,并检查收到的响应。它以以下模式之一…...
深入浅出深度学习基础:从感知机到全连接神经网络的核心原理与应用
文章目录 前言一、感知机 (Perceptron)1.1 基础介绍1.1.1 感知机是什么?1.1.2 感知机的工作原理 1.2 感知机的简单应用:基本逻辑门1.2.1 逻辑与 (Logic AND)1.2.2 逻辑或 (Logic OR)1.2.3 逻辑与非 (Logic NAND) 1.3 感知机的实现1.3.1 简单实现 (基于阈…...
Selenium常用函数介绍
目录 一,元素定位 1.1 cssSeector 1.2 xpath 二,操作测试对象 三,窗口 3.1 案例 3.2 窗口切换 3.3 窗口大小 3.4 屏幕截图 3.5 关闭窗口 四,弹窗 五,等待 六,导航 七,文件上传 …...
