使用OpenHarmony实现一个简易的音乐播放器应用

发布于:2024-03-29 ⋅ 阅读:(22) ⋅ 点赞:(0)

介绍

本篇Codelab使用ArkTS语言实现了一个简易的音乐播放器应用,主要包含以下功能:

  1. 播放应用中的音频资源文件,并可进行上一曲、下一曲、播放、暂停、切换播放模式(顺序播放、单曲循环、随机播放)等操作。
  2. 结合后台任务管理模块,实现熄屏后继续播放音频。

相关概念

  • AVPlayer:AVPlayer主要工作是将Audio/Video媒体资源转码为可供渲染的图像和可听见的音频模拟信号,并通过输出设备进行播放,同时对播放任务进行管理,包括开始播放、暂停播放、停止播放、释放资源、设置音量、跳转播放位置、获取轨道信息等功能控制。
  • 后台任务管理:针对应用或业务模块处于后台(无可见界面)时,有需要继续执行或者后续执行的业务,可基于业务类型,申请短时任务延迟挂起或者长时任务避免进入挂起状态;如后台播放音乐可使用长时任务避免进入挂起状态。

约束与限制

  1. 本篇Codelab部分能力依赖于系统API,需下载full-SDK并替换DevEco Studio自动下载的public-SDK。具体操作可参考指南《如何替换full-SDK》。
  2. 本篇Codelab使用的部分API仅系统应用可用,需要提升应用等级。具体可参考指南《访问控制授权申请指导》。

环境搭建

软件要求

  • 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. 工程创建完成后,选择使用真机进行调测。

代码结构解读

本篇Codelab只对核心代码进行讲解。

├──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}`);
    }
  }
}

总结

您已经完成了本次Codelab的学习,并了解到以下知识点:

  1. 使用AVPlayer播放音频资源。
  2. 通过后台任务管理模块backgroundTaskManager管理长时任务。

为了帮助大家更深入有效的学习到鸿蒙开发知识点,小编特意给大家准备了一份全套最新版的HarmonyOS NEXT学习资源,获取完整版方式请点击→HarmonyOS教学视频

HarmonyOS教学视频:语法ArkTS、TypeScript、ArkUI等…视频教程

鸿蒙生态应用开发白皮书V2.0PDF:

获取完整版白皮书方式请点击→《鸿蒙生态应用开发白皮书V2.0PDF

在这里插入图片描述

鸿蒙 (Harmony OS)开发学习手册

一、入门必看

  1. 应用开发导读(ArkTS)
  2. .……

在这里插入图片描述


二、HarmonyOS 概念

  1. 系统定义
  2. 技术架构
  3. 技术特性
  4. 系统安全

在这里插入图片描述

三、如何快速入门?鸿蒙基础入门学习指南

  1. 基本概念
  2. 构建第一个ArkTS应用
  3. .……

在这里插入图片描述


四、开发基础知识

  1. 应用基础知识
  2. 配置文件
  3. 应用数据管理
  4. 应用安全管理
  5. 应用隐私保护
  6. 三方应用调用管控机制
  7. 资源分类与访问
  8. 学习ArkTS语言
  9. .……

在这里插入图片描述


五、基于ArkTS 开发

  1. Ability开发
  2. UI开发
  3. 公共事件与通知
  4. 窗口管理
  5. 媒体
  6. 安全
  7. 7.网络与链接
  8. 电话服务
  9. 数据管理
  10. 后台任务(Background Task)管理
  11. 设备管理
  12. 设备使用信息统计
  13. DFX
  14. 国际化开发
  15. 折叠屏系列
  16. .……

在这里插入图片描述


更多了解更多鸿蒙开发的相关知识可以参考:《鸿蒙 (Harmony OS)开发学习手册

本文含有隐藏内容,请 开通VIP 后查看