vue-audio
Version:
vue.js audio files player
163 lines (154 loc) • 4.4 kB
JavaScript
export const baseVolumeValue = 7.5
let audio, uuid
export const prefixCls = 'vue-sound'
export const generateUUID = () => {
return 'xxxxxxxx-xxxx-4xxx'.replace(/[xy]/g, function (c) {
let v, r
r = Math.random() * 16 | 0; v = c === 'x' ? r : (r & 0x3 | 0x8)
return v.toString(16)
})
}
export const convertTimeHHMMSS = (val) => {
let hhmmss = new Date(val * 1000).toISOString().substr(11, 8)
return (hhmmss.indexOf('00:') === 0) ? hhmmss.substr(3) : hhmmss
}
export default {
name: 'vue-audio',
props: {
file: {
type: String,
default: null
},
autoPlay: {
type: Boolean,
default: false
},
loop: {
type: Boolean,
default: false
}
},
computed: {
duration: function () {
return this.audio ? convertTimeHHMMSS(this.totalDuration) : ''
},
playerId: function () {
return 'player-' + this.uuid
},
classes: function () {
return prefixCls
}
},
data () {
return {
isMuted: false,
loaded: false,
playing: false,
paused: true,
progressStyle: '',
currentTime: '00:00',
uuid: '0',
innerLoop: undefined,
audio: undefined,
totalDuration: 0,
hideVolumeSlider: false,
volumeValue: baseVolumeValue
}
},
methods: {
setPosition: function name (e) {
let tag = e.target
if (this.paused) return
if (e.target.tagName === 'SPAN') {
return
}
const pos = tag.getBoundingClientRect()
const seekPos = (e.clientX - pos.left) / pos.width
this.audio.currentTime = parseInt(this.audio.duration * seekPos)
},
updateVolume: function () {
this.hideVolumeSlider = false
this.audio.volume = this.volumeValue / 100
if (this.volumeValue / 100 > 0) {
this.isMuted = this.audio.muted = false
}
if (this.volumeValue / 100 === 0) {
this.isMuted = this.audio.muted = true
}
},
toggleVolume: function () {
this.hideVolumeSlider = true
},
stop: function () {
this.playing = false
this.paused = true
this.audio.pause()
this.audio.currentTime = 0
},
play: function () {
if (this.playing && !this.paused) return
this.paused = false
this.audio.play()
this.playing = true
},
pause: function () {
this.paused = !this.paused;
(this.paused) ? this.audio.pause() : this.audio.play()
},
changeLoop: function () {
this.innerLoop = !this.innerLoop
},
download: function () {
this.stop()
window.open(this.file, 'download')
},
mute: function () {
this.isMuted = !this.isMuted
this.audio.muted = this.isMuted
this.volumeValue = this.isMuted ? 0 : 75
},
_handleLoaded: function () {
if (this.audio.readyState >= 2) {
if (this.autoPlay) this.play()
this.loaded = true
this.totalDuration = parseInt(this.audio.duration)
} else {
throw new Error('Failed to load sound file')
}
},
_handlePlayingUI: function (e) {
let currTime = parseInt(this.audio.currentTime)
let percentage = parseInt((currTime / this.totalDuration) * 100)
this.progressStyle = `width:${percentage}%;`
this.currentTime = convertTimeHHMMSS(currTime)
},
_handlePlayPause: function (e) {
if (e.type === 'pause' && this.playing === false) {
this.progressStyle = `width:0%;`
this.currentTime = '00:00'
this.paused = true
}
},
init: function () {
this.audio.addEventListener('timeupdate', this._handlePlayingUI)
this.audio.addEventListener('loadeddata', this._handleLoaded)
this.audio.addEventListener('pause', this._handlePlayPause)
this.audio.addEventListener('play', this._handlePlayPause)
},
getAudio: function () {
return this.$el.querySelectorAll('audio')[0]
}
},
mounted: function () {
this.uuid = generateUUID()
this.audio = this.getAudio()
this.innerLoop = this.loop
this.init()
},
beforeDestroy: function () {
this.audio.removeEventListener('timeupdate', this._handlePlayingUI)
this.audio.removeEventListener('loadeddata', this._handleLoaded)
this.audio.removeEventListener('pause', this._handlePlayPause)
this.audio.removeEventListener('play', this._handlePlayPause)
}
}