Audio标签二次开发时遇到的坑

Audio

Posted by gomyck on June 24, 2019

博客播放器开发过程中遇到的坑

audio标签扫盲(可跳过)

audio标签提供了HTML页面播放音频资源的能力

标签属性

1
2
3
4
5
6
autoplay  如果出现该属性,则音频在就绪后马上播放。
controls  如果出现该属性,则向用户显示控件,比如播放按钮。
loop      如果出现该属性,则每当音频结束时重新开始播放。
muted     规定视频输出应该被静音。
preload   如果出现该属性,则音频在页面加载时进行加载,并预备播放。如果使用 "autoplay",则忽略该属性。
src url   要播放的音频的 URL。

audio标签事件

点我进入w3c学习

audio对象方法

点我进入w3c学习

—-爬坑篇—-

因audio标签默认的外观严重偏离个人审美观, 故决定对audio标签进行二次开发

开发过程忽略, 直接上有问题的代码片段(以下代码经过简化处理, 只保留有价值的信息):

HTML:
1
<audio id="playerAudio" preload="auto" loop src="uri"></audio>
JavaScript
1
2
3
4
5
6
window.onload = function() {
  const audio = document.getElementById('playerAudio');
  audio.addEventListener("canplaythrough", function () {
    //do something....
  }, false);
};

canplaythrough 为audio标签的一个事件, 在音频资源可以播放时触发(不一定加载完毕)

以上代码中的监听在播放器准备OK时并不会触发, 查资料, 看官方文档并没有发现兼容性或者写法的问题

打开F12调试, 发现页面正常渲染, 代码正常执行无错误

多次调试无果之后, 忽然在拖动进度条的时候, 该监听事件被触发了(一直以为监听并没生效. 拖动进度条代表IO读取的变动, 也会触发该方法), 说明问题不是出现在代码上, 而是其他地方, 思前想后, 觉得是注册监听的时间线出现问题

即(可能): 注册事件时间应 < 标签渲染时间

因为在监听是在window.onload时注册的, 此时页面所有元素已渲染完毕, audio标签已经在此之前就触发了canplaythrough, 所以在此时注册的监听, 不会达到想要的效果

一番修改之后, 监听成功生效, 附代码:

1
<audio id="playerAudio" oncanplaythrough="initPlayer(this)" preload="auto" loop src="uri"></audio>
1
2
3
function initPlayer(_this) {
  //do something....
};

结论

1.不要把这个监听写在onload方法中, 这里涉及到一个先有鸡还是先有蛋的哲学问题

2.写在标签内的属性靠谱