xChar
·a year ago

马上又要开学了😭😭😭。

1.前言

我在为我的博客实现一个移动端使用的音乐播放器的时候,为了美观,我们不得通过调用audioapi来实现自己想要的样式,那么我们在使用他们的时候应该注意些什么呢。

2.audio的使用方法

要想了解它我们就应该知道它怎样被使用,下面是它的基本使用,有两种方式:

  1. 直接使用audio标签。这里我是使用的vue来动态的切换播放的音乐。

    <audio    :src="currentMusic.url"
              controls
              @ended="musicEnd"
              ref="myaudio"
              style="display:none;">
        您的浏览器不支持audio
    </audio>
    

    以上代码就是通过修改src来切换音频的播放,但是这里要注意几点:

    1. 以这种方式来切换音频是不需要调用this.$refs.myaudio.load()方法,它会自动的加载音频,,这是因为在vue中如果改变某个属性,那么将会引起浏览器的重排,从而会使浏览器自动的去获取音频数据
    2. 每次只有一个音频,可能会遇到浏览器不兼容的情况。
    3. 如果直接使用this.$refs.myaudio.play()可能会出现音频还没加载好你就调用这个方法来播放,在显然是不合理的。
  2. 使用source的方式。

    <audio controls>   
        <source id='test' src="http://music.163.com/song/media/outer/url?id=26447698.mp3" type="audio/mpeg">
        <source src="horse.ogg" type="audio/ogg">
    	您的浏览器不支持 audio 元素。 
    </audio>
    

    使用上面的这种方式可以通过添加多个source标签来实现对不同浏览器的格式兼容问题。其余的和第一种方式类似。

3.关于在什么时候调用play方法

如果你是直接在切换了src后调用play方法来播放,那么这样很有可能出现问题,例如这是一个切换下一首的方法:

next(){
      this.currentMusic = this.audio[this.current+1 === this.allMusic?this.current = 0:++this.current]
      this.$refs.myaudio.play()
   }
},

currentMusic表示当前的音乐,current为当前音乐的索引值,allMusic为总的音乐数量,audio为全部音乐的列表,在点击下一首时会调用这个方法,因为这是使用vue,所以每次切换src后,audio会重新加载,但是如果我们点击的过快,或者是网速过慢,那么将会出现一个错误。

DOMException: The play() request was interrupted by a new load request.

关于这个错误正如字面的意思一样,资源还没有准备好,你就开始播放了,这显然是错误的行为,那么如何解决这个问题呢?我们很快就能想到,如果我知道了资源准备好了,再去调用这个play方法来进行播放不久行了吗。当然正如你所见,HTML5提供了这些方法。

4.怎样确定使用play方法的时机

为了确定audio的数据是否加载好了我们可以通过在视频/音频(audio/video)加载过程中,会触发一个事件oncanplay 来通知你视频/音频已经可以播放了,用法如下:

this.currentMusic = this.audio[this.current - 1 === -1?this.current =this.allMusic - 1:--this.current]
this.$refs.myaudio.oncanplay =()=>{
    this.$refs.myaudio.play();
}

在切换完音频后,audio先会自动的加载音频,当加载完毕后会触发oncanplay来执行你想要的操作。

除了这一个事件对象,相应的还有onloadstart,ondurationchange,onloadedmetadata,onloadeddata,onprogress,oncanplaythrough

// onloadstart 事件在浏览器开始寻找指定视频/音频(audio/video)触发。
audio.onloadstart = function (){
    console.log('开始寻找指定视频/音频')
}
// ondurationchange 事件在视频/音频(audio/video)的时长发生变化时触发
// 注意:当视频/音频(audio/video)已经加载后,视频/音频(audio/video)的时长从 "NaN" 修改为正在的时长。
audio.ondurationchange = function (){
    console.log('视频/音频(audio/video)发生了改变')
}
// onloadedmetadata 事件在指定视频/音频(audio/video)的元数据加载后触发
// 注意:视频/音频(audio/video)的元数据包含: 时长,尺寸大小(视频),文本轨道。
audio.onloadedmetadata = function (){
    console.log('视频/音频(audio/video)的元数据被加载')
}
// onloadeddata 事件在当前帧的数据加载完成且还没有足够的数据播放视频/音频(audio/video)的下一帧时触发。
audio.onloadeddata = function (){
    console.log('当前帧的数据已经加载完成了,但是下一帧还有加载好')
}
// onprogress 事件在浏览器下载指定的视频/音频(audio/video)时触发。
audio.onprogress = function (){
    console.log('(audio/video)开始下载了')
}
// oncanplay 事件在用户可以开始播放视频/音频(audio/video)时触发。
audio.oncanplay = function (){
    console.log('我现在可以播放了')
}
// oncanplaythrough 事件在视频/音频(audio/video)可以正常播放且无需停顿和缓冲时触发。
audio.oncanplaythrough = function (){
    console.log('视频/音频(audio/video)已经全部加载完了')
}

以上的这些事件都会在播放视频/音频(audio/video)过程中触发,他们会按照onloadstart,ondurationchange,onloadedmetadata,onloadeddata,onprogress,oncanplay``oncanplaythrough

的顺序进行执行。

5.参考链接

  1. HTML DOM 教程 | 菜鸟教程 (runoob.com)

6.尾言

感觉还得补充。

Loading comments...