基于 vue-element 组件实现音乐播放器功能

效果:

代码:

<template>
  <div id='playMusic'>
    <audio ref='audio' :src='src'
     @pause="onPause"
     @play='onplay'
     @timeupdate="onTimeupdate"
     @loadedmetadata="onLoadedmetadata"></audio>

    <el-button type='text' @click='startPlayOrPause'>{{audio.playing | transPlayPause}}</el-button>

    <!-- 进度条 -->
    <el-slider v-model="sliderTime" :format-tooltip="formatProcessToolTip" @change="changeCurrentTime" class="slider"></el-slider>

    <span>{{audio.currentTime | formartSecond}} / </span>

    <span>{{audio.maxTime | formartSecond}}</span>

  </div>
</template>

js:

<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 {
  name: 'playMusic',
  props: {
    src: {
      type: String,
      default: ''
    }
  },
  methods: {
    /* 进度条格式化toolTip */
    formatProcessToolTip (index = 0) {
      index = parseInt(this.audio.maxTime / 100 * index)
      return '时长:' + realFormatSecond(index)
    },
    /* 拖动进度条,改变当前时间 index是进度条改变时的回调函数的参数 值为0~100之间,需要换算成实际时间 */
    changeCurrentTime (index) {
      this.$refs.audio.currentTime = parseInt(index / 100 * this.audio.maxTime)
    },
    /* 音频加载完成后的回调函数 */
    onLoadedmetadata (res) {
      console.log(111)
      this.audio.maxTime = parseInt(res.target.duration)
    },
    /* 每秒触发一次 用来更新当前播放时间 */
    onTimeupdate (res) {
      this.audio.currentTime = res.target.currentTime
      /* 当音频播放时 进度条也要随之改变 */
      this.sliderTime = parseInt(this.audio.currentTime / this.audio.maxTime * 100)
    },
    /* 控制音频播放、暂停 */
    startPlayOrPause () {
      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
    }
  },
  data () {
    return {
      sliderTime: 0,
      audio: {
        maxTime: 0, /* 音频最大播放时长 */
        currentTime: 0, /* 当前播放时长 */
        playing: false /* 音频当前处于播放/暂停状态 */
      }
    }
  },
  filters: {
    /* 使用vue过滤器动态改变按钮的显示 */
    transPlayPause (value) {
      return value ? '暂停' : '播放'
    },
    /* 整数转换时分秒 */
    formartSecond (second = 0) {
      return realFormatSecond(second)
    }
  }
}
</script>

less:

<style lang="less">
#playMusic {
  display: flex;
  align-items: center;
  .el-button {
    margin-right: 15px;
  }
  .slider {
    width: 150px;
    margin-right: 15px;
  }
  > span:nth-of-type(2) {
    margin-left: 5px;
  }
}
</style>

参考: https://github.com/wangduanduan/element-audio

另一个类似功能实现:

效果:

代码:

<template>
  <div>
  <el-row>
   <el-col :span="4">
    <el-popover
    placement="top-start"
    trigger="hover">
     <div style="text-align: center">
      <el-progress 
      color="#67C23A"
      type="circle"
      :percentage="music.volume"></el-progress><br>
      <el-button 
      @click="changeVolume(-10)"
      icon="el-icon-minus"
      circle></el-button>
      <el-button 
      @click="changeVolume(10)"
      icon="el-icon-plus"
      circle></el-button>
     </div>
     <el-button 
     @click="play"
     id="play"
     slot="reference"
     :icon="music.isPlay?'el-icon-refresh':'el-icon-caret-right'"
     circle></el-button>
    </el-popover>
   </el-col>
   <el-col :span="14" style="padding-left: 20px">
    <el-slider
    @change="changeTime"
    :format-tooltip="formatTime"
    :max="music.maxTime"
    v-model="music.currentTime"
    style=" 100%;"></el-slider>
   </el-col>
   <el-col :span="6" style="padding: 9px 0px 0px 10px;color:#909399;font-size: 13px">
    {{formatTime(music.currentTime)}}/{{formatTime(music.maxTime)}}
   </el-col>
  </el-row>
  <audio ref="music" loop autoplay> 
   <source src="http://sc1.111ttt.cn:8282/2018/1/03m/13/396131232171.m4a?tflag=1519095601&pin=6cd414115fdb9a950d827487b16b5f97#.mp3" type="audio/mpeg">
  </audio>
 </div>
</template>

js:

<script>
 export default{
  data(){
   return {
    music:{
     isPlay:false,
     currentTime:0,
     maxTime:0,
     volume:100
    }
   }
  },
  mounted(){
   this.$nextTick(()=>{
    setInterval(this.listenMusic,1000)
   })
  },
  methods:{
   listenMusic(){
    if(!this.$refs.music){
     return
    }
    if(this.$refs.music.readyState){
     this.music.maxTime = this.$refs.music.duration
    }
    this.music.isPlay=!this.$refs.music.paused
    this.music.currentTime = this.$refs.music.currentTime
   },
   play(){
    if(this.$refs.music.paused){
     this.$refs.music.play()
    }else{
     this.$refs.music.pause()
    }
    this.music.isPlay=!this.$refs.music.paused
    this.$nextTick(()=>{
     document.getElementById('play').blur()
    })
   },
   changeTime(time){
    this.$refs.music.currentTime = time
   },
   changeVolume(v){
    this.music.volume += v 
    if(this.music.volume>100){
     this.music.volume = 100
    }
    if(this.music.volume<0){
     this.music.volume = 0
    }
    this.$refs.music.volume = this.music.volume/100
   },
   formatTime(time){
    let it = parseInt(time)
    let m = parseInt(it/60)
    let s = parseInt(it%60)
    return (m<10?"0":"")+parseInt(it/60)+":"+(s<10?"0":"")+parseInt(it%60)
   }
  } 
 }
</script>

更详细的实现可以看 https://github.com/GitHub-Laziji/vblog

原文地址:https://www.cnblogs.com/joe235/p/14754286.html