0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

HarmonyOS开发案例:【音乐播放器】

jf_46214456 来源:jf_46214456 作者:jf_46214456 2024-04-23 15:44 次阅读

介绍

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

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

相关概念

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

约束与限制

  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. 工程创建完成后,选择使用[真机进行调测]。
    4. HarmonyOS与OpenHarmony鸿蒙文档籽料:mau123789是v直接拿

搜狗高速浏览器截图20240326151450.png

代码结构解读

本篇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}`);
    }
  }
}

审核编辑 黄宇

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 鸿蒙
    +关注

    关注

    55

    文章

    1651

    浏览量

    42132
  • HarmonyOS
    +关注

    关注

    79

    文章

    1864

    浏览量

    29274
  • OpenHarmony
    +关注

    关注

    23

    文章

    3328

    浏览量

    15172
收藏 人收藏

    评论

    相关推荐

    基于labview的音乐播放器(可用)

    相关课程推荐:《8周LabVIEW视觉项目编程实战特训营》 用LabVIEW声音控件做的音乐播放器,做的比较简单,用的方法也比较笨,如图所示。有暂停、调节音量、进度条、伪旋律图等,不过受控件限制
    发表于 11-24 15:36

    如果我的诺基亚设备在音乐播放器 (或多媒体播放器) 中未能

    如果我的诺基亚设备在音乐播放器 (或多媒体播放器) 中未能显示新的音乐文件,该怎么办?刷新或更新音乐库。打开
    发表于 01-23 17:40

    音乐播放器的硬件编程

    音乐播放器的硬件编程
    发表于 08-17 20:44

    音乐播放器

    音乐播放器播放和暂停
    发表于 05-28 17:30

    做一个音乐播放器

    大家集思广益,做一个音乐播放器,要求能播放多种格式的音乐文件具有选择播放文件的功能,声音大小可调能录音,并能回放,任意设置
    发表于 07-01 11:12

    基于STM32无线音乐播放器

    这是基于STM32VET6的用51单片机控制播放音乐播放器
    发表于 07-06 12:06

    求助,谁有基于labview的音乐播放器

    谁有基于labview的音乐播放器,能实现显示当前音乐名,播放列表,音量调节,切歌,顺序、循环播放
    发表于 01-06 15:00

    音乐播放器制作手册

    音乐播放器
    发表于 01-17 21:40

    基于战舰板的遥控音乐播放器

    2012年买的战舰板,有较长时间放着吃灰觉得很可惜。感觉战舰板的音乐播放器音质蛮不错的,于是想就折腾一个遥控音乐播放器。貌似很简单的事,实际上我折腾一个星期的时间才达到理想效果。思路:
    发表于 07-01 04:35

    网页音乐播放器代码

    网页音乐播放器代码:有MP3的,有Windows Media Player音乐播放器代码的,也有视频的,
    发表于 01-10 11:18 86次下载

    Windows Media Player音乐播放器代码

    Windows Media Player音乐播放器代码 一、Windows Media Player音乐播放器代码:
    发表于 01-10 11:14 2203次阅读

    基于Android音乐播放器的研究

    Android平台是目前智能移动终端的主流系统。随着人们生活、工作节奏的加快,乘车、运动、学习等碎片时间的增多,音乐播放器成为人们所关心的必备应用之一,广受大家欢迎。 目前,Android市场上
    发表于 12-11 11:44 7次下载
    基于Android<b class='flag-5'>音乐</b><b class='flag-5'>播放器</b>的研究

    数码播放器开发案

    数码播放器开发案例说明。
    发表于 05-19 11:07 6次下载

    HarmonyOS开发案例:【视频播放器

    基于video、swiper和slider组件,实现简单的视频播放器,可支持海报轮播、视频播放等功能。
    的头像 发表于 04-22 21:06 81次阅读
    <b class='flag-5'>HarmonyOS</b><b class='flag-5'>开发案</b>例:【视频<b class='flag-5'>播放器</b>】

    HarmonyOS开发案例:【视频播放器

    使用ArkTS语言实现视频播放器,主要包括主界面和视频播放界面,
    的头像 发表于 04-23 17:25 154次阅读
    <b class='flag-5'>HarmonyOS</b><b class='flag-5'>开发案</b>例:【视频<b class='flag-5'>播放器</b>】