Vue实现audio播放音频【切换播放/拖动进度条播放】_JavaScript_菜鸟老五-CSDN博客

//如图所示?功能//1--上一首下一首切换播放音乐//2--点击进度条播放音乐//3--拖动进度条播放音乐//4--模拟预加载进度条//5--播放倒计时

<template>  <!--  -->  <div>    <div id="page-body">      <!-- banner图文 -->      <div class="banner-div">        <img src="../../../../static/img/productModel/headbg.png" class="headbg" />        <label class="banner-name">{{current.name}}</label>        <label class="banner-title">{{current.title}}</label>        <div class="banner-lab">          <img src="../../../../static/img/productModel/banner@2x.png" class="banner-divimg" />        </div>        <label class="banner-desc">{{current.desc}}</label>      </div>      <!-- 播放视图 -->      <div class="audio-div">        <div class="bg-blur"></div>        <div class="audio-block">          <div class="header">            <label class="startTime">{{ audio.currentTime | formatSecond}}</label>            <div class="silder">              <div class="slider" @touchstart="handleTouchStart">                <div class="slider-track"></div>                <div class="silderNone" :style="'width:'+silderNone+'%'"></div>                <div class="slider-fill" :style="'width:'+sliderTime+'%'"></div>                <div class="slider-thumb" :style="'left:'+sliderTime+'%'"></div>              </div>              <!--  -->              <audio                ref="audio"                @pause="onPause"                @play="onPlay"                @timeupdate="onTimeupdate"                @loadedmetadata="onLoadedmetadata"                preload="auto"                autoplay                :src="current.audioHttp"                controls="controls"                style="display:none;"              ></audio>            </div>            <label class="endtime">{{ audio.maxTime | formatSecond}}</label>          </div>          <!-- <label class="playname">{{current.title}}</label> -->          <div class="model-div">            <img              src="../../../../static/img/productModel/lasticon.png"              v-if="current.index!=1"              class="lasticon"              @click="switchAudio('top')"            />            <img src="../../../../static/img/productModel/lastnone.png" v-else class="lasticon" />            <img              v-if="play"              src="../../../../static/img/productModel/stopicon.png"              class="playicon"              @click="startPlayOrPause"            />            <img              v-else              src="../../../../static/img/productModel/playicon.png"              class="playicon"              @click="startPlayOrPause"            />            <img              v-if="current.nextIndex!=2"              src="../../../../static/img/productModel/nexticon.png"              class="nexticon"              @click="switchAudio('bottom')"            />            <img v-else src="../../../../static/img/productModel/nextnone.png" class="nexticon" />          </div>        </div>      </div>      <!-- 课程内容 -->      <div class="contents">        <div class="contents-div">          <label class="label-cont">课程内容</label>          <label class="label-block"></label>          <div class="label-text">            第一次买重疾,这些都要注意            医疗险,除了百万你还要知道这些写            家庭支柱,都该看看寿险            意外险,不是你该省的钱          </div>        </div>      </div>      <!-- 课程福利 -->      <div class="welfare-div">        <div class="contents-div">          <label class="label-cont">课程福利</label>          <label class="label-block"></label>        </div>        <div class="label-div">          <div class="left-div">            <img class="auimg" src="../../../../static/img/productModel/left.png" />            <label class="auimgName">1次</label>            <label class="auimgTitle">免费家庭风险测评</label>          </div>          <div class="right-div">            <label class="auimgName">1V1</label>            <label class="auimgTitle">专家免费咨询</label>            <img class="auimg" src="../../../../static/img/productModel/right.png" />          </div>        </div>      </div>    </div>  </div></template> <script>import { truncate, ftruncate, truncateSync } from "fs";import { fips } from "crypto";import { clearInterval } from 'timers';// 将整数转换成 时:分:秒的格式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;    // hours + ':' +    return ("0" + mimute).slice(-2) + ":" + ("0" + second).slice(-2);  } else {    return "0:00:00";  }}var times=null;export default {  data() {    return {      sliderTime: 0,      silderNone: 0,          audio: {        // 该字段是音频是否处于播放状态的属性        playing: false,         // 音频当前播放时长        currentTime: 0,        // 音频最大播放时长        maxTime: 0,        minTime: 0,        step: 0.1      },      lefticon: "",      play: false, // 播放暂停按钮      current: {        startTime: "00:00",        endtime: "00:00",        index: 1,        nextIndex: 1,        poster: "https://img-cdn-qiniu.dcloud.net.cn/uniapp/audio/music.jpg",        name: "第一节:",        author: "暂无",        audioHttp: "../../../../static/audio/1.mp3",        title: "四大基础险种",        desc: "主讲老师:郭冲老师",        content: {          name: "课程内容",          title:            "第一次买重疾,这些都要注意 医疗险,除了百万你还要知道这些写家庭支柱,都该看看寿险意外险,不是你该省的钱"        },        times: ""      }    };  },  created() {    var that = this;    that.$refs.audio.play();    that.play = true;    that.$refs.audio.pause();    //  that.silderNone=0;   },  mounted() {    // this.$refs.audio.play();    var that=this;    that.play = true;    // this.$refs.audio.pause();      times= setInterval(() => {      that.silderNone =that.silderNone+10;         if(that.silderNone==100){        window.clearInterval(times);      }         console.log("开始播放",that.silderNone);     }, 1000);  },  methods: {    /**     * 控制音频的播放与暂停 {三元运算方式简单/后期优化}     */    startPlayOrPause() {      console.log(this.audio.playing);      if (!this.audio.playing) {        this.play = true;        this.$refs.audio.play();      } else {        this.$refs.audio.pause();        this.play = false;      }    },    /**     * 切换歌曲事件     */    switchAudio(value) {      var that = this;      if (value === "top") {        this.current = {          startTime: "00:00",          endtime: "00:00",          index: 1,          nextIndex: 1,          poster: "https://img-cdn-qiniu.dcloud.net.cn/uniapp/audio/music.jpg",          name: "第一节:",          author: "暂无",          audioHttp: "../../../../static/audio/1.mp3",          title: "四大基础险种",          desc: "主讲老师:郭冲老师",          content: {            name: "课程内容",            title:              "第一次买重疾,这些都要注意 医疗险,除了百万你还要知道这些写家庭支柱,都该看看寿险意外险,不是你该省的钱"          },          time: ""        };      } else if (value === "bottom") {        this.current = {          startTime: "00:00",          endtime: "00:00",          index: 2,          nextIndex: 2,          poster: "https://img-cdn-qiniu.dcloud.net.cn/uniapp/audio/music.jpg",          name: "第二节:",          author: "暂无",          audioHttp: "../../../../static/audio/2.mp3",          title: "儿童保险",          desc: "主讲老师:老白老师",          content: {            name: "课程内容",            title:              "第一次买重疾,这些都要注意 医疗险,除了百万你还要知道这些写家庭支柱,都该看看寿险意外险,不是你该省的钱"          },          time: ""        };      }      this.sliderTime = 0;      this.audio.currentTime = "00:00";      this.play = true; // 更改播放暂停按钮为播放      that.silderNone=0;      // 切换下一首,进度条模拟预加载效果       times= setInterval(() => {      that.silderNone =that.silderNone+10;         if(that.silderNone==100){        window.clearInterval(times);      }         console.log("开始播放",that.silderNone);     }, 1000);      this.$refs.audio.play();      // index = 0; // 清空颜色进度条    },    // 播放音频    play() {      console.log("你的播放开启了");      this.$refs.audio.play();      this.play = true;    },    // 暂停音频    pause() {      this.$refs.audio.pause();    },    // 当音频播放    onPlay() {      console.log("音频正在播放中");      this.audio.playing = true;    },    // 当音频暂停    onPause() {      this.audio.playing = false;      var startTime = parseInt(this.audio.currentTime);      console.log(        "this.audio.playing",        this.audio.playing,        "maxTime",        this.audio.maxTime      );      //      this.play = false;      if (startTime == this.audio.maxTime) {        this.sliderTime = 0;        this.audio.currentTime = "00:00";      }    },    handleFocus() {      console.log("focues");    },    // 当加载语音流元数据完成后,会触发该事件的回调函数    // 语音元数据主要是语音的长度之类的数据    // 结束时间    onLoadedmetadata(res) {      console.log("loadedmetadata");      // console.log(res)      this.audio.maxTime = parseInt(res.target.duration);    },    // 当timeupdate事件大概每秒一次,用来更新音频流的当前播放时间    // 当音频当前时间改变后,进度条也要改变    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);    },     handleTouchStart(e) {      this.setValue(e.touches[0]);      this.$refs.audio.play();      document.addEventListener("touchmove", this.handleTouchMove);      document.addEventListener("touchup", this.handleTouchEnd);      document.addEventListener("touchend", this.handleTouchEnd);      document.addEventListener("touchcancel", this.handleTouchEnd);       // e.preventDefault();      // this.onDragStart(e);    },    handleTouchMove(e) {      console.log(e.changedTouches[0]);      this.setValue(e.changedTouches[0]);    },    handleTouchEnd(e) {      this.setValue(e.changedTouches[0]);      document.removeEventListener("touchmove", this.handleTouchMove);      document.removeEventListener("touchup", this.handleTouchEnd);      document.removeEventListener("touchend", this.handleTouchEnd);      document.removeEventListener("touchcancel", this.handleTouchEnd);      // this.onDragStop(e);    },    // 从点击位置更新 value    setValue(e) {      const $el = this.$el;      const { maxTime, minTime, step } = this.audio;      let value =        ((e.clientX - $el.getBoundingClientRect().left) / $el.offsetWidth) *        (maxTime - minTime);      value = Math.round(value / step) * step + minTime;      value = parseFloat(value.toFixed(5));       if (value > maxTime) {        value = maxTime;      } else if (value < minTime) {        value = minTime;      }      this.$refs.audio.currentTime = value;    },    // 拖动进度条,改变当前时间,index是进度条改变时的回调函数的参数0-100之间,需要换算成实际时间    changeCurrentTime(index) {      console.log("拖动进度条");      // this.audio.playing && this.pause();      // console.log('拖动了',index,this.sliderTime,this.audio.maxTime,parseInt(index / 100 * this.audio.maxTime))      // !this.audio.playing && this.play();      this.$refs.audio.currentTime = parseInt(        (index / 100) * this.audio.maxTime      );    }  },  filters: {    // 使用组件过滤器来动态改变按钮的显示    transPlayPause(value) {      return value ? "暂停" : "播放";    },    // 将整数转化成时分秒    formatSecond(second = 0) {      return realFormatSecond(second);    }  }};</script> <style lang="less">#page-body {  background: #f5f5f5;  overflow: hidden;   .banner-div {    font-size: 0.44rem;    font-family: PingFangSC-Medium;    color: rgba(51, 51, 51, 1);    width: 100%;    position: relative;    background-color: #fff;    text-align: center;    height: 4rem;     .headbg {      width: 100%;      height: 3rem;    }    .banner-lab {      position: absolute;      top: 0;      width: 100%;      padding-top: 0.5rem;      height: 3rem;    }    .banner-divimg {      width: 90%;      margin: 0 auto;      display: inline-block;      height: 3.5rem;    }    .banner-name {      position: absolute;      z-index: 2;      left: 1.1rem;      top: 1.1rem;    }    .banner-title {      position: absolute;      z-index: 2;      left: 1.1rem;      top: 1.75rem;    }    .banner-desc {      position: absolute;      z-index: 2;      left: 1.1rem;      font-size: 0.28rem;      top: 2.8rem;    }  }  .audio-div {    position: relative;    width: 100%;    height: 2.4rem;    background: #fff;    margin-bottom: 0.2rem;     .audio-block {      width: 100%;      height: 0.9rem;      display: inline-block;      position: relative;      .header {        position: relative;        width: 68%;        display: inline-block;        top: 0;        text-align: center;        height: 0.7rem;        line-height: 0.7rem;         .slider {          width: 100%;          position: relative;          height: 0.1rem;          left: 1.2rem;          display: flex;          align-items: center;          bottom: 0.15rem;          cursor: default;          border-radius: 0.3rem;          user-select: none;          outline: none;        }        .silderNone {            position: absolute;          height: 0.1rem;          width: 100%;          background-color:#ccc;          left: 0;          border-radius: 0.3rem;          top: 50%;          margin-top: -1px;        }         .slider-track {          position: absolute;          height: 0.1rem;          left: 0;          right: 0;          border-radius: 0.3rem;          top: 50%;          background-color: #e4e4e4;        }         .slider-fill {          position: absolute;          height: 0.1rem;          width: 100%;          background-color: #ffbb38;          left: 0;          border-radius: 0.3rem;          top: 50%;          margin-top: -1px;        }         .slider-thumb {          position: absolute;          width: 0.27rem;          top: 0.08rem;          height: 0.27rem;          background-color: #ffbb38;          color: #ffbb38;          border-radius: 50%;          transform: translate(-50%, -50%);          cursor: pointer;        }             .startTime {          font-size: 0.25rem;          position: absolute;          z-index: 2;          left: 0.35rem;          font-size: 0.26rem;          bottom: 0.45rem;        }        .endtime {          font-size: 0.25rem;          position: absolute;          z-index: 2;          left: 6.5rem;          bottom: 0.45rem;        }      }    }     .model-div {      position: relative;      width: 100%;      bottom: 0.5rem;      height: 1rem;      text-align: center;    }    .playicon {      width: 1rem;      height: 1rem;      position: relative;      display: inline-block;      top: 0;    }    .lasticon {      position: absolute;      width: 0.74rem;      height: 0.74rem;      left: 1.2rem;      top: 0.2rem;    }     .nexticon {      position: absolute;      width: 0.74rem;      height: 0.74rem;      right: 1.2rem;      top: 0.2rem;    }  }  //  .contents {    position: relative;    width: 100%;    height: 3.04rem;    margin-bottom: 0.2rem;    background: #fff;    .contents-div {      position: relative;      width: 100%;      top: 0.1rem;      padding-top: 0.3rem;      height: 0.5rem;      /* background: red; */      .label-cont {        position: absolute;        left: 0.26rem;        font-size: 0.4rem;        font-family: PingFangSC-Medium;        font-weight: 500;        color: rgba(247, 97, 21, 1);        z-index: 1;      }       .label-block {        position: absolute;        left: 0.22rem;        width: 1.69rem;        height: 0.14rem;        background: rgba(255, 234, 205, 1);        border-radius: 0.7rem;        bottom: 0.1rem;      }    }    .label-text {      position: absolute;      font-size: 0.3rem;      font-family: PingFangSC-Medium;      font-weight: 500;      width: 7rem;      height: 1.66rem;      line-height: 1.5em;      left: 0.3rem;      top: 1rem;      left: 0.3rem;      color: rgba(88, 96, 106, 1);    }  }   .welfare-div {    position: relative;    width: 100%;    height: 3.34rem;    background: #ffffff;    .contents-div {      position: relative;      width: 100%;      top: 0.1rem;      padding-top: 0.3rem;      height: 0.5rem;      /* background: red; */      .label-cont {        position: absolute;        left: 0.26rem;        font-size: 0.4rem;        font-family: PingFangSC-Medium;        font-weight: 500;        color: rgba(247, 97, 21, 1);        z-index: 1;      }      .label-block {        position: absolute;        left: 0.22rem;        width: 1.69rem;        height: 0.14rem;        background: rgba(255, 234, 205, 1);        border-radius: 0.7rem;        bottom: 0.1rem;      }    }    .label-div {      position: relative;      width: 100%;      height: 2rem;      top: 0.2rem;      text-align: center;    }     .left-div {      position: absolute;      left: 0.3rem;      width: 3.32rem;      background: #fff;      height: 1.52rem;      top: 0.2rem;    }     .right-div {      position: absolute;      right: 0.3rem;      width: 3.32rem;      background: #fff;      top: 0.2rem;      height: 1.52rem;    }     .auimg {      width: 3.32rem;      height: 1.58rem;    }     .auimgName {      position: absolute;      z-index: 1;      top: 0.35rem;      left: 0;      width: 100%;      display: inline-block;      font-size: 0.5rem;      font-family: PingFang SC;      font-weight: 500;      color: rgba(87, 26, 10, 1);      text-align: center;    }     .auimgTitle {      position: absolute;      z-index: 1;      width: 100%;      left: 0;      text-align: center;      height: 0.3rem;      display: inline-block;      /* background: #007AFF; */      top: 1rem;      font-size: 0.28rem;      font-family: PingFang SC;      font-weight: 400;      color: rgba(150, 84, 61, 1);    }  }}</style>

Original url: Access
Created at: 2020-02-26 20:14:28
Category: default
Tags: none

请先后发表评论
  • 最新评论
  • 总共0条评论