229 lines
5.2 KiB
JavaScript
Raw Normal View History

/* eslint-disable */
import HTMLAudioElement from './HTMLAudioElement'
let SN_SEED = 1
const _innerAudioContextMap = {}
class AudioMock {
play() {}
pause() {}
stop() {}
seek() {}
destroy() {}
onCanplay() {}
offCanplay() {}
onEnded() {}
offEnded() {}
onError() {}
offError() {}
onPause() {}
offPause() {}
onPlay() {}
offPlay() {}
onSeeked() {}
offSeeked() {}
onSeeking() {}
offSeeking() {}
onStop() {}
offStop() {}
onTimeUpdate() {}
offTimeUpdate() {}
offWaiting() {}
onWaitin() {}
}
export default class Audio extends HTMLAudioElement {
constructor(url) {
super()
this._$sn = SN_SEED++;
this.readyState = Audio.HAVE_NOTHING
const innerAudioContext = swan.createInnerAudioContext
? swan.createInnerAudioContext()
: new AudioMock();
_innerAudioContextMap[this._$sn] = innerAudioContext
this._canplayEvents = [
'load',
'loadend',
'canplay',
'canplaythrough',
'loadedmetadata'
]
innerAudioContext.onCanplay(() => {
this._loaded = true
this.readyState = Audio.HAVE_CURRENT_DATA
this._canplayEvents.forEach((type) => {
this.dispatchEvent({ type: type })
})
})
innerAudioContext.onPlay(() => {
this._paused = _innerAudioContextMap[this._$sn].paused
this.dispatchEvent({ type: 'play' })
})
innerAudioContext.onPause(() => {
this._paused = _innerAudioContextMap[this._$sn].paused
this.dispatchEvent({ type: 'pause' })
})
innerAudioContext.onEnded(() => {
this._paused = _innerAudioContextMap[this._$sn].paused
if (_innerAudioContextMap[this._$sn].loop === false) {
this.dispatchEvent({ type: 'ended' })
}
this.readyState = Audio.HAVE_ENOUGH_DATA
})
innerAudioContext.onError(() => {
this._paused = _innerAudioContextMap[this._$sn].paused
this.dispatchEvent({ type: 'error' })
})
if (url) {
this.src = url
} else {
this._src = ''
}
this._loop = innerAudioContext.loop
this._autoplay = innerAudioContext.autoplay
this._paused = innerAudioContext.paused
this._volume = innerAudioContext.volume
this._muted = false
}
addEventListener(type, listener, options = {}) {
type = String(type).toLowerCase()
super.addEventListener(type, listener, options)
if (this._loaded && this._canplayEvents.indexOf(type) !== -1) {
this.dispatchEvent({ type: type })
}
}
load() {
// console.warn('HTMLAudioElement.load() is not implemented.')
// weixin doesn't need call load() manually
}
play() {
_innerAudioContextMap[this._$sn].play()
}
resume() {
_innerAudioContextMap[this._$sn].resume()
}
pause() {
_innerAudioContextMap[this._$sn].pause()
}
destroy() {
_innerAudioContextMap[this._$sn].destroy()
}
canPlayType(mediaType = '') {
if (typeof mediaType !== 'string') {
return ''
}
if (mediaType.indexOf('audio/mpeg') > -1 || mediaType.indexOf('audio/mp4')) {
return 'probably'
}
return ''
}
get currentTime() {
return _innerAudioContextMap[this._$sn].currentTime
}
set currentTime(value) {
_innerAudioContextMap[this._$sn].seek(value)
}
get duration() {
return _innerAudioContextMap[this._$sn].duration
}
get src() {
return this._src
}
set src(value) {
this._src = value
this._loaded = false
this.readyState = Audio.HAVE_NOTHING
const innerAudioContext = _innerAudioContextMap[this._$sn]
innerAudioContext.src = value
}
get loop() {
return this._loop
}
set loop(value) {
this._loop = value
_innerAudioContextMap[this._$sn].loop = value
}
get autoplay() {
return this._autoplay
}
set autoplay(value) {
this._autoplay = value
_innerAudioContextMap[this._$sn].autoplay = value
}
get paused() {
return this._paused
}
get volume() {
return this._volume
}
set volume(value) {
this._volume = value
if (!this._muted) {
_innerAudioContextMap[this._$sn].volume = value
}
}
get muted() {
return this._muted
}
set muted(value) {
this._muted = value
if (value) {
_innerAudioContextMap[this._$sn].volume = 0
} else {
_innerAudioContextMap[this._$sn].volume = this._volume
}
}
cloneNode() {
const newAudio = new Audio()
newAudio.loop = this.loop
newAudio.autoplay = this.autoplay
newAudio.src = this.src
return newAudio
}
}
Audio.HAVE_NOTHING = 0
Audio.HAVE_METADATA = 1
Audio.HAVE_CURRENT_DATA = 2
Audio.HAVE_FUTURE_DATA = 3
Audio.HAVE_ENOUGH_DATA = 4