3

需求背景

H5页面上一组音频,需要获取每个音频的时长,展示在页面上,尝试使用Audio对象,在canplay或者loadedmetadata事件中,获取audio.duration

audioList.forEach((audioItem, index) => {
    let audio = new Audio(audioItem.voiceUrl)
    audio.onloadedmetadata = function () {
        console.log(audio.duration);
    }
    audio.oncanplay = function () {}
    audio.onerror = function () {
         console.log('音频加载失败') 
    }
})

问题

在浏览器上是没有什么问题的,可以正常获取,但是在ios手机上打开之后,发现只有手动触发了audio的play事件后,才会打印出duration

解决方法

由于ios对audio和video的一系列限制,包括提前load和自动播放等,audio的canpplay,loadedmetadata等事件只有在用户手动的play之后,才会触发,此时才能获取duration,可以通过设置audio为静音,再在用户手动触发play之前,用代码触发play事件来解决,不过要注意暂停
如下

audioList.forEach((audioItem, index) => {
    let audio = new Audio(audioItem.voiceUrl)
    audio.muted = true
    audio.play().then(() => audio.pause();)
    audio.addEventListener('loadedmetadata', function () {
      console.log('音频加载成功', Math.round(audio.duration))
    })
    audio.muted = false
    audio.oncanplay = function () {}
    audio.onerror = function () {
         console.log('音频加载失败') 
    }
})

tips

虽然ios对audio和video的播放都有限制,但是在静音(也就是通过设置muted = true)的情况下这两者都是可以自动播放的,由此可以想到,在要求自动播放的情况下,可以选择静音播放,给用户一个图标标识可以打开声音,体验会更好。


羊羊羊
1.7k 声望59 粉丝

没人能在我的BGM里战胜我