偶尔有安卓用户反馈同一个音频播放第一遍时正常,第二遍以后就卡顿。目前没收到ios用户的反馈,只有安卓用户反馈(oppo和一加),我自己用一些安卓设备没有复现。
最早在3月中的时候就收到过反馈,看日志是用户的基础库版本升级后才出现问题,所以问题在早于3.8.8的版本应该就有。
昨天收到反馈的用户日志如下,看不出啥问题:
2025-6-15 15:46:0 [log] App onShow have been invoked 2025-6-15 15:46:0 [log] wx.getStorageSync api invoke 2025-6-15 15:46:0 [log] wx.getStorageSync return 2025-6-15 15:46:0 [log] page pages/reader/index onShow have been invoked 2025-6-15 15:46:2 [log] wx.createInnerAudioContext api invoke 2025-6-15 15:46:2 [log] wx.createInnerAudioContext return 2025-6-15 15:46:2 [log] wx.createSelectorQuery api invoke 2025-6-15 15:46:3 [log] wx.createSelectorQuery api invoke 2025-6-15 15:46:13 [log] wx.createInnerAudioContext api invoke 2025-6-15 15:46:13 [log] wx.createInnerAudioContext return 2025-6-15 15:46:13 [log] wx.createSelectorQuery api invoke 2025-6-15 15:46:14 [log] wx.createSelectorQuery api invoke 2025-6-15 15:46:14 [log] wx.createInnerAudioContext api invoke 2025-6-15 15:46:14 [log] wx.createInnerAudioContext return 2025-6-15 15:46:20 [log] wx.createInnerAudioContext api invoke 2025-6-15 15:46:20 [log] wx.createInnerAudioContext return 2025-6-15 15:46:26 [log] wx.getNetworkType api invoke
代码的逻辑大致是播放音频就用wx.createInnerAudioContext创建并播放,播放第二次或者其他音频就destroy掉之前的context,再创建一个新的。
import type { Track } from '../interface';
class AudioContext {
context: UniNamespace.InnerAudioContext | null;
onTimeUpdateFunc: (percent: number) => void;
isPlaying: boolean;
timer: any;
start: number;
setCurrentTrack: (id: number) => void;
setPercent: (percent: number) => void;
constructor() {
this.context = null;
this.onTimeUpdateFunc = () => {};
this.isPlaying = false;
this.setCurrentTrack = () => {};
this.setPercent = () => {};
this.start = new Date().getTime();
}
init() {
this.destroy();
uni.setInnerAudioOption({
obeyMuteSwitch: false,
}); // ios静音模式也能播放声音
this.timer = setInterval(() => {
if (this.isPlaying && this.context && this.context.duration) {
this.onTimeUpdateFunc(
(new Date().getTime() - this.start) / 1000 / this.context.duration
);
}
}, 200);
}
play(track: Track, canStopPrev = true) {
if (canStopPrev || !this.isPlaying) {
this.stop();
this.context = uni.createInnerAudioContext();
this.context.obeyMuteSwitch = false; // ios静音模式也能播放声音
this.context.onEnded(() => {
this.isPlaying = false;
this.onTimeUpdateFunc(1);
this.onTimeUpdateFunc = () => {};
this.setCurrentTrack(-1);
});
this.context.onCanplay(async () => {
if (!this.isPlaying) {
this.context!.play();
this.isPlaying = true;
this.start = new Date().getTime();
}
});
this.context.onError((error) => {
console.log(error);
});
this.onTimeUpdateFunc = (percent: number) => {
this.setPercent(percent);
if (percent >= 1 && !this.isPlaying) {
uni.$emit('audioEnd', track.track_id);
}
};
this.onTimeUpdateFunc(0);
this.setCurrentTrack(track.track_id);
this.context!.src = track.track_url_source;
}
}
stop() {
if (this.context) {
this.context.destroy();
this.context = null;
}
this.setCurrentTrack(-1);
this.isPlaying = false;
this.onTimeUpdateFunc = () => {};
}
destroy() {
this.stop();
clearInterval(this.timer);
this.setCurrentTrack = () => {};
}
}
export const audioContext = new AudioContext();