鸿蒙开发-如何实现音频播放

423 阅读2分钟

1 选择技术

要想实现音频播放功能,目前支持的解决方案有:Video、AVPlayer、AudioRenderer、OpenSL ES

image.png

通过分析对比,我们选用AVPlayer来进行音频的播放

2 使用AVPlayer开发音频播放功能

2.1 播放状态变化示意图

官方给的示例图
AVPlayer传送门 image.png 翻译一下

image.png

2.2 播放状态

与2.1中分析图一一对应

image.png

2.3 开发步骤

1 创建实例createAVPlayer(),AVPlayer初始化idle状态。

2 设置业务需要的监听事件,搭配全流程场景使用。

3 设置资源,设置属性url,AVPlayer进入initialized状态。

4 准备播放:调用prepare(),AVPlayer进入prepared状态。

5 音频播控:播放play(),暂停pause(),跳转seek(),停止stop() 等操作。

6 (可选)更换资源:调用reset()重置资源,AVPlayer重新进入idle状态,允许更换资源url。

7 退出播放:调用release()销毁实例,AVPlayer进入released状态,退出播放。

完整代码

AVPlayerClass

import media from '@ohos.multimedia.media'
import { SongType } from '../model/music'
import { emitter } from '@kit.BasicServicesKit'
import { promptAction } from '@kit.ArkUI'

export default class AVPlayerClass {
  // 播放器对象
  static player: media.AVPlayer = {} as media.AVPlayer
  // 歌曲时长
  static duration: number = 0
  // 播放时长
  static time: number = 0
  // 是否播放
  static isPlay: boolean = false
  // 播放模式
  static playMode: 'auto' | 'repeat' | 'random' = 'auto'
  // 播放列表
  static playList: SongType[] = []
  // 播放索引
  static playIndex: number = 0

  // 初始化播放器
  static async init() {
    // 创建播放器
    AVPlayerClass.player = await media.createAVPlayer()
    // 监听播放状态
    AVPlayerClass.player.on('stateChange', state => {
      switch (state) {
      // 初始化完成
        case 'initialized':
          AVPlayerClass.player.prepare() // 准备
          break
      // 准备完成
        case 'prepared':
          AVPlayerClass.player.play() // 播放
          break
      // 播放中
        case 'playing':
          AVPlayerClass.isPlay = true
          break
      // 播放暂停
        case 'paused':
          AVPlayerClass.isPlay = false
          break
      // 播放结束
        case 'completed':
          AVPlayerClass.next()
          break
      }
    })
    // 监听歌曲时长
    AVPlayerClass.player.on('durationUpdate', duration => {
      AVPlayerClass.duration = duration
    })
    // 监听播放时长
    AVPlayerClass.player.on('timeUpdate', time => {
      AVPlayerClass.time = time
      // 发布播放消息
      AVPlayerClass.updateInfo()
    })
  }

  // 单曲播放
  static async singlePlay(song: SongType) {
    // // 添加到播放列表-->添加歌曲
    // AVPlayerClass.playList.unshift(song)
    // AVPlayerClass.playIndex = 0
    // // 重置-->让状态进入闲置状态-->可以再次设置播放地址
    // AVPlayerClass.player.reset()
    // // 设置播放地址
    // AVPlayerClass.player.url = song.url
    const index = AVPlayerClass.playList.findIndex(item => item.id == song.id)
    if (index >= 0) {
      // 正在播放
      if (AVPlayerClass.player.url == song.url) {
        // 继续播放
      } else {
        // 切换
        await AVPlayerClass.player.reset()
        AVPlayerClass.player.url = song.url
      }
    } else {
      // 添加
      AVPlayerClass.playList.unshift(song)
      AVPlayerClass.playIndex = 0
      // 切换
      await AVPlayerClass.player.reset()
      AVPlayerClass.player.url = song.url
    }
  }

  // 发布信息
  static updateInfo() {
    emitter.emit({
      eventId: 0
    }, {
      data: {
        duration: AVPlayerClass.duration,
        time: AVPlayerClass.time,
        isPlay: AVPlayerClass.isPlay,
        playMode: AVPlayerClass.playMode,
        playList: AVPlayerClass.playList,
        playIndex: AVPlayerClass.playIndex,
        img: AVPlayerClass.playList[AVPlayerClass.playIndex].img,
        name: AVPlayerClass.playList[AVPlayerClass.playIndex].name,
        author: AVPlayerClass.playList[AVPlayerClass.playIndex].author
      }
    })
  }
  

  // 下一首
  static next() {
    if (AVPlayerClass.playIndex < AVPlayerClass.playList.length - 1) {
      AVPlayerClass.playIndex++
    } else {
      AVPlayerClass.playIndex = 0
    }
    AVPlayerClass.singlePlay(AVPlayerClass.playList[AVPlayerClass.playIndex])
  }

  // 上一首
  static prev() {
    if (AVPlayerClass.playIndex == 0) {
      AVPlayerClass.playIndex = AVPlayerClass.playList.length - 1
    } else {
      AVPlayerClass.playIndex--
    }
    AVPlayerClass.singlePlay(AVPlayerClass.playList[AVPlayerClass.playIndex])
  }
}

总结

对于音频播放主要我们熟练掌握不同状态的切换就能实现对应的功能

简而言之就是---什么时候干什么事