赞
踩
本篇Codelab使用ArkTS语言实现了一个简易的音乐播放器应用,主要包含以下功能:
完成本篇Codelab我们首先要完成开发环境的搭建,本示例以RK3568开发板为例,参照以下步骤进行:
获取OpenHarmony系统版本:标准系统解决方案(二进制)。以3.2 Release版本为例:
搭建烧录环境。
搭建开发环境。
本篇Codelab只对核心代码进行讲解,对于完整代码,我们会在gitee中提供。
- ├──entry/src/main/ets // 代码区
- │ ├──common
- │ │ ├──constants
- │ │ │ └──CommonConstants.ets // 公共常量
- │ │ ├──model
- │ │ │ └──PlayBarModel // 播放栏数据模型
- │ │ └──utils
- │ │ ├──AvSessionUtil.ets // 媒体会话工具类
- │ │ ├──BackgroundTaskUtil.ets // 后台任务工具类
- │ │ ├──CommonUtil.ets // 公共工具类
- │ │ ├──GlobalContext.ets // 公共工具类
- │ │ ├──Logger.ets // 日志类
- │ │ └──ResourceManagerUtil.ets // 资源管理工具类
- │ ├──controller
- │ │ ├──AudioPlayerController.ets // 音乐播放器控制器
- │ │ └──PlayBarController.ets // 播放栏控制器
- │ ├──entryability
- │ │ └──EntryAbility.ets // 程序入口类
- │ ├──pages
- │ │ ├──AudioStartUp.ets // 启动页
- │ │ ├──MusicList.ets // 歌单页
- │ │ └──Play.ets // 播放页
- │ ├──view
- │ │ ├──MusicCardView.ets // 播放卡片模块
- │ │ ├──MusicView.ets // 歌单音乐模块
- │ │ ├──PlayBarView.ets // 播放控制模块
- │ │ ├──PlayListDialogView.ets // 弹窗模块
- │ │ ├──PlayListMusicView.ets // 弹窗音乐模块
- │ │ └──ProgressView.ets // 播放页
- │ └──viewmodel
- │ ├──MusicItem.ets // 音乐类
- │ └──MusicViewModel.ets // 歌单音乐模型
- └──entry/src/main/resources // 应用资源目录

本案例使用播放管理类AVPlayer,实现应用内音频资源的播放,并可进行上一曲、下一曲、播放、暂停、切换播放模式(顺序播放、单曲循环、随机播放)等操作。
使用AVPlayer播放器,需要先创建一个AVPlayer实例。在AudioPlayerController中使用createAVPlayer方法完成音频播放实例的创建。
- // AudioPlayerController.ets
- initAudioPlayer() {
- media.createAVPlayer((error, video) => {
- if (video === undefined) {
- this.avPlayer = video;
- Logger.error(TAG, `createAVPlayer fail, error: ${error}`);
- } else {
- this.avPlayer = video;
- Logger.info(TAG, 'createAVPlayer success');
- }
- });
- }
根据业务需要设置监听事件,搭配播放场景使用。
- // AudioPlayerController.ets
- // 注册AVPlayer回调函数
- setEventCallBack() {
- ...
- // 状态变更回调函数。
- this.avPlayer.on('stateChange', async (state) => {
- ...
- switch (state) {
- case StateEvent.IDLE: // 调用reset成功后触发此状态。
- ...
- case StateEvent.INITIALIZED: // 设置播放源触发此状态。
- ...
- case StateEvent.PREPARED:
- ...
- case StateEvent.PLAYING:
- ...
- case StateEvent.COMPLETED:
- ...
- default:
- Logger.error('unknown state: ' + state);
- break;
- }
- })
- }

设置音频资源,AVPlayer进入initialized状态。在initialized状态回调中,调用prepare方法,准备播放,AVPlayer进入prepared状态。
- // AudioPlayerController.ets
- async play(src: media.AVFileDescriptor, seekTo: number) {
- Logger.info(TAG, 'audioPlayer play');
- ...
- // 设置播放源
- this.avPlayer.fdSrc = src;
- }
-
- setEventCallBack() {
- ...
- this.avPlayer.on('stateChange', async (state) => {
- ...
- switch (state) {
- ...
- case StateEvent.INITIALIZED:// 设置播放源后进入initialized状态
- Logger.info(TAG, 'state initialized called');
- this.avPlayerState = PlayerState.INITIALIZED;
- this.avPlayer.prepare().then(() => {
- Logger.info(TAG, 'prepare success');
- }, (err) => {
- Logger.error(TAG, `prepare failed,error message is: ${err.message}`);
- })
- break;
- ...
- }
- })
- }

AVPlayer进入prepared状态,可进行音频播控操作。包括播放play()、跳转至指定位置播放seek()、暂停pause()、停止stop()等操作。
- // AudioPlayerController.ets
- setEventCallBack() {
- ...
- this.avPlayer.on('stateChange', async (state) => {
- ...
- switch (state) {
- ...
- case StateEvent.PREPARED:
- Logger.info(TAG, 'state prepared called');
- this.avPlayer.play();
- break;
- ...
- }
- })
- }
切换歌曲播放时,需调用reset()重置资源。此时AVPlayer重新进入idle状态,允许更换资源。
- // AudioPlayerController.ets
- async play(src: media.AVFileDescriptor, seekTo: number) {
- ...
- if (this.avPlayerState === PlayerState.INITIALIZED) {
- await this.avPlayer.reset();
- Logger.info(TAG, 'play reset success');
- }
- ...
- }
说明: 只能在initialized/prepared/playing/paused/complete/stopped/error状态调用reset()。
调用release()销毁实例,AVPlayer进入released状态,退出播放。
- // AudioPlayerController.ets
- async release() {
- Logger.info(TAG, 'audioPlayer release');
- if (typeof (this.avPlayer) !== 'undefined') {
- if (this.timeId === CommonConstants.DEFAULT_TIME_ID) {
- clearInterval(this.timeId);
- }
- await this.avPlayer.release();
- this.avPlayer = undefined;
- }
- }
通过后台任务管理模块申请长时任务,可避免设备熄屏后,应用进入挂起状态。
首先在module.json5文件中配置长时任务权限和后台模式类型。
- "module": {
- ...
- "abilities": [
- {
- ...
- "backgroundModes": [
- "audioPlayback"
- ],
- ...
- }
- ],
- "requestPermissions": [
- {
- "name": "ohos.permission.KEEP_BACKGROUND_RUNNING"
- }
- ],
- }

在播放音乐时,申请长时任务。这样在应用切换至后台或设备熄屏后,仍可以继续播放音乐。
- // BackgroundTaskUtil.ets
- import wantAgent from '@ohos.app.ability.wantAgent';
- import backgroundTaskManager from '@ohos.resourceschedule.backgroundTaskManager';
- ...
- export class BackgroundTaskUtil {
- ...
- public static startContinuousTask(context: Context) {
- if (context === undefined) {
- Logger.info(TAG, 'startContinuousTask fail,context is empty.');
- return;
- }
- let wantAgentInfo = {
- // 点击通知后需要执行的动作
- wants: [
- {
- bundleName: CommonConstants.BUNDLE_NAME,
- abilityName: CommonConstants.ABILITY_NAME
- }
- ],
- // 单击通知后的动作类型
- operationType: wantAgent.OperationType.START_ABILITY,
- // 用户定义的私有属性
- requestCode: CommonConstants.BACKGROUND_REQUEST_CODE
- } as wantAgent.WantAgentInfo;
-
- // 通过WanAgent模块的方法获取WanAgent对象
- wantAgent.getWantAgent(wantAgentInfo).then((wantAgentObj) => {
- try {
- backgroundTaskManager.startBackgroundRunning(context, backgroundTaskManager.BackgroundMode.AUDIO_PLAYBACK,
- wantAgentObj).then(() => {
- Logger.info(TAG, 'startBackgroundRunning succeeded');
- }).catch((err: Error) => {
- Logger.error(TAG, 'startBackgroundRunning failed, Cause: ' + JSON.stringify(err));
- });
- } catch (error) {
- Logger.error(TAG, `startBackgroundRunning failed. code is ${error.code} message is ${error.message}`);
- }
- });
- }
- ...
- }

暂停音乐播放,结束长时任务。
- // BackgroundTaskUtil.ets
- import wantAgent from '@ohos.app.ability.wantAgent';
- import backgroundTaskManager from '@ohos.resourceschedule.backgroundTaskManager';
- ...
- export class BackgroundTaskUtil {
- ...
- public static stopContinuousTask(context: Context) {
- if (context === undefined) {
- Logger.info(TAG, 'stopContinuousTask fail,context is empty.');
- return;
- }
- try {
- backgroundTaskManager.stopBackgroundRunning(context).then(() => {
- Logger.info(TAG, 'stopBackgroundRunning succeeded');
- }).catch((err: Error) => {
- Logger.error(TAG, 'stopBackgroundRunning failed Cause: ' + JSON.stringify(err));
- });
- } catch (error) {
- Logger.error(TAG, `stopBackgroundRunning failed. code is ${error.code} message is ${error.message}`);
- }
- }
- }

有很多小伙伴不知道学习哪些鸿蒙开发技术?不知道需要重点掌握哪些鸿蒙应用开发知识点?而且学习时频繁踩坑,最终浪费大量时间。所以有一份实用的鸿蒙(HarmonyOS NEXT)资料用来跟着学习是非常有必要的。
这份鸿蒙(HarmonyOS NEXT)资料包含了鸿蒙开发必掌握的核心知识要点,内容包含了(ArkTS、ArkUI开发组件、Stage模型、多端部署、分布式应用开发、音频、视频、WebGL、OpenHarmony多媒体技术、Napi组件、OpenHarmony内核、Harmony南向开发、鸿蒙项目实战等等)鸿蒙(HarmonyOS NEXT)技术知识点。
希望这一份鸿蒙学习资料能够给大家带来帮助,有需要的小伙伴自行领取,限时开源,先到先得~无套路领取!!
如果你是一名有经验的资深Android移动开发、Java开发、前端开发、对鸿蒙感兴趣以及转行人员,可以直接领取这份资料
获取这份完整版高清学习路线,请点击→纯血版全套鸿蒙HarmonyOS学习资料
HarmonOS基础技能
有了路线图,怎么能没有学习资料呢,小编也准备了一份联合鸿蒙官方发布笔记整理收纳的一套系统性的鸿蒙(OpenHarmony )学习手册(共计1236页)与鸿蒙(OpenHarmony )开发入门教学视频,内容包含:ArkTS、ArkUI、Web开发、应用模型、资源分类…等知识点。
获取以上完整版高清学习路线,请点击→纯血版全套鸿蒙HarmonyOS学习资料
OpenHarmony北向、南向开发环境搭建
获取以上完整鸿蒙HarmonyOS学习资料,请点击→纯血版全套鸿蒙HarmonyOS学习资料
总的来说,华为鸿蒙不再兼容安卓,对中年程序员来说是一个挑战,也是一个机会。只有积极应对变化,不断学习和提升自己,他们才能在这个变革的时代中立于不败之地。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。