当前位置: 首页 > 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效果预览

图片

图片

相关文章:

【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&#xff0c;不同之处仅在于网络层数&#xff0c;一般来说&#xff0c;神经网络越深&#xff0c;它的准确率就越高。但并非…...

机器学习第六课--朴素贝叶斯

朴素贝叶斯广泛地应用在文本分类任务中&#xff0c;其中最为经典的场景为垃圾文本分类(如垃圾邮件分类:给定一个邮件&#xff0c;把它自动分类为垃圾或者正常邮件)。这个任务本身是属于文本分析任务&#xff0c;因为对应的数据均为文本类型&#xff0c;所以对于此类任务我们首先…...

基于Java+SpringBoot+Vue的图书借还小程序的设计与实现(亮点:多角色、点赞评论、借书还书、在线支付)

图书借还管理小程序 一、前言二、我的优势2.1 自己的网站2.2 自己的小程序&#xff08;小蔡coding&#xff09;2.3 有保障的售后2.4 福利 三、开发环境与技术3.1 MySQL数据库3.2 Vue前端技术3.3 Spring Boot框架3.4 微信小程序 四、功能设计4.1 主要功能描述 五、系统实现5.1 小…...

【校招VIP】前端计算机网络之UDP相关

考点介绍 UDP是一个简单的面向消息的传输层协议&#xff0c;尽管UDP提供标头和有效负载的完整性验证&#xff08;通过校验和&#xff09;&#xff0c;但它不保证向上层协议提供消息传递&#xff0c;并且UDP层在发送后不会保留UDP 消息的状态。因此&#xff0c;UDP有时被称为不可…...

前缀和实例4(和可被k整除的子数组)

题目&#xff1a; 给定一个整数数组 nums 和一个整数 k &#xff0c;返回其中元素之和可被 k 整除的&#xff08;连续、非空&#xff09; 子数组 的数目。 子数组 是数组的 连续 部分。 示例 1&#xff1a; 输入&#xff1a;nums [4,5,0,-2,-3,1], k 5 输出&#xff1a;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&#xff1a;100031. 计算 K 置位下标对应元素的和竞赛时代码写法2——手写二进制中1的数量 Q2&#xff1a;100040. 让所有学生保持开心的分组方法数&#xff08;排序后枚举分界&#xff09;竞赛时代码 Q3&#xff1a;100033. 最大合金数&#xff08;二分答…...

RocketMQ的介绍和环境搭建

一、介绍 我也不知道是啥&#xff0c;知道有什么用、怎么用就行了&#xff0c;说到mq&#xff08;MessageQueue&#xff09;就是消息队列&#xff0c;队列是先进先出的一种数据结构&#xff0c;但是RocketMQ不一定是这样&#xff0c;简单的理解一下&#xff0c;就是临时存储的…...

【web开发】7、Django(2)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 一、部门列表二、部门管理&#xff08;增删改&#xff09;三、用户管理过渡到modelform组件四、modelform实例&#xff1a;靓号操作五、自定义分页组件六、datepick…...

Prometheus+Grafana可视化监控【Nginx状态】

文章目录 一、安装Docker二、安装Nginx(Docker容器方式)三、安装Prometheus四、安装Grafana五、Pronetheus和Grafana相关联六、安装nginx_exporter七、Grafana添加Nginx监控模板 一、安装Docker 注意&#xff1a;我这里使用之前写好脚本进行安装Docker&#xff0c;如果已经有D…...

R 语言的安装教程

一、下载相关软件 1、R 下载 官网&#xff1a;R: The R Project for Statistical Computing 找到中国镜像&#xff0c;下载快 历史版本点击这里 2、Rtools 下载 进入镜像后&#xff0c;点击这里 然后选择与上面下载的R版本相对应的版本即可 3、Rstudio 下载 官网&#xff1…...

uniapp-提现功能(demo)

页面布局 提现页面 有一个输入框 一个提现按钮 一段提现全部的文字 首先用v-model 和data内的数据双向绑定 输入框逻辑分析 输入框的逻辑 为了符合日常输出 所以要对输入框加一些条件限制 因为是提现 所以对输入的字符做筛选,只允许出现小数点和数字 这里用正则实现的小数点…...

Spring 篇

1、什么是 Spring&#xff1f; Spring是一个轻量级的IOC和AOP容器框架。是为Java应用程序提供基础性服务的一套框架&#xff0c;目的是用于简化企业应用程序的开发&#xff0c;它使得开发者只需要关心业务需求。常见的配置方式有三种&#xff1a;基于XML的配置、基于注解的配置…...

Vim 调用外部命令学习笔记

Vim 外部命令集成完全指南 文章目录 Vim 外部命令集成完全指南核心概念理解命令语法解析语法对比 常用外部命令详解文本排序与去重文本筛选与搜索高级 grep 搜索技巧文本替换与编辑字符处理高级文本处理编程语言处理其他实用命令 范围操作示例指定行范围处理复合命令示例 实用技…...

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型

摘要 拍照搜题系统采用“三层管道&#xff08;多模态 OCR → 语义检索 → 答案渲染&#xff09;、两级检索&#xff08;倒排 BM25 向量 HNSW&#xff09;并以大语言模型兜底”的整体框架&#xff1a; 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后&#xff0c;分别用…...

从零实现富文本编辑器#5-编辑器选区模型的状态结构表达

先前我们总结了浏览器选区模型的交互策略&#xff0c;并且实现了基本的选区操作&#xff0c;还调研了自绘选区的实现。那么相对的&#xff0c;我们还需要设计编辑器的选区表达&#xff0c;也可以称为模型选区。编辑器中应用变更时的操作范围&#xff0c;就是以模型选区为基准来…...

Python:操作 Excel 折叠

💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 Python 操作 Excel 系列 读取单元格数据按行写入设置行高和列宽自动调整行高和列宽水平…...

python爬虫:Newspaper3k 的详细使用(好用的新闻网站文章抓取和解析的Python库)

更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、Newspaper3k 概述1.1 Newspaper3k 介绍1.2 主要功能1.3 典型应用场景1.4 安装二、基本用法2.2 提取单篇文章的内容2.2 处理多篇文档三、高级选项3.1 自定义配置3.2 分析文章情感四、实战案例4.1 构建新闻摘要聚合器…...

关键领域软件测试的突围之路:如何破解安全与效率的平衡难题

在数字化浪潮席卷全球的今天&#xff0c;软件系统已成为国家关键领域的核心战斗力。不同于普通商业软件&#xff0c;这些承载着国家安全使命的软件系统面临着前所未有的质量挑战——如何在确保绝对安全的前提下&#xff0c;实现高效测试与快速迭代&#xff1f;这一命题正考验着…...

高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数

高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数 在软件开发中,单例模式(Singleton Pattern)是一种常见的设计模式,确保一个类仅有一个实例,并提供一个全局访问点。在多线程环境下,实现单例模式时需要注意线程安全问题,以防止多个线程同时创建实例,导致…...

C/C++ 中附加包含目录、附加库目录与附加依赖项详解

在 C/C 编程的编译和链接过程中&#xff0c;附加包含目录、附加库目录和附加依赖项是三个至关重要的设置&#xff0c;它们相互配合&#xff0c;确保程序能够正确引用外部资源并顺利构建。虽然在学习过程中&#xff0c;这些概念容易让人混淆&#xff0c;但深入理解它们的作用和联…...

苹果AI眼镜:从“工具”到“社交姿态”的范式革命——重新定义AI交互入口的未来机会

在2025年的AI硬件浪潮中,苹果AI眼镜(Apple Glasses)正在引发一场关于“人机交互形态”的深度思考。它并非简单地替代AirPods或Apple Watch,而是开辟了一个全新的、日常可接受的AI入口。其核心价值不在于功能的堆叠,而在于如何通过形态设计打破社交壁垒,成为用户“全天佩戴…...

wpf在image控件上快速显示内存图像

wpf在image控件上快速显示内存图像https://www.cnblogs.com/haodafeng/p/10431387.html 如果你在寻找能够快速在image控件刷新大图像&#xff08;比如分辨率3000*3000的图像&#xff09;的办法&#xff0c;尤其是想把内存中的裸数据&#xff08;只有图像的数据&#xff0c;不包…...