HarmonyOS鸿蒙Next中通过AVPlayer如何实现音乐播放、暂停、音量设置?

HarmonyOS鸿蒙Next中通过AVPlayer如何实现音乐播放、暂停、音量设置? 通过AVPlayer如何实现音乐播放、暂停、音量设置?

4 回复
// 播放操作。
avPlayer.play().then(() => {
    console.info('Succeeded in playing');
}, (err: BusinessError) => {
    console.error('Failed to play,error message is :' + err.message);
});

// 暂停操作。
avPlayer.pause((err: BusinessError) => {
    if (err) {
        console.error('Failed to pause,error message is :' + err.message);
    } else {
        console.info('Succeeded in pausing');
    }
});

[示例工程](https://gitcode.com/openharmony/applications_app_samples/tree/master/code/DocsSample/Media/AVPlayer/AVPlayerArkTSAudio)

更多关于HarmonyOS鸿蒙Next中通过AVPlayer如何实现音乐播放、暂停、音量设置?的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


效果展示

cke_21416.png

实现思路

  • 传统操作音乐播放:传统写项目(淘宝京东)就是一个个html文件,里面写Javascript代码(切记不允许全部看代码,看大步骤)

1 获取音乐对象 player 2 调用api 播放play、暂定pause等等

<audio
  controls
  src="http://tmp00002.zhaodashen.cn/mp3/chenyixun_000z2oXY18Hsli.m4a"
></audio>

<button id="playerBtn">播放</button>
<button id="pausereBtn">暂停</button>
<script>
  // 1 获取实例
  const player = document.querySelector("audio");
  //   console.log("player::: ", player);
  // 2 调用api播放
  playerBtn.onclick = () => {
    player.play();
  };
  pausereBtn.onclick = () => {
    player.pause();
  };
</script>
  • 鸿蒙操作音乐播放语法
import {media} from '@kit.MediaKit'


// ✅ 1. 创建音乐播放器对象
const player:media.AVPlayer  = await media.createAVPlayer()

// ✅ 2. 侦听播放状态(监控设置地址)
player.on('stateChange', (state) => {
    switch(state) {
        // 初始化状态
        case 'initialized':
            player.prepare() // 准备就绪态
            break;
        // 准备就绪态
        case 'prepared':
            player.play() // 播放
            break;
    }
})
player.on('durationUpdate', (duration) => {}) // 歌曲时长
player.on('timeUpdate', (data) => {}) 				// 播放时长
player.on('volumeChange', () => {})  // 音量


// ✅ 3. 调用API控制状态

// - 播放地址
player.url = 播放源地址

// - 切换播放地址
await player.reset()
player.url = 播放源地址

// - 暂停
player.pause()

// - 音量
player.setVolume(0~1范围)

// - 循环播放
player.loop = 布尔

// - 播放速率
player.setSpeed(media.PlaybackSpeed.SPEED_FORWARD_0_75_X)
player.setSpeed(media.PlaybackSpeed.SPEED_FORWARD_1_00_X)
player.setSpeed(media.PlaybackSpeed.SPEED_FORWARD_1_25_X)
player.setSpeed(media.PlaybackSpeed.SPEED_FORWARD_1_75_X)
player.setSpeed(media.PlaybackSpeed.SPEED_FORWARD_2_00_X)

// - 本地播放
//这里的音频资源是放在rawfile文件夹中的.mp3文件,读者自己设置其他文件资源。
//给播放器设置播放资源,上图有参考资料,使用的是fsSrc资源,不是网络资源->。
const fd = getContext().resourceManager.getRawFdSync(name)
this.avplayer.fdSrc = { fd: fd.fd, offset: fd.offset, length: fd.length }

完整代码

import {media} from '@kit.MediaKit'


export class DateUtil {
  static m2s(ms:number) {
    // 分钟 = parseInt(总毫秒/1000/60) 得到分钟然后不够补0    这个parseInt是为了去掉小数
    const m = parseInt(String(ms/1000/60)).toString().padStart(2,'0');
    // 秒数 = parseInt(总毫秒/100得到秒 - 分占用的秒)   最终秒数  不够补0
    // const s = parseInt(String(ms/1000 - parseInt(m)*60)).toString().padStart(2,'0')
    const s = parseInt(String(ms/1000%60)).toString().padStart(2,'0')
    return `${m}:${s}`
  }
}


@Entry
@Component
struct Index {

  // "[al:认了吧]"
  // "[00:00.00]爱情转移 - 陈奕迅 (Eason Chan)"
  // "[00:05.73]词:林夕"
  @State currentLrc:string = ''
  private lrc: string[] = "[ti:爱情转移 (《爱情呼叫转移》电影主题曲|《富士山下》国语版)]\n[ar:陈奕迅]\n[al:认了吧]\n[by:]\n[offset:0]\n[00:00.00]爱情转移 - 陈奕迅 (Eason Chan)\n[00:05.73]词:林夕\n[00:11.47]曲:泽日生\n[00:17.21]编曲:陈珀/C.Y.Kong\n[00:22.95]徘徊过多少橱窗\n[00:25.29]住过多少旅馆\n[00:27.54]才会觉得分离也并不冤枉\n[00:31.89]感情是用来浏览\n[00:34.15]还是用来珍藏\n[00:36.55]好让日子天天都过得难忘\n[00:40.98]熬过了多久患难\n[00:43.37]湿了多少眼眶\n[00:45.63]才能知道伤感是爱的遗产\n[00:50.22]流浪几张双人床\n[00:52.63]换过几次信仰\n[00:54.77]才让戒指义无反顾的交换\n[00:59.28]把一个人的温暖\n[01:01.70]转移到另一个的胸膛\n[01:04.74]让上次犯的错反省出梦想\n[01:08.48]\n[01:08.98]每个人都是这样\n[01:11.27]享受过提心吊胆\n[01:13.74]才拒绝做爱情待罪的羔羊\n[01:18.21]回忆是抓不到的月光握紧就变黑暗\n[01:22.84]等虚假的背影消失于晴朗\n[01:26.67]\n[01:27.34]阳光在身上流转\n[01:29.53]等所有业障被原谅\n[01:32.62]\n[01:34.94]爱情不停站\n[01:36.78]想开往地老天荒\n[01:39.34]需要多勇敢\n[01:41.35]\n[01:43.58]烛光照亮了晚餐\n[01:45.95]照不出个答案\n[01:48.20]恋爱不是温馨的请客吃饭\n[01:52.18]\n[01:52.69]床单上铺满花瓣\n[01:55.11]拥抱让它成长\n[01:57.33]太拥挤就开到了别的土壤\n[02:01.79]感情需要人接班\n[02:04.22]接近换来期望\n[02:06.51]期望带来失望的恶性循环\n[02:10.96]短暂的总是浪漫\n[02:13.31]漫长总会不满\n[02:15.57]烧完美好青春换一个老伴\n[02:19.59]\n[02:20.12]把一个人的温暖\n[02:22.45]转移到另一个的胸膛\n[02:25.28]让上次犯的错反省出梦想\n[02:29.14]\n[02:29.86]每个人都是这样\n[02:32.03]享受过提心吊胆\n[02:34.42]才拒绝做爱情待罪的羔羊\n[02:39.01]回忆是抓不到的月光握紧就变黑暗\n[02:43.54]等虚假的背影消失于晴朗\n[02:47.43]\n[02:48.08]阳光在身上流转\n[02:50.38]等所有业障被原谅\n[02:53.37]\n[02:54.86]爱情不停站\n[02:56.83]想开往地老天荒\n[02:59.79]需要多勇敢\n[03:01.88]\n[03:04.22]把一个人的温暖\n[03:06.75]转移到另一个的胸膛\n[03:09.60]让上次犯的错反省出梦想\n[03:13.70]\n[03:14.21]每个人都是这样\n[03:16.61]享受过提心吊胆\n[03:19.08]才拒绝做爱情待罪的羔羊\n[03:23.82]回忆是抓不到的月光握紧就变黑暗\n[03:28.46]等虚假的背影消失于晴朗\n[03:32.54]\n[03:33.11]阳光在身上流转\n[03:35.47]等所有业障被原谅\n[03:38.67]\n[03:42.48]爱情不停站\n[03:44.28]想开往地老天荒\n[03:47.24]\n[03:47.82]需要多勇敢\n[03:50.26]\n[03:53.07]你不要失望\n[03:54.75]荡气回肠是为了\n[03:57.64]最美的平凡".split('\n')


  @State duration:number = 0
  @State currentTime:number = 0

  // private player: media.AVPlayer = {} as media.AVPlayer
  // private player: media.AVPlayer = {} as ESObject
  private player: media.AVPlayer = Object()


  async aboutToAppear() {
    // ✅ 1. 创建音乐播放器对象
    // const player:media.AVPlayer  = await media.createAVPlayer()  切记player放外面 后期要操作
    this.player = await media.createAVPlayer()

    // ✅ 2. 侦听播放状态
    this.player.on('stateChange', (state) => {
      switch(state) {
        // 初始化状态
        case 'initialized':
          console.log('11111 initialized')
          this.player.prepare() // 准备就绪态
          break;
        // 准备就绪态
        case 'prepared':
          console.log('2222 prepared')
          this.player.play() // 播放
          break;
      }
    })
    this.player.on('durationUpdate', (duration) => { // 歌曲时长
      console.log('歌曲时长:', duration)
      this.duration = duration
    })
    this.player.on('timeUpdate', (time) => {  // 播放时长
      console.log('播放时长:', time)
      this.currentTime = time

      for (let i=0; i<this.lrc.length; i++) {
        const item = this.lrc[i]
        const m2s = item.slice(1,6)  // '01:11'
        if (DateUtil.m2s(time) === m2s) {
          this.currentLrc = item.slice(10)
        }
      }
    })
    // this.player.on('volumeChange', () => {})  // 音量
  }
  build() {
    Column() {
      Text('hello music').fontSize(30)


      Button('打开界面(设置播放链接)').onClick(() => {
        this.player.url = 'http://tmp00002.zhaodashen.cn/mp3/chenyixun_003u2qmP0Mp2pW.m4a'
      }).margin({bottom:20})
      Button('播放').onClick(() => this.player.play()).margin({bottom:20})
      Button('暂停').onClick(() => this.player.pause()).margin({bottom:20})
      Button('换一首').onClick(async () => {
        await this.player.reset()
        this.player.url = 'http://tmp00002.zhaodashen.cn/mp3/wangjingwenbupang_0017ZGNs0ISfYi.m4a'
      }).margin({bottom:20})


      Text(`播放进度:${this.currentTime} 、 ${this.duration}`).fontSize(20)
      Text(DateUtil.m2s(this.currentTime)).fontSize(20)
      Slider({
        value: this.currentTime,
        min: 0,
        max: this.duration,
        style: SliderStyle.OutSet
      })
        .showTips(true)
        .onChange((value: number, mode: SliderChangeMode) => {
          console.info('value:' + value + 'mode:' + mode.toString())
          if (mode === 2) {
            this.player.seek(value)
          }

        })
      Text(DateUtil.m2s(this.duration)).fontSize(20).margin({bottom:50})

      Text('音量🔊').fontSize(20)
      Slider({
        value: 100,
        min: 0,
        max: 100,
        style: SliderStyle.OutSet
      })
        .showTips(true)
        .onChange((value: number, mode: SliderChangeMode) => {
          console.info('value:' + value + 'mode:' + mode.toString())
          // this.player.setVolume(0~1范围)
          this.player.setVolume(value/100)
        })


      Text(this.currentLrc).fontSize(30)
    }.padding(50)
  }
}

在HarmonyOS Next中,使用AVPlayer实现音乐播放:

  1. 创建AVPlayer实例,设置音频源(如URL或文件路径)。
  2. 调用prepare()准备播放器,通过play()开始播放,pause()暂停。
  3. 音量设置:通过AVPlayervolume属性调整,范围0.0(静音)到1.0(最大)。
  4. 监听播放状态变化,使用stateChange事件处理播放、暂停等状态。

在HarmonyOS Next中,使用AVPlayer实现音乐播放、暂停和音量设置的核心步骤如下:

1. 创建与初始化AVPlayer

import media from '@ohos.multimedia.media';

// 创建AVPlayer实例
let avPlayer: media.AVPlayer;
avPlayer = await media.createAVPlayer();

// 设置播放源(以网络音频为例)
avPlayer.url = 'https://example.com/audio.mp3';

2. 实现播放控制

// 准备播放
await avPlayer.prepare();

// 开始播放
avPlayer.play();

// 暂停播放
avPlayer.pause();

// 停止播放(释放资源)
avPlayer.stop();
avPlayer.release();

3. 音量设置

import audio from '@ohos.multimedia.audio';

// 获取音频管理器
let audioManager = audio.getAudioManager();

// 设置媒体音量(范围0.0-1.0)
audioManager.setVolume(audio.AudioVolumeType.MEDIA, 0.7);

// 或通过AVPlayer的音量属性设置(部分版本支持)
// avPlayer.volume = 0.5;

4. 关键配置与权限

  • module.json5中添加权限:
{
  "requestPermissions": [
    {
      "name": "ohos.permission.INTERNET"
    }
  ]
}
  • 添加多媒体能力:
{
  "abilities": [
    {
      "name": "EntryAbility",
      "srcEntry": "./ets/entryability/EntryAbility.ets",
      "backgroundModes": ["audioPlayback"]
    }
  ]
}

5. 事件监听(可选)

// 监听播放状态变化
avPlayer.on('stateChange', (state: string) => {
  console.log('Current state:' + state);
});

// 监听错误事件
avPlayer.on('error', (error: BusinessError) => {
  console.error('Playback error:' + JSON.stringify(error));
});

注意事项:

  1. 确保网络权限和音频后台播放能力已正确配置
  2. 播放完成后及时调用release()释放资源
  3. 音量设置通常通过系统AudioManager统一管理
  4. 实际开发中需处理生命周期,避免后台播放被中断

以上代码基于HarmonyOS Next API 10+,具体实现可能因版本调整而略有差异。

回到顶部