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')
})
}
我在 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')
})
}