uni-app uni.getBackgroundAudioManager()的使用问题

uni-app uni.getBackgroundAudioManager()的使用问题

操作步骤:

  • 播放后暂停在播放
  • 拉动进度条执行seek

预期结果:

  • onTimeUpdate可正常触发

实际结果:

  • onTimeUpdate不触发

bug描述:

在使用uni.getBackgroundAudioManager()时,在触发seek后,或者在暂停后继续播放,onTimeUpdate执行一次后不会继续执行(有时直接不执行)。使用了红米K30S,小米10 (安卓11)都会发生这样的问题,使用荣耀v10(安卓10)、电脑模拟器 不会发生这样的问题。

开发环境 版本号 项目创建方式
Windows win10 HBuilderX

相关链接:

附件


更多关于uni-app uni.getBackgroundAudioManager()的使用问题的实战教程也可以访问 https://www.itying.com/category-93-b0.html

13 回复

大佬们看过来,看看啥情况啊【哭】

更多关于uni-app uni.getBackgroundAudioManager()的使用问题的实战教程也可以访问 https://www.itying.com/category-93-b0.html


用示例代码hello uni-app能出现你的问题吗? 在什么设备上可稳定复现此问题? 此设备在旧版是否正常?

非常感谢回复。示例代码hello uni-app刚刚试了下,没有发生这种情况。我现在使用的是红米k30s(android11)会一直这种情况。在8.20之前的发布版本,当时是测试没问题的,然而现在安装当时的旧版本也会有这个问题了(卸载重装、清除缓存都没有用)。在插件市场打包安装其他的使用uni.getBackgroundAudioManager()的也会出现这种情况

回复 canace: 请提供可稳定复现直接运行的完整示例(上传附件),方便我们快速排查问题哦。 【正确报bug的姿势】https://ask.dcloud.net.cn/article/38139

回复 DCloud_UNI_Anne: 你好,我从插件市场找了个seek后onTimeUpdate不更新的样例,已上传附件,使用红米k30s测试是不更新的

回复 canace: 用示例代码hello uni-app一直都是正常的吗?

回复 DCloud_UNI_Anne: 使用的是官方的音乐链接地址,容易失效,麻烦测试时使用下面两个接口去获取最新的音乐地址: http://api.music.canace.cn/v1/kuwo/song?mid=192855469 ,取url里面的地址; http://api.music.canace.cn/v1/kugou/song?hash=60E2852AE95C6CA399D464CB5734467B&aid=48960639,取play_url的地址

回复 canace: 用你提供的音频复现此问题,这边先排查下

问题已确认,后续优化,已加分,感谢您的反馈!

请问这个问题什么时候能够修复

HBuilder X 3.3.0-alpha已修复,请升级

3.8.4.20230531这个版本也出现这个问题了

根据你描述的问题,这确实是 uni.getBackgroundAudioManager() 在部分安卓机型(特别是较新版本)上存在的一个已知兼容性问题。核心原因是底层音频引擎在不同安卓系统版本和厂商定制系统上的实现差异。

问题分析: onTimeUpdate 回调的触发依赖于系统音频播放器内部定时器的稳定工作。在 seek 操作或 pause -> play 操作后,这个定时器在某些系统上可能被异常重置或挂起,导致回调停止。

直接解决方案:

  1. 使用备用定时器: 最有效且可控的方案是不依赖 onTimeUpdate,而是使用 uni.createInnerAudioContext() 配合 setInterval 模拟进度更新。

    // 创建音频上下文
    const innerAudioContext = uni.createInnerAudioContext();
    innerAudioContext.src = 'your_audio_url';
    // 使用定时器主动获取当前播放位置
    let progressTimer = null;
    innerAudioContext.play();
    progressTimer = setInterval(() => {
        let currentTime = innerAudioContext.currentTime;
        let duration = innerAudioContext.duration;
        // 更新你的UI进度条
        console.log(currentTime, duration);
    }, 500); // 500ms更新一次,频率可调
    
    // 在暂停、停止或销毁时清除定时器
    innerAudioContext.onPause(() => {
        clearInterval(progressTimer);
    });
    
  2. 降级使用 uni.createInnerAudioContext() 如果不需要后台播放功能,uni.createInnerAudioContext() 的兼容性和稳定性通常更好,其 onTimeUpdate 也更可靠。

  3. 针对 BackgroundAudioManager 的补救措施: 如果必须使用后台播放,可以尝试在 seekplay 后,短暂延迟并重新触发播放来“唤醒”定时器(此方法不保证有效,属于尝试性修复):

    audioManager.seek(position);
    audioManager.play();
    // 尝试性修复:短暂暂停后重新播放
    setTimeout(() => {
        audioManager.pause();
        setTimeout(() => {
            audioManager.play();
        }, 50);
    }, 100);
回到顶部