本項目的音頻文件是位於static/falling-star.mp3
,歌曲名爲:星球墜落Live 艾熱、李佳隆css
查看在線demo
: https://wangduanduan.github.i...項目地址
: https://github.com/wangduandu...cd element-aduio && yarn && yarn run dev
Vue單文件組件開發知識
Element UI基本用法
Audio原生API及Audio相關事件
音頻播放器的基本原理
音頻的播放暫停控制
音頻顯示時間
音頻進度條控制與跳轉
音頻音量控制
音頻播放速度控制
音頻靜音控制
音頻下載控制
個性化配置與排他性播放
一點點ES6語法
基本上不須要什麼準備,可是若是你能先看一下Aduio相關API和事件將會更好vue
沒有在線demo的教程都是耍流氓
webpack
➜ test vue init webpack element-audio A newer version of vue-cli is available. latest: 2.9.2 installed: 2.9.1 ? Project name element-audio ? Project description A Vue.js project ? Author wangdd <wangdd@xxxxxx.com> ? Vue build standalone ? Install vue-router? No ? Use ESLint to lint your code? No ? Set up unit tests No ? Setup e2e tests with Nightwatch? No ? Should we run `npm install` for you after the project has been created? (recommended) npm ➜ test cd element-audio ➜ element-audio npm run dev
瀏覽器打開 http://localhost:8080/
, 看到以下界面,說明項目初始化成功ios
圖片1
git
安裝ElementUI
yarn add element-ui // or npm i element-ui -S
src/main.js
中引入Element UI// 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 } })
src/components/VueAudio.vue
// filename: src/components/VueAudio.vue <template> <div> <audio src="http://devtest.qiniudn.com/secret base~.mp3" controls="controls"></audio> </div> </template> <script> export default { data () { return {} } } </script> <style> </style>
src/App.vue
, 並引入VueAudio.vue
組件// filename: src/App.vue <template> <div id="app"> <VueAudio /> </div> </template> <script> import VueAudio from './components/VueAudio' export default { name: 'app', components: { VueAudio }, data () { return {} } } </script> <style> </style>
打開:http://localhost:8080/,你應該能看到以下效果,說明引入成功,你能夠點擊播放按鈕看看,音頻是否可以播放圖2
github
咱們須要用一個按鈕去控制音頻的播放與暫停,這裏調用了audio的兩個api,以及兩個事件web
修改src/components/VueAudio.vue
vue-router
// filename: src/components/VueAudio.vue <template> <div> <!-- 此處的ref屬性,能夠很方便的在vue組件中經過 this.$refs.audio獲取該dom元素 --> <audio ref="audio" @pause="onPause" @play="onPlay" src="http://devtest.qiniudn.com/secret base~.mp3" controls="controls"></audio> <!-- 音頻播放控件 --> <div> <el-button type="text" @click="startPlayOrPause">{{audio.playing | transPlayPause}}</el-button> </div> </div> </template> <script> export default { data () { return { audio: { // 該字段是音頻是否處於播放狀態的屬性 playing: false } } }, methods: { // 控制音頻的播放與暫停 startPlayOrPause () { return this.audio.playing ? this.pause() : this.play() }, // 播放音頻 play () { this.$refs.audio.play() }, // 暫停音頻 pause () { this.$refs.audio.pause() }, // 當音頻播放 onPlay () { this.audio.playing = true }, // 當音頻暫停 onPause () { this.audio.playing = false } }, filters: { // 使用組件過濾器來動態改變按鈕的顯示 transPlayPause(value) { return value ? '暫停' : '播放' } } } </script> <style> </style>
圖3 音頻播放與暫停
vue-cli
音頻的時間顯示主要有兩部分,音頻的總時長和當前播放時間。能夠從兩個事件中獲取npm
loadedmetadata
:表明音頻的元數據已經被加載完成,能夠從中獲取音頻總時長timeupdate
: 當前播放位置做爲正常播放的一部分而改變,或者以特別有趣的方式,例如不連續地改變,能夠從該事件中獲取音頻的當前播放時間,該事件在播放過程當中會不斷被觸發
要點代碼
:整數格式化成時:分:秒
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' } }
要點代碼
: 兩個事件的處理
// 當timeupdate事件大概每秒一次,用來更新音頻流的當前播放時間 onTimeupdate(res) { console.log('timeupdate') console.log(res) this.audio.currentTime = res.target.currentTime }, // 當加載語音流元數據完成後,會觸發該事件的回調函數 // 語音元數據主要是語音的長度之類的數據 onLoadedmetadata(res) { console.log('loadedmetadata') console.log(res) this.audio.maxTime = parseInt(res.target.duration) }
完整代碼
<template> <div> <!-- 此處的ref屬性,能夠很方便的在vue組件中經過 this.$refs.audio獲取該dom元素 --> <audio ref="audio" @pause="onPause" @play="onPlay" @timeupdate="onTimeupdate" @loadedmetadata="onLoadedmetadata" src="http://devtest.qiniudn.com/secret base~.mp3" controls="controls"></audio> <!-- 音頻播放控件 --> <div> <el-button type="text" @click="startPlayOrPause">{{audio.playing | transPlayPause}}</el-button> <el-tag type="info">{{ audio.currentTime | formatSecond}}</el-tag> <el-tag type="info">{{ audio.maxTime | formatSecond}}</el-tag> </div> </div> </template> <script> // 將整數轉換成 時:分:秒的格式 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' } } export default { data () { return { audio: { // 該字段是音頻是否處於播放狀態的屬性 playing: false, // 音頻當前播放時長 currentTime: 0, // 音頻最大播放時長 maxTime: 0 } } }, methods: { // 控制音頻的播放與暫停 startPlayOrPause () { return this.audio.playing ? this.pause() : this.play() }, // 播放音頻 play () { this.$refs.audio.play() }, // 暫停音頻 pause () { this.$refs.audio.pause() }, // 當音頻播放 onPlay () { this.audio.playing = true }, // 當音頻暫停 onPause () { this.audio.playing = false }, // 當timeupdate事件大概每秒一次,用來更新音頻流的當前播放時間 onTimeupdate(res) { console.log('timeupdate') console.log(res) this.audio.currentTime = res.target.currentTime }, // 當加載語音流元數據完成後,會觸發該事件的回調函數 // 語音元數據主要是語音的長度之類的數據 onLoadedmetadata(res) { console.log('loadedmetadata') console.log(res) this.audio.maxTime = parseInt(res.target.duration) } }, filters: { // 使用組件過濾器來動態改變按鈕的顯示 transPlayPause(value) { return value ? '暫停' : '播放' }, // 將整數轉化成時分秒 formatSecond(second = 0) { return realFormatSecond(second) } } } </script> <style> </style>
打開瀏覽器能夠看到,當音頻播放時,當前時間也在改變。圖4
進度條主要有兩個控制,改變進度的原理是:改變audio.currentTime
屬性值
// 進度條ui <el-slider v-model="sliderTime" :format-tooltip="formatProcessToolTip" @change="changeCurrentTime" class="slider"></el-slider> // 拖動進度條,改變當前時間,index是進度條改變時的回調函數的參數0-100之間,須要換算成實際時間 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) }, // 進度條格式化toolTip formatProcessToolTip(index = 0) { index = parseInt(this.audio.maxTime / 100 * index) return '進度條: ' + realFormatSecond(index) },
音頻的音量控制和進度控制差很少,也是經過拖動滑動條,去修改aduio.volume
屬性值,此處再也不囉嗦
音頻的音量控制和進度控制差很少,也是點擊按鈕,去修改aduio.playbackRate
屬性值,該屬性表明音量的大小,取值範圍是0 - 1,用滑動條的時候,也是須要換算一下值,此處再也不囉嗦
靜音的控制是點擊按鈕,去修改aduio.muted
屬性,該屬性有兩個值: true(靜音),false(不靜音)。 注意,靜音的時候,音頻的進度條仍是會繼續往前走的。
音頻下載是一個a連接,記得加上download
屬性,否則瀏覽器會在新標籤打開音頻,而不是下載音頻
<a :href="url" v-show="!controlList.noDownload" target="_blank" class="download" download>下載</a>
音頻的個性化配置有不少,你們能夠本身擴展,經過父組件傳遞響應的值,能夠作到個性化設置。
controlList: { // 不顯示下載 noDownload: false, // 不顯示靜音 noMuted: false, // 不顯示音量條 noVolume: false, // 不顯示進度條 noProcess: false, // 只能播放一個 onlyOnePlaying: false, // 不要快進按鈕 noSpeed: false } setControlList () { let controlList = this.theControlList.split(' ') controlList.forEach((item) => { if(this.controlList[item] !== undefined){ this.controlList[item] = true } }) },
例如父組件這樣
<template> <div id="app"> <div v-for="item in audios" :key="item.url"> <VueAudio :theUrl="item.url" :theControlList="item.controlList"/> </div> </div> </template> <script> import VueAudio from './components/VueAudio' export default { name: 'app', components: { VueAudio }, data () { return { audios: [ { url: 'http://devtest.qiniudn.com/secret base~.mp3', controlList: 'onlyOnePlaying' }, { url: 'http://devtest.qiniudn.com/回レ!雪月花.mp3', controlList: 'noDownload noMuted onlyOnePlaying' },{ url: 'http://devtest.qiniudn.com/あっちゅ~ま青春!.mp3', controlList: 'noDownload noVolume noMuted onlyOnePlaying' },{ url: 'http://devtest.qiniudn.com/Preparation.mp3', controlList: 'noDownload noSpeed onlyOnePlaying' } ] } } } </script> <style> </style>
大多數時候,咱們但願頁面上播放一個音頻時,其餘音頻能夠暫停。[...audios]
能夠把一個類數組轉化成數組,這個是我經常使用的。
onPlay (res) { console.log(res) this.audio.playing = true this.audio.loading = false if(!this.controlList.onlyOnePlaying){ return } let target = res.target let audios = document.getElementsByTagName('audio'); // 若是設置了排他性,當前音頻播放是,其餘音頻都要暫停 [...audios].forEach((item) => { if(item !== target){ item.pause() } }) },