收藏
回答

wx.createInnerAudioContext播放同一个音频第二次会卡顿

框架类型 问题类型 API/组件名称 终端类型 微信版本 基础库版本
小程序 Bug wx.createInnerAudioContext 微信安卓客户端 8.0.60 3.8.8

偶尔有安卓用户反馈同一个音频播放第一遍时正常,第二遍以后就卡顿。目前没收到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();




最后一次编辑于  1天前
回答关注问题邀请回答
收藏
登录 后发表内容