Skip to content

音频

部分前端业务需要播放音频,这里整理一下常见的问题

格式兼容

不同的浏览器对音频格式的支持不同,Audio 标签默认支持的主流的音频文件格式有 MP3、WAV、OGG

  • MP3(MPEG-1 Audio Layer 3)是一种使用有损压缩算法的音频格式。它能够显著减小文件大小,同时保持较高的音质。MP3 格式广泛应用于音乐下载和流媒体领域。由于其压缩算法的特性,MP3 文件的质量在一定程度上会受到影响,特别是低比特率的 MP3 文件可能会有明显的音质损失。
  • WAV(Waveform Audio File Format)是一种无损音频格式,以线性脉冲编码调制(LPCM)进行存储。它通常包含未经压缩的音频数据,因此质量保持较高。WAV 文件相对较大,适合存储音频的原始副本或需要保持最高音质的场景。
  • OGG 是一种开放的、免费的音频容器格式,支持多种音频编码,其中最常见的是 Vorbis 编码。OGG 文件可以提供较高的音质,并且在相对较小的文件大小下实现。相对于 MP3,OGG 可以在相同的比特率下提供更好的音频质量。然而,由于它的广泛兼容性相对较低,可能不被所有音频播放器或设备支持。

总结一下

  • WAV 格式音质最好,但是文件体积较大。
  • MP3 压缩率较高,普及率高,音质相比 WAV 要差。
  • OGG 与 MP3 在相同位速率(Bit Rate)编码的情况下,OGG 体积更小,并且 OGG 是免费的不用交专利费

自动播放

出于用户体验和广告滥用的考虑,现代浏览器对自动播放音频有一些限制。通常情况下,需要用户与页面进行交互后,才能触发音频的自动播放。

js
var audio = document.querySelector('audio');
document.addEventListener('click', function() {
  audio.play();
});

预加载

在 iOS safari 浏览器初始化一个新的音频流时会有几秒的延时。原因是因为 iOS 需要实例化一个新的音频对象,再通过网络请求音频资源,音频资源加载完毕之后才能进行播放

preload可以指定音频的预加载策略,也就是在播放之前需要提前加载好音频的哪些资源。

html
<audio src="audiofile.mp3" preload="auto"></audio>

该属性有三个枚举值nonemetadataauto,查到某些说法是在iOS Safari浏览器下和微信浏览器中预加载并不会生效

也可以通过load()方法触发音频文件的加载。如果浏览器不支持preload属性,则此方法也不会有效果。

js
audio.load();

因此,音频预加载更通用的方案是:第一次触摸的时候,音频静音,同时触发音频play()然后很快再pause(),此时可以有类似preload的预加载行为。

播放多个音频

项目中有切换不同音乐播放,如果采用更改 Audio 标签的 src 的方式,iOS 下会出现不能播放音乐或者播放延迟太高问题。

这种 bug 出现的原因是音频文件不能缓存在 iOS 系统上,每当页面访问其他音频文件时,都从网络访问音频文件,

解决方法:可以在页面中声明多个 Audio 标签,把需要引入的音频文件预先引入,播放哪个再调用相应文件。

这个方案的缺点是在 iOS 系统下每一个 Audio 占一个线程,如果有多个的 Audio ,则很占资源

另外一个思路是把多个音频文件合并成为一个文件,播放其他音频的时候只需要调用合并之后的音频文件的相应时段,虽然比较繁琐,但是兼容性很好

工具库

如果要做类似于网页音乐播放器之类的应用,可以考虑一些比较主流的音频工具库

  • Howler.js,提供了简单易用的 API,支持音频播放、暂停、音量控制、循环播放等功能,并具有优秀的性能和兼容性。

视频

与音频类型,视频也是前端业务中比较常见的多媒体

格式兼容

常见的视频格式如 MP4、WebM 和 Ogg 在不同浏览器上的支持情况可能有所差异

自定义UI

如果要自定义视频播放器,需要实现的组件包括

  • 操作按钮,如播放、暂停、音量控制等
  • 进度条,拖拽控制播放进度
  • 全屏,如果视频全屏播放则需要Fullscreen_API MDN

自动播放

外部字幕

预加载

可以通过video标签的preload属性来控制视频预加载,加快视频资源的播放

  • auto:浏览器将自动选择加载策略,默认值。浏览器可能会根据当前网络状况和设备性能自动决定何时加载视频。
  • metadata:仅加载视频的元数据(如时长、尺寸等),不加载视频内容。这对于获取视频信息而不立即播放视频很有用。
  • none:不预加载视频,直到用户明确要求播放视频才进行加载。

可以通过buffered属性得到视频已被缓冲的部分

js
video.addEventListener('progress', function() {
  var buffered = video.buffered;
  if (buffered.length > 0) {
    console.log('已缓冲的时间范围:');
    for (var i = 0; i < buffered.length; i++) {
      console.log('开始时间:', buffered.start(i));
      console.log('结束时间:', buffered.end(i));
    }
  }
});

直播

参考

直播视频格式

  • hls更准确的说是一种视频协议,文件对应的后缀是ts,适配Safari浏览器,是苹果推出的视频协议
  • flv是早期的flash格式
  • MP4和WEBM是偏点播使用的视频格式(如爱奇艺)
  • TS和FLV是偏直播使用的视频格式(如斗鱼)

常用协议

  • hls协议,播放器使用video作为点播和直播的基石(将M3U8索引文件[是ts文件的索引]给video进行播放,播放时会被解析成多个ts直播流片段,浏览器会实时向服务器请求M3U8文件里面是每个片段,之后会再次下载,之后会再次请求M3U8等等,从而保证直播的实时和连续)
  • RTMP协议(开发客户端通常采用),TMP是Real Time Messaging Protocol(实时消息传输协议)的首字母缩写。该协议基于TCP,是一个协议族,包括RTMP基本协议及RTMPT/RTMPS/RTMPE等多种变种。RTMP是一种设计用来进行实时数据通信的网络协议,主要用来在Flash、AIR平台和支持RTMP协议的流媒体/交互服务器之间进行音视频和数据通信。
  • HTTP-FLV协议(兼备RTMP低延时和HLS传输快的特性,视频格式是FLV)

hls

接口返回一个hls的链接 ,然后交给客户端播放即可

todo