当前位置:首页>鸿蒙APP>v1.0.8版本先捉个BUG--鸿蒙音频播放器捉虫记

v1.0.8版本先捉个BUG--鸿蒙音频播放器捉虫记

  • 2026-09-12 12:03:46
v1.0.8版本先捉个BUG--鸿蒙音频播放器捉虫记
书接上回:我们在v1.0.7版本中实现了多条音乐的自动顺序播放,但是顺序播放对流程的控制和倒计时发生了冲突:每次切换到下一首歌,倒计时都会重新开始计时;但在单曲循环模式下却一切正常。设想一下,我们本想设定好30分钟睡眠定时,结果每换一首歌就和月光宝盒一样时光倒流,重新开始计时,这不是永远睡不着了!💤

一、“犯罪现场” 寻找虫子活动的蛛丝马迹

首先看下出问题的顺序播放的代码:

// 在顺序播放完成时else if (this.playMode === PlayMode.SEQUENTIAL) {    console.info('执行顺序播放,尝试播放下一首');    if (this.currentAudioIndex < this.audioList.length - 1) {        const nextIndex = this.currentAudioIndex + 1;        this.updateStatus(`顺序播放,下一首: ${this.audioList[nextIndex].name}`);        this.playAudioByIndex(nextIndex); // 这里调用了播放下一首    }    // ...}

这里并没有重新开始倒计时的动作。

我们再看看播放函数:

async playAudioByIndex(index: number) {    // ... 一些检查代码    await this.playAudioFile(audioFile.fileName, audioFile.name);}async playAudioFile(fileName: string, audioName: string) {    // ... 准备播放器的代码    this.startCountdown(); // 倒计时每次都从这里开始!}

真相水落石出:每次在调用playAudioFile()函数时,都会执行startCountdown()函数,重启倒计时。

那么问题来了,为什么单曲循环模式,不会重启倒计时呢?还是得看代码:

if (this.playMode === PlayMode.SINGLE_LOOP) {    // 注意这里!单曲循环是直接操作当前播放器    this.avPlayer!.seek(0);    this.avPlayer!.play();    // 没有调用 playAudioByIndex,所以倒计时不会重启}

可以看出来,单曲循环模式是对当前播放器进行操作,并没有重建一个播放器实例,而是把当前播放器的播放进度重置为0,然后开始播放。没有调用播放函数,因此也就没有重启倒计时。

关键线索:

播放模式
切换方式
是否重新初始化播放器
单曲循环
seek(0) + play()
否
顺序播放
调用 playAudioByIndex()
是

playAudioByIndex() 方法每次都会重新创建播放器,并无条件地调用startCountdown(),导致倒计时被重置。

二、解决方案:是否启动倒计时加个“开关”

  1. 区分场景:

        当用户主动操作 → 重置倒计时;当顺序播放自动切换时 → 不重置倒计时。

  2. 具体修改点:

    在playAudioByIndex()和playAudioFile()增加参数,根据参数判断是否重启倒计时。

    // v1.0.8 修改:增加参数控制是否重置倒计时async playAudioByIndex(index: number, resetCountdown: boolean = true) {    if (index < 0 || index >= this.audioList.length) {        this.updateStatus('音频索引无效');        return;    }    const audioFile = this.audioList[index];    this.currentAudioIndex = index;    await this.playAudioFile(audioFile.fileName, audioFile.name, resetCountdown);}// v1.0.8 修改:增加resetCountdown参数async playAudioFile(fileName: string, audioName: string, resetCountdown: boolean = true) {    try {        // 释放之前的播放器        await this.releasePlayer();        // 更新状态        this.updateStatus(`正在加载: ${audioName}...`);        this.playerState = PlayerState.PREPARING;        // 创建AVPlayer实例        this.avPlayer = await media.createAVPlayer();        // 设置事件监听        this.setAVPlayerCallbacks();        // 获取ResourceManager并打开rawfile资源        let resourceMgr = this.context.resourceManager;        let fileDescriptor = await resourceMgr.getRawFd(fileName);        // 设置音频源        this.avPlayer.fdSrc = {            fd: fileDescriptor.fd,            offset: fileDescriptor.offset,            length: fileDescriptor.length        };        console.info(`音频源设置成功: ${audioName}`);        // v1.0.8 修改:根据参数决定是否启动倒计时        if (resetCountdown) {            this.startCountdown();        }    } catch (error) {        console.error('播放音频出错:', error);        this.updateStatus(`播放失败: ${error.message}`);        this.playerState = PlayerState.ERROR;        this.clearCountdown();    }}

    在顺序播放模式处增加参数,值为false,表示不重置倒计时:

    // v1.0.8 修改:传递false,表示不重置倒计时            this.playAudioByIndex(nextIndex, false);

    在点击列表某条音乐,以及点击上一首,下一首按钮,手动切换音乐时,重启倒计时:

    // 用户主动点击列表时,应该重置倒计时.onClick(() => {    this.currentAudioIndex = index;    // 用户主动点击时重置倒计时    this.playAudioByIndex(index, true);})// 上一首/下一首按钮async playPrev() {    if (this.audioList.length === 0) return;    let prevIndex = this.currentAudioIndex - 1;    if (prevIndex < 0) {        prevIndex = this.audioList.length - 1;    }    // 用户主动切换时重置倒计时    await this.playAudioByIndex(prevIndex, true);}async playNext() {    if (this.audioList.length === 0) return;    let nextIndex = this.currentAudioIndex + 1;    if (nextIndex >= this.audioList.length) {        nextIndex = 0;    }    // 用户主动切换时重置倒计时    await this.playAudioByIndex(nextIndex, true);}

    3. 修改后的使用场景对比表:

使用场景
resetCountdown 参数值
是否重启倒计时
说明
用户点击列表歌曲
true
是
主动选择,重新计时
点击上一首/下一首
true
是
主动切换,重新计时
顺序播放自动切换
false
否
自动切换,继续计时
单曲循环
不涉及
否
保持原有倒计时方案

大功告成:让我们安心的欣赏音乐吧。

播放器完整代码可在评论区留言“1”获取!~

预计下个版本(v1.0.9)将实现随机播放,欲知后事如何,且听下回~分~解!

最新文章

随机文章