It's almost time to go back to school 😭😭😭.
1. Introduction#
When I was implementing a mobile music player for my blog, I wanted to achieve the desired style without using the audio
API. So what should we pay attention to when using them?
2. How to use audio#
To understand how it is used, here are two basic ways:
-
Directly use the
audio
tag. Here I am usingvue
to dynamically switch the playing music.<audio :src="currentMusic.url" controls @ended="musicEnd" ref="myaudio" style="display:none;"> Your browser does not support audio </audio>
The above code switches the audio playback by modifying the
src
. However, there are a few things to note:- When switching audio in this way, there is no need to call the
this.$refs.myaudio.load()
method. It will automatically load the audio. This is because in Vue, if a certain property is changed, it will cause the browser to reflow and automatically fetch the audio data. - There is only one audio at a time, which may cause compatibility issues with some browsers.
- If you directly use
this.$refs.myaudio.play()
, it may start playing before the audio is fully loaded, which is obviously not reasonable.
- When switching audio in this way, there is no need to call the
-
Using the
source
method.<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"> Your browser does not support the audio element. </audio>
Using this method, you can add multiple
source
tags to achieve compatibility with different browsers. The rest is similar to the first method.
3. When to call the play method#
If you call the play
method directly after switching the src
, it is likely to cause problems. For example, this is a method for switching to the next song:
next(){
this.currentMusic = this.audio[this.current+1 === this.allMusic?this.current = 0:++this.current]
this.$refs.myaudio.play()
}
},
currentMusic
represents the current music, current
is the index value of the current music, allMusic
is the total number of music, and audio
is the list of all music. This method will be called when clicking on the next song. Because we are using Vue, every time the src
is switched, the audio
will be reloaded. However, if we click too quickly or the internet speed is slow, an error may occur.
DOMException: The play() request was interrupted by a new load request.
As the error suggests, the resource is not ready yet, but you start playing it. This is obviously incorrect behavior. So how do we solve this problem? We can quickly think of a solution: if we know that the resource is ready, we can call the play method to start playing. As you can see, HTML5
provides these methods.
4. How to determine the timing of using the play method#
To determine if the data of the audio
has been loaded, we can use the oncanplay
event, which is triggered during the loading process of the video/audio (audio/video) to notify you that the video/audio is ready to play. Here is how to use it:
this.currentMusic = this.audio[this.current - 1 === -1?this.current =this.allMusic - 1:--this.current]
this.$refs.myaudio.oncanplay =()=>{
this.$refs.myaudio.play();
}
After switching the audio, the audio
will automatically load the audio. When it is loaded, the oncanplay
event will be triggered to perform the desired operation.
In addition to this event, there are also onloadstart
, ondurationchange
, onloadedmetadata
, onloadeddata
, onprogress
, oncanplaythrough
events.
// The onloadstart event is triggered when the browser starts looking for the specified video/audio (audio/video).
audio.onloadstart = function (){
console.log('Start looking for the specified video/audio')
}
// The ondurationchange event is triggered when the duration of the video/audio (audio/video) changes.
// Note: When the video/audio (audio/video) is already loaded, the duration changes from "NaN" to the actual duration.
audio.ondurationchange = function (){
console.log('The video/audio (audio/video) has changed')
}
// The onloadedmetadata event is triggered after the metadata of the specified video/audio (audio/video) is loaded.
// Note: The metadata of the video/audio (audio/video) includes: duration, size (for video), text tracks.
audio.onloadedmetadata = function (){
console.log('The metadata of the video/audio (audio/video) has been loaded')
}
// The onloadeddata event is triggered when the current frame's data is loaded and there is not enough data to play the next frame of the video/audio (audio/video).
audio.onloadeddata = function (){
console.log('The current frame\'s data has been loaded, but the next frame is not yet loaded')
}
// The onprogress event is triggered when the browser is downloading the specified video/audio (audio/video).
audio.onprogress = function (){
console.log('The audio/video has started downloading')
}
// The oncanplay event is triggered when the user can start playing the video/audio (audio/video).
audio.oncanplay = function (){
console.log('I can play now')
}
// The oncanplaythrough event is triggered when the video/audio (audio/video) can be played smoothly without pausing or buffering.
audio.oncanplaythrough = function (){
console.log('The video/audio (audio/video) has been fully loaded')
}
These events will be triggered during the playback of the video/audio (audio/video), and they will be executed in the order of onloadstart
, ondurationchange
, onloadedmetadata
, onloadeddata
, onprogress
, oncanplay
, oncanplaythrough
.