Just to make fun of it: the company has changed a lot recently. The new leader has passed all the previous projects and has to do it again. B: well… (Many, many words omitted here)
Today I want to share vue+Element rewrite audio player style, because the default player style is very ugly, UI colleagues must follow the UI.
Segmentfault.com/a/119000001…
Let’s look at the directory structure first
You have to install it in advance
yarn add element-ui // or npm i element-ui -S
Copy the code
Import and use in main.js file
// filename: src/main.js
import Vue from 'vue'
import ElementUI from 'element-ui'
import App from './App'
import 'element-ui/lib/theme-chalk/index.css'
Vue.config.productionTip = false
Vue.use(ElementUI)
/* eslint-disable no-new */
new Vue({
el: '#app',
template: '<App/>',
components: { App }
})
Copy the code
Now let’s look at the audiocom.vue file
<template>
<div>
<audio src="http://devtest.qiniudn.com/secret base~.mp3" controls="controls"></audio>
</div>
</template>
<script>
export default {
data () {
return {}
}
}
</script>
<style>
</style>
Copy the code
We need a button to play and pause the audio, and here we call two apis of Audio, and two events.
- audio.play()
- audio.pause()
- Play events
- Pause event
Audio playback pause control
Methods: {// Control audio playback and pausestartPlayOrPause () {
returnthis.audio.playing ? This.pause () : this.play()}, // Play the audioplay () {
this.$refs.audio. Play ()}, // Pause the audiopause () {
this.$refs.audio. Pause ()}, // When the audio is playingonPlay () {
this.audio.playing = true}, // When audio pausesonPause () {
this.audio.playing = false}}Copy the code
Audio display time
The audio time display has two main parts, the total duration of the audio and the current playing time. This can be obtained from two events
- Loadedmetadata: The metadata representing the audio has been loaded to obtain the total duration of the audio
- Timeupdate: The current playback position changes as part of normal playback, or in a particularly interesting way, such as discontinuously, to get the current playback time of the audio from this event, which is constantly triggered during playback
Key code: integer formatted into hours: minutes: seconds
function realFormatSecond(second) {
var secondType = typeof second
if (secondType === 'number' || secondType === 'string') {
second = parseInt(second)
var hours = Math.floor(second / 3600)
second = second - hours * 3600
var mimute = Math.floor(second / 60)
second = second - mimute * 60
return hours + ':' + ('0' + mimute).slice(-2) + ':' + ('0' + second).slice(-2)
} else {
return '0:00:00'}}Copy the code
Key code: Handling of two events
OnTimeupdate (res) {console.log('timeupdate') console.log(res) this.audio. CurrentTime = res.target.currentTime}, // When loading voice stream metadata is complete, OnLoadedmetadata (res) {console.log('loadedmetadata')
console.log(res)
this.audio.maxTime = parseInt(res.target.duration)
}
Copy the code
The complete code
<template>
<div>
<audio
ref="audio"
:src="url"
@pause="onPause"
@play="onPlay"
@timeupdate="onTimeupdate"
@loadedmetadata="onLoadedmetadata"
controls="controls"></audio> <! Audio playback control --> <div class="audio-com-box">
<div class="audio-icont-div" @click="startPlayOrPause">
<span class="iconfont icon-shengyin"></span>
</div>
<div class="progress-box">
<span class="current-time">{{ audio.currentTime | formatSecond}}</span>
<span class="total-time"> {{audio. MaxTime | formatSecond}} < / span > < / div > < / div > < / div > < / template > < script > / / converting integers: points: second formatfunction realFormatSecond(second) {
var secondType = typeof second
if (secondType === 'number' || secondType === 'string') {
second = parseInt(second)
var hours = Math.floor(second / 3600)
second = second - hours * 3600
var mimute = Math.floor(second / 60)
second = second - mimute * 60
return hours + ':' + ('0' + mimute).slice(-2) + ':' + ('0' + second).slice(-2)
} else {
return '0:00:00'}}export default {
data () {
return{audio: {// This field is the playing property of whether the audio is playing:false, currentTime: 0, maxTime: 0}}}, methods: {// Control audio playback and pausestartPlayOrPause () {
returnthis.audio.playing ? This.pause () : this.play()}, // Play the audioplay () {
this.$refs.audio. Play ()}, // Pause the audiopause () {
this.$refs.audio. Pause ()}, // When the audio is playingonPlay () {
this.audio.playing = true}, // When audio pausesonPause () {
this.audio.playing = false}, // The current playback time of the audio stream is updated when a timeUpdate event occurs approximately once per second onTimeupdate(res) {console.log('timeupdate') console.log(res) this.audio. CurrentTime = res.target.currentTime}, // When loading voice stream metadata is complete, OnLoadedmetadata (res) {console.log('loadedmetadata') console.log(res) this.audio.maxTime = parseInt(res.target.duration) } }, filters: FormatSecond (second = 0) {return realFormatSecond(second)
}
}
}
</script>
<style>
</style>
Copy the code
Audio progress bar control
The progress bar has two main controls. The principle for changing progress is to change the value of the audio. CurrentTime property
-
When the current time changes, the progress bar changes accordingly
-
Drag the progress bar to change the current time of audio
<el-slider
class="slider"
v-model="sliderTime"
:show-tooltip="false"
@change="changeCurrentTime"></el-slider>
Copy the code
// Drag the progress bar to change the current time. Index is the callback function parameter when the progress bar changes. It needs to be converted to the actual time changeCurrentTime(index) {this.$refs.audio. CurrentTime = parseInt(index / 100 * this.audio. MaxTime)}, OnTimeupdate (res) {console.log('timeupdate')
console.log(res)
this.audio.currentTime = res.target.currentTime
this.sliderTime = parseInt(this.audio.currentTime / this.audio.maxTime * 100)
}
Copy the code
Finally fill in the full code
<template>
<div>
<audio
ref="audio"
:src="url"
@pause="onPause"
@play="onPlay"
@timeupdate="onTimeupdate"
@loadedmetadata="onLoadedmetadata"
controls="controls"></audio> <! Audio playback control --> <div class="audio-com-box">
<div class="audio-icont-div" @click="startPlayOrPause">
<span class="iconfont icon-shengyin"></span>
</div>
<div class="progress-box">
<el-slider
class="slider"
v-model="sliderTime"
:show-tooltip="false"
@change="changeCurrentTime"></el-slider>
<span class="current-time">{{ audio.currentTime | formatSecond}}</span>
<span class="total-time">{{ audio.maxTime | formatSecond}}</span>
</div>
</div>
</div>
</template>
Copy the code
<script> // Convert the integer to the hour: minute: second formatfunction realFormatSecond(second) {
var secondType = typeof second
if (secondType === 'number' || secondType === 'string') {
second = parseInt(second)
var hours = Math.floor(second / 3600)
second = second - hours * 3600
var mimute = Math.floor(second / 60)
second = second - mimute * 60
return hours + ':' + ('0' + mimute).slice(-2) + ':' + ('0' + second).slice(-2)
} else {
return '0:00:00'}}export default {
props: {},
components: {},
data() {
return {
url: 'http://final.tfedu.net/nor/3001234567890/b90e3bc71d79520d72612f00cc80832e/reading/2019/10001/7/2019071915105700931-62.m p3',
audio: {
playing: falseCurrentTime: 0,// maxTime: 0,// Maximum playback duration}, sliderTime: []}}, watch: {}, methods: {// Drag the progress bar to change the current time, index is the callback function when the progress bar changes parameters between 0 and 100, need to convert the actual time changeCurrentTime(index) {this.$refs.audio. CurrentTime = parseInt(index / 100 * this.audio. MaxTime)}, OnTimeupdate (res) {this.audio. CurrentTime = res.target.currentTime; this.sliderTime = parseInt(this.audio.currentTime / this.audio.maxTime * 100); }, // Control audio playback and pausestartPlayOrPause() {
returnthis.audio.playing ? This.pause () : this.play()}, // Play the audioplay() {
this.$refs.audio.play(); }, // Pause the audiopause() {
this.$refs.audio.pause(); }, // When the audio playsonPlay() {
this.audio.playing = true}, // When audio pausesonPause() {
this.audio.playing = false}, // When the timeUpdate event is about once per second, OnTimeupdate (res) {this.audio. CurrentTime = res.target.currentTime this.sliderTime = ParseInt (this.audio. CurrentTime/this.audio. MaxTime * 100)}, OnLoadedmetadata (res) {this.audio. MaxTime = parseInt(res.target.duration)}}, Filters: {// Convert integers to time seconds formatSecond(second = 0) {return realFormatSecond(second)
}
},
created() {},mounted() {
}
}
</script>
Copy the code
<style lang="less">
audio {
display: none;
}
.audio-com-box {
border: 1px solid #E5E5E5;
background-color: #FAFAFA;border-radius: 10px; padding: 15px 25px; display: flex; align-items: center; /* audio icon */ >. Audio-icont-div {width: 40px; height: 40px; border: 2px solid#17CE88;
border-radius: 50%;
text-align: center;
line-height: 40px;
cursor: pointer;
> .icon-shengyin {
color: #17CE88;font-size: 20px; }} /* progress bar */ >. Progress-box {flex: 1; margin-left: 15px; position: relative; > .slider { > .el-slider__runway { height: 3px; > .el-slider__bar { height: 3px; background-color:#17CE88;
}
.el-slider__button {
width: 10px;
height: 10px;
border: 2px solid #17CE88
}
}
}
> .current-time, > .total-time {
position: absolute;
bottom: -15px;
color: #AAAAAA;
}
> .current-time {
left: 0;
}
> .total-time {
right: 0;
}
}
}
</style>
Copy the code
Segmentfault.com/a/119000001…
Or check out vue-aPlayer
(Any problems or deficiencies are welcome to correct)