最新消息:看到那些跳动的图片、文字了吗?点击点击 O(∩_∩)O~~

微信小程序 BackgroundAudioManager currentTime、duration 的问题以及如何规避

若思若想 onlyling 6053浏览

BackgroundAudioManager 文档

在微信小程序中,BackgroundAudioManager 是一个很棒、很实用的 API,他可以跨页面使用。

一般情况,音频(AudioContext)播放只在当前页面使用,一旦离开页面,就会自动停止播放。如果想在切换页面的时候保持音乐不停播,就要使用到 BackgroundAudioManager 才行。

BackgroundAudioManager 整个应用中只有一个实例,无论在哪个页面、哪个小程序的生命周期里,wx.getBackgroundAudioManager() 得到的实例都是同一个,可以自由的获取。

const backgroundAudioManager = wx.getBackgroundAudioManager();

// 每次播放音乐的时候,这三个是必要的,否则可能存在不能播放的情况
backgroundAudioManager.title = '此时此刻';
backgroundAudioManager.epname = '此时此刻';
backgroundAudioManager.singer = '许巍';

在做音乐播放的是,可能会遇见显示播放进度的需求,要么“00:00/01:00”这样文字的显示,要么进度条的方式。

BackgroundAudioManager 里面有几个非常棒的属性。

  • currentTime [Number] 当前音频的播放位置(单位:s),只有在有合法 src 时返回。(只读)
  • duration [Number] 当前音频的长度(单位:s),只有在有合法 src 时返回。(只读)
  • src [String] 默认为空字符串,当设置了新的 src 时,会自动开始播放,目前支持的格式有 m4a, aac, mp3, wav。

有了这两个数据,进度就可以完美的显示出来。

AudioContext 也有这两个属性,遇见问题,可以尝试一下以下方式规避。

duration 当前音频的长度

在微信小程序中,它的规范时只读,只能被动的获取。

backgroundAudioManager.src = 'your aduio url';

console.log(backgroundAudioManager.duration);

假设如上获取一段音频的时长,会存在获取不到的情况,虽然更新了 src,但是音频初次播放需要一点时间加载,所以,立即响应可能获取不到对应的时长。

那么,当音频能播放的时候再去获取呢?

backgroundAudioManager.onCanplay(() => {
    console.log(backgroundAudioManager.duration);
    setTimeout(() => {
        // Yes, I can
        console.log(backgroundAudioManager.duration);
    }, 500);
});

经过 Android 真机、微信开发者工具实测,也存在一定的几率获取不到时长。最后,通过一个延迟才获取到,具体延迟多少比较合适,暂时没有深究。

如果还不能获取,或者不能及时获取到,更新 src 后主动触发一下 backgroundAudioManager.play()backgroundAudioManager.pause()

currentTime 当前音频的播放位置

// 获取播放进度比例
const getProgress = () => {
    const duration = backgroundAudioManager.duration;
    // 可能还在初始化中
    if(!duration || duration === 0) {
        return 0;
    }

    // 当前音频位置
    const currentTime = backgroundAudioManager.currentTime || 0;

    return Math.floor((currentTime * 100) / duration);

}

// TODO 更新页面进度
let updateTimer;
const doUpdate = () => {
    const p = getProgress();
}

当第一次播放音频的时候,起始会从 0 开始,快结束的时候也会接近最后的时长,但当音频播放停止,currentTime 的值会莫名其妙的比 当前音频的长度少几秒。

getBackgroundAudioManager播放时间问题,类似这个问题,在微信开发者工具没有这个问题,Android 机器上会存在。

当第二次播放的时候,currentTime 会从上次那个错误的结束时间开始,当音频准备好后,又从 0 开始,再到错误的结尾。

错误的结尾,通过一个变量记录音频是否已经停止播放,直接返回 0。

错误的开始,通过一个变量记录音频是否已经初始化好,没有初始化,进度是 0,初始化好后真实数据计算。

let initialized = false; // 是否初始化
let isEnd = true; // 是否已经结束

backgroundAudioManager.onCanplay(() => {
    initialized = true;
});

backgroundAudioManager.onPlay(() => {
    isEnd = false;
});

backgroundAudioManager.onEnded(() => {
    isEnd = true;
    initialized = false;
});

// 获取播放进度比例
const getProgress = () => {
    if(!initialized) {
        return 0;
    }

    if(isEnd) {
        return 0;
        // return 1;
    }

    const duration = backgroundAudioManager.duration;
    // 可能还在初始化中
    if(!duration || duration === 0) {
        return 0;
    }

    // 当前音频位置
    const currentTime = backgroundAudioManager.currentTime || 0;

    return Math.floor((currentTime * 100) / duration);

}

具体业务中可能会涉及到 暂停 之类,暂不做分解。

最后,比较理想的获得了播放进度。

转载请注明:OnlyLing - Web 前端开发者 » 微信小程序 BackgroundAudioManager currentTime、duration 的问题以及如何规避