Html5 首次在 iPhone ionic 5 中未加载音频

Html5 audio does not loading first time in iPhone ionic 5

我在 IONIC 5 中使用 HTML 5 音频来播放音频。我不使用 HTML 音频控件。我使用 ion-range 创建自己的控件搜索栏。 离子应用 运行 在 android 中符合预期,但在 iPhone 中产生了问题。当我在 iPhone 上部署应用程序时,第一次没有加载音频。当用户访问应用程序的另一个页面然后移动到音频页面时,它会按预期加载音频。 我的 HTML 标签是

<audio id="{{i}}" class="audio" playsinline>
        <source src="{{music.url}}" type="audio/mp3">
      </audio>

我在 ionViewWillEnter 中获取音频持续时间,也尝试使用 ionViewDidLoad,但出现相同的错误。我怎样才能解决这个问题。 请看看我的 ts 代码。

ionViewWillEnter() {
    this.utils.showLoading('please wait...');
    setTimeout(() => {
      this.utils.hideLoading();
      this.musicList.forEach((music, index) => {
        var audio: any = document.getElementById((index);
        music.duration = this.calculateDuration(audio.duration);
        music.maxRange = audio.duration;
      });
    }, 1000);
  }

问题在于您不知道音频是否已准备好播放。您只需设置 1 秒的加载时间,假设它就足够了,但实际上并非如此。

查看媒体事件文档。您需要创建一个 listener/override canplaythrough 事件,以便您知道音频何时加载到浏览器上。

根据你的情况,它会是这样的

//it's better to use viewDidLoad in your case because it only runs on the page instatiation
async ionViewDidLoad() {
  await this.utils.showLoading('please wait...'); //remember loading instantiations and presentation returns a promise
  
  const MAX_WAIT = 10000 //maximum wait time in ms
  const loadings = []

  this.musicList.forEach((music, index) => {
    const audio: any = document.getelementById(index)
    const p = new Promise((resolve, reject) => {
      // creating a timeout handler
      const timeoutHandler = setTimeout(() => {
        const errorMsg = `Timeout waiting audio ${index} to load/buffer` 
        console.error(errorMsg)
        reject(new Error(errorMsg))
      }, MAX_WAIT)
      
      // overriding the oncanplaythrough event handler
      audio.oncanplaythrough = (event) => {
        music.duration = this.calculateDuration(audio.duration);
        music.maxRange = audio.duration;

        console.log(`audio ${index} is loaded and buffered enough to play without interruptions`)
        clearTimeout(timeoutHandler) //clearing the timeout handler
        resolve()
      }
    })

    // pushing the loading the promise arrays
    loadings.push(p)
  })

  //waiting all audios to load
  Promise.all(loadings).then(()=> {
    console.log('all audios loaded')
    this.utils.hideLoading()
  }).catch((error)=> {
    this.utils.hideLoading()
    console.error('error loading some files')
  })

}