vue-AudioComponent 音频播放组件

时间:2025-02-21 08:16:26

本文参考 /weixin_40404336/article/details/84570070

感谢上面博主分享,为了方便前端开发人员查阅,提供新的连接。~_~.

下面代码有个细节,slider滑块这里采用的vant,原理同上。

定义vue 文件 :,代码内容如下:(引用代码后,在其他页面导入该组件即可,不懂的可以看上面博主分享)

<template>

  <div class="di main-wrap">

    <!-- 这里设置了ref属性后,在vue组件中,就可以用this.$来访问该dom元素 -->

 

    

<template>

  <div class="di main-wrap">

    <!-- 这里设置了ref属性后,在vue组件中,就可以用this.$来访问该dom元素 -->

 

    <audio

      ref="audio"

      class="dn"

      :src="url"

      :preload=""

      @play="onPlay"

      @error="onError"

      @waiting="onWaiting"

      @pause="onPause"

      @timeupdate="onTimeupdate"

      @loadedmetadata="onLoadedmetadata"

    ></audio>

 

    <div>

      <!-- 倍率播放速度 -->

      <!-- <el-button v-show="!" type="text" @click="changeSpeed">{{ | transSpeed}}</el-button> -->

      <div class="boxs">

        <div class="track">

          <!-- <el-tag type="info">{{  | formatSecond}}</el-tag> -->

          <div class="times startT" @click="startPlayOrPause">播放</div>

          <div class="sliders-box">

            <!-- <el-slider

              v-show="!"

              v-model="sliderTime"

              :format-tooltip="formatProcessToolTip"

              @change="changeCurrentTime"

              class="slider"

            ></el-slider>-->

            <vanSlider

              v-model="sliderTime"

              :inactive-color="'#EBEBEB'"

              :bar-height="'2vw'"

              :active-color="'#0096F0'"

              @change="changeCurrentTime"

            >

              <!-- <div slot="button" class="custom-button">a</div> -->

            </vanSlider>

          </div>

          <div class="times endT">{{  | formatSecond }}</div>

          <!-- <el-tag type="info">{{  | formatSecond }}</el-tag> -->

        </div>

      </div>

 

      <div class="operation">

        <div class="back-box" @click="minus">

          <div style="width:20px;height:20px;background:red"></div>

        </div>

        <div class="play-bt" @click="startPlayOrPause">

          <img :src=" | transPlayPause" width="100%" alt />

        </div>

        <!-- <el-button type="text" @click="startPlayOrPause">{{ | transPlayPause}}</el-button> -->

 

        <div class="forward" @click="add">

          <div style="width:20px;height:20px;background:blue"></div>

        </div>

      </div>

 

      <!-- <el-button v-show="!" type="text" @click="startMutedOrNot">{{ | transMutedOrNot}}</el-button> -->

 

      <!-- <el-slider v-show="!" v-model="volume" :format-tooltip="formatVolumeToolTip" @change="changeVolume" class="slider"></el-slider> -->

 

      <!-- <a :href="url" v-show="!" target="_blank" class="download" download>下载</a> -->

    </div>

  </div>

</template>

 

<script>

function realFormatSecond(second) {

  var secondType = typeof second;

 

  if (secondType === "number" || secondType === "string") {

    second = parseInt(second);

 

    var hours = (second / 3600);

    second = second - hours * 3600;

    var mimute = (second / 60);

    second = second - mimute * 60;

 

    //   return hours + ':' + ('0' + mimute).slice(-2) + ':' + ('0' + second).slice(-2)

    return ("0" + mimute).slice(-2) + ":" + ("0" + second).slice(-2);

  } else {

    return "00:00";

  }

}

import { Slider } from "vant";

import "vant/lib/";

export default {

  components: {

    vanSlider: Slider

  },

  props: {

//音频路径

    theUrl: {

      type: String,

      required: true

    },

//播放速度 未测试

    theSpeeds: {

      type: Array,

      default() {

        return [1, 1.5, 2];

      }

    },

//

    theControlList: {

      type: String,

      default: ""

    }

  },

  name: "VueAudio",

  data() {

    return {

      L: 0,

      url:  || "/images/ti100audio/201909/2019/1569407886_019499.mp3",

      audio: {

        currentTime: 0,//当前播放时间

        maxTime: 0,//最大时长

        playing: false, //是否自动播放

        muted: false, //是否静音

 

        speed: 1,//播放速度

        waiting: true, // 处于等待状态

        preload: "auto" //是否重新播放

      },

 

      sliderTime: 0, //开始播放位置,

      volume: 100,//音量

      speeds: , // 播放速度

 

      controlList: {

        // 不显示下载

        noDownload: false,

        // 不显示静音

        noMuted: false,

        // 不显示音量条

        noVolume: false,

        // 不显示进度条

        noProcess: false,

        // 只能播放一个

        onlyOnePlaying: false,

        // 不要快进按钮

        noSpeed: false

      }

    };

  },

  methods: {

    setControlList() {

      let controlList = (" ");

      (item => {

        // ([item]);

        if ([item] !== undefined) {

          [item] = true;

        }

      });

    },

    changeSpeed() {

      let index = () + 1;

       = [index % ];

      this.$ = ;

    },

    startMutedOrNot() {

      this.$ = !this.$;

       = this.$;

    },

    // 音量条toolTip

    formatVolumeToolTip(index) {

      return "音量条: " + index;

    },

    // 进度条toolTip

    formatProcessToolTip(index = 0) {

      index = parseInt(( / 100) * index);

      return "进度条: " + realFormatSecond(index);

    },

    // 音量改变

    changeVolume(index = 0) {

      this.$ = index / 100;

       = index;

    },

    // 播放跳转

    changeCurrentTime(index) {

      this.$ = parseInt(

        (index / 100) * 

      );

    },

    startPlayOrPause() {

      return  ? () : ();

    },

    // 开始播放

    startPlay() {

      this.$();

    },

    // 暂停

    pausePlay() {

      this.$();

    },

    // 当音频暂停

    onPause() {

       = false;

    },

    // 当发生错误, 就出现loading状态

    onError() {

       = true;

    },

    // 当音频开始等待

    onWaiting(res) {

      (res);

    },

    // 当音频开始播放

    onPlay(res) {

      // (res)

       = true;

       = false;

 

      if (!) {

        return;

      }

 

      let target = ;

 

      let audios = ("audio");

 

      [...audios].forEach(item => {

        if (item !== target) {

          ();

        }

      });

    },

    // 当timeupdate事件大概每秒一次,用来更新音频流的当前播放时间

    onTimeupdate(res) {

      // ('timeupdate')

      //(res)

       = ;

       = parseInt(

        ( / ) * 100

      );

    },

    // 当加载语音流元数据完成后,会触发该事件的回调函数

    // 语音元数据主要是语音的长度之类的数据

    onLoadedmetadata(res) {

      ("loadedmetadata");

      (res);

       = false;

       = parseInt();

 

      // = parseInt( this.$);

      ("总时间", this.$);

      this.$emit("loading-true", 11);

    },

    add() {

      //前进15s

 

      let current_t = parseInt(this.$);

      let total_t = parseInt(this.$);

      //(this.$);

      this.$ =

        current_t + 15 >= total_t ? total_t : current_t + 15;

      (current_t, total_t, this.$);

      // (this.$);

    },

    minus() {

      //后退15秒

      let current_t = parseInt(this.$);

 

      this.$ = current_t - 15 <= 0 ? 0 : current_t - 15;

    }

  },

  watch: {},

  filters: {

    formatSecond(second = 0) {

      return realFormatSecond(second);

    },

    transPlayPause(value) {

      // (value);

      //return value ? require("../assets/img/") : require("../assets/img/")

      return "123";

    },

    transMutedOrNot(value) {

      return value ? "放音" : "静音";

    },

    transSpeed(value) {

      return "快进: x" + value;

    }

  },

  watch: {

    url(val, oldval) {

      (val, oldval);

    },

    sliderTime(val, oldval) {

      // (val,oldval);

      if (val >= 98) {

         = 98;

        return;

      }

       = val;

    }

  },

  created() {

    // let audio = new Audio();

    //  = ; //audio链接

    // ('loadedmetadata', function() {

    //     ();

    //     //

    // });

    ();

  }

};

</script>

 

<!-- Add "scoped" attribute to limit CSS to this component only -->

<style scoped>

.van-slider {

  width: 100%;

}

.boxs {

  display: flex;

  justify-content: center;

  position: fixed;

  bottom: 14vw;

  width: 100%;

  border-bottom: 1px solid #dfdfdf;

}

.track {

  background: #f8f8f8;

  height: 15vw;

  display: flex;

  justify-content: flex-start;

  align-items: center;

  box-sizing: border-box;

  width: 100%;

}

 

.times {

  color: #fff;

}

.startT {

  padding: 0 4vw;

  color: #333333;

}

.endT {

  padding: 0 4vw;

  color: #333333;

}

.operation {

  margin-top: 4vw;

  display: flex;

  justify-content: center;

  align-items: center;

}

.play-bt {

  font-size: 0;

  width: 76px;

  height: 75px;

}

.back-box {

  margin-right: 50px;

}

.forward {

  margin-left: 50px;

}

.back-box,

.forward {

  font-size: 0;

  width: 47px;

  height: 46px;

}

.sliders-box {

  width: 100%;

  display: flex;

  justify-content: center;

  align-items: center;

}

.div_box {

  height: 100px;

  position: relative;

}

.div0 {

  width: 10px;

  height: 10px;

  border-radius: 5px;

  background: red;

  position: absolute;

  top: 0;

}

.main-wrap {

  padding: 0;

}

 

.download {

  color: #409eff;

  margin-left: 15px;

}

 

.dn {

  display: none;

}

</style>