1.主要针对ie浏览器下播放音频,这个时候需要用到audio来创建一个播放器。并且无法使用二进制流边加载边播放。所以用到了播放地址来创建播放器。
2.简单的封装一下播放器。
// Audio的状态
export const AudioState = {
suspended: 'suspended',
running: 'running',
closed: 'closed',
loading: 'loading',
error: 'error'
}
export class Audio {
constructor (audioParam) {
this._url = audioParam.url // 地址
this._theoryDuration = audioParam.duration // 全部时间
this._setCurrentTime = audioParam.setCurrentTime // 开始时间
this._autoPlay = audioParam.autoPlay // 是否自动播放
}
_url
_setCurrentTime
// 最大分区索引
_splitMax
// 分区索引
_splitIndex = 0
_startLoading = false
_cacheBuffer
_buffers = []
_bufferDuration = []
// window.Audio实例
_nativeAudio
// 开始时间
_startTime = 0
// 理论总时间
_theoryDuration
// 是否自动播放
_autoPlay = true
// 是否加载完成,用于IE
_loadedIE = false
// AudioError对象
_error
// 监听播放时间
_listeners = []
// 监听播放状态变化
_stateListeners = []
_buffListeners = []
_timeBuffListeners = []
_buffProgress = [0, 0]
_state
_progress = 0
/**
* public method
* 开始播放
* @returns {Promise<void>}
*/
start = async () => {
try {
this.close()
this._startLoading = true
this.setAudioState(AudioState.loading)
this._createAudioIE().then(() => {
}).catch(e => console.log('audio', e))
} catch (e) {
console.log('start Exception', e)
}
}
// 创建IE播放器
_createAudioIE = async () => {
const self = this
this._nativeAudio = new window.Audio()
this._nativeAudio.src = this._url
this._startLoading = false
this._nativeAudio.addEventListener('canplay', function () {
self._buffProgress = [0, 100]
self._notifyListeners(self._buffListeners)
}, false)
this._nativeAudio.addEventListener('timeupdate', function () {
self.setAudioCurrentTime()
})
await this.timeout(1000)
if (this._autoPlay) {
this.setAudioState(AudioState.running)
this._nativeAudio.play()
this._nativeAudio.currentTime = this._setCurrentTime
} else {
this._nativeAudio.currentTime = this._setCurrentTime
this.setAudioCurrentTime()
this.setAudioState(AudioState.suspended)
}
}
setAudioProgress (val) {
this._progress = val
if (val === 100) this.setAudioState(AudioState.closed)
}
setAudioCurrentTime () {
if (this._nativeAudio !== null && this._nativeAudio.paused) {
this.setAudioState(AudioState.suspended)
}
this.setAudioProgress(this.certainTime / this.duration * 100)
}
/**
* public method
* 播放器状态设置
*/
setAudioState (val) {
let playStatus = -1 // -1未定义audio,0暂停,1播放,2缓冲, 3播放完毕
switch (val) {
case AudioState.suspended:
playStatus = 0
break
case AudioState.running:
playStatus = 1
break
case AudioState.loading:
playStatus = 2
break
case AudioState.closed:
playStatus = 3
break
case AudioState.error:
playStatus = 4
break
default:
playStatus = -1
break
}
this._state = playStatus
}
// 延时
async timeout (time) {
return new Promise((resolve, reject) => {
setTimeout(() => resolve(), time)
})
}
}
3.播放器的一些简单操作
/**
* public method
* 播放器逻辑方法
* @returns {Promise<void>}
*/
play = () => {
this.setAudioState(AudioState.running)
this._nativeAudio.play()
}
/**
* public method
* 继续播放
*/
resume () {
this.setAudioState(AudioState.running)
if (this._nativeAudio) {
this._nativeAudio.play()
}
}
/**
* public method
* 暂停播放
*/
pause () {
this.setAudioState(AudioState.suspended)
if (this._nativeAudio) {
this._nativeAudio.pause()
}
}
/**
* public method
* 缓冲
*/
onload () {
this.setAudioState(AudioState.loading)
if (this._nativeAudio) {
this._nativeAudio.pause()
}
}
/**
* public method
* 跳到某个时间进行播放
* @param time
* @returns {Promise<void>}
*/
async seek (time, autoPlay = true) {
this.setAudioState(AudioState.loading)
this._startTime = time
this._nativeAudio.currentTime = time
this.setAudioCurrentTime()
if (autoPlay) this.resume()
else this.pause()
}
// 设置音量
set volume (value) {
if (this._nativeAudio) { this._nativeAudio.volume = value }
}
// 获取准确的时间
get certainTime () {
if (!this._nativeAudio || this.loading) return this._startTime
return this._nativeAudio.currentTime
}
// 获取总时长
get duration () {
if (this._nativeAudio && this._nativeAudio.duration !== Infinity && !isNaN(this._nativeAudio.duration)) { return this._nativeAudio.duration }
return this._theoryDuration
}
/**
* public method
* 分片播放逻辑方法
* @returns {Promise<void>}
*/
// 分片是否都加载完成
get loaded () {
return this._buffers.length - 1 === this._splitMax || this._loadedIE
}
/**
* public method
* 关闭,可以多次执行
*/
close () {
this.setAudioState(AudioState.closed)
if (this._nativeAudio) {
this._nativeAudio.pause()
this._nativeAudio = null
}
}
一个简单的Audio播放器的封装,希望能帮助到大家,如有优化或者问题可以私聊我下。谢谢。