zoukankan      html  css  js  c++  java
  • vue中可以用的音频播放demo,可以作为组件引入

    vue中可以用的音频播放demo,可以作为组件引入

    参考文章:

    https://segmentfault.com/a/1190000012453975

    https://blog.csdn.net/xzwwjl1314/article/details/107204842/

    其中主要参考第二篇,但在进度条拖动上,获取鼠标当前位置遇到问题。

    clickProgress这个方法

    const position = e.clientX - e.currentTarget.offsetLeft

    这个地方获取的e.clientX值为900多,是变化的,但是e.currentTarget.offsetLeft的值一直是41,导致一拖动按照百分比计算的播放时间直接因为分子太大直接到底

    后面发下在0的位置,是917, e.clientX为变化,923,957,依次变化,变化的值就是点击后的当前鼠标位置

    所以用 (e.clientX-917)/ 进度条总宽度 * 总时长,获得跳转时长

    4/20 update:

    clickProgress方法这里的固定距离,写死的917遇到不同情况会失效,因为917不可以写死。
    后续根据屏幕估算,用了document.body.clientWidth * 0.74代替写死的数值
    const fixedSpace = document.body.clientWidth * 0.74; // 这是根据屏幕估算的
     
        clickProgress(event) {
          console.log(event);
          // 点击进度条时 更新音频时间和进度条
          const e = event || window.event;
          const position = e.clientX - e.currentTarget.offsetLeft; // 当前点击的位置
          const progressWidth = this.$refs.progress.offsetWidth; // 进度条总宽度
          // 第一步确认固定距离 878  减去固定距离就是剩余距离
          const fixedSpace = document.body.clientWidth * 0.74; // 这是根据屏幕估算的
          const space = position - fixedSpace;
          this.$refs.audio.currentTime = (space / progressWidth) * this.duration;
          this.updateProgress(
            (position / progressWidth) * this.duration,
            this.duration
          );
        },
    <template>
      <div>
        <div class="ckplayer">
          <div class="bottom-progress">
            <div class="curTime">{{ curTime ? curTime : "00:00" }}</div>
            <div class="progress" @click="clickProgress($event)" ref="progress">
              <div class="line" :style="{  `${precent}` }"></div>
              <div
                class="dot"
                :style="{ left: `${precent}` }"
                @touchstart="dotStart"
                @touchmove="dotMove"
                @touchend="dotEnd"
              ></div>
            </div>
            <div class="allTime">{{ allTime }}</div>
          </div>
          <div class="bottom-controls">
            <div class="prev" @click="prevSong">
              <!-- <i class="pre"></i> -->
            </div>
            <div class="pause" v-show="isPlaying" @click="pauseSong">
              <!-- <i class="fa fa-pause">暂停</i> -->
            </div>
            <div class="play" v-show="!isPlaying" @click="playSong">
              <!-- <i class="fa fa-play">播放</i> -->
            </div>
            <div class="next" @click="nextSong"></div>
          </div>
          <!-- autio标签 -->
          <audio
            @timeupdate="updateTime"
            @canplay="getDuration"
            @ended="ended"
            :src="musicUrl"
            id="audio"
            ref="audio"
            class="testAudio"
          ></audio>
        </div>
      </div>
    </template>
    
    <script>
    import { boardListDetail } from "@/utils/api";
    export default {
      data() {
        return {
          list: [],
          tvUrl: "",
          player: null,
          playingSong: {}, // 正在播放的歌曲信息
          show: true, // 控制cd和lyrics的显示 默认显示cd
          isPlaying: false, // 播放和暂停状态
          musicUrl: "", // 音乐地址
          curTime: "00:00", // 当前播放时间,格式化之后的
          allTime: "00:00", // 当前音频总时长,格式化之后的
          duration: 0, // 音频总时长,单位秒
          currentTime: 0, // 音频当前播放时间, 单位秒
          precent: "0%", // 当前播放进度百分比
          touchInfo: {}, // 原点滑动时的位置信息
          lyrics: {}, // 歌词 中英文
          lyricsObjArr: [], // 处理之后的歌词 包含时间和歌词
          curMsTime: "", // 当前音频播放的时分毫秒
          like: false, // 是否喜欢当前歌曲 默认为不喜欢
          lyricIndex: "0", // 当前显示的歌词
          isMuted: false, // 是否经验 默认不静音
          volume: 100, // 音频音量
          likeList: [],
          playType: 0, // 播放类型 0代表播放单曲 1代表播放歌曲列表
          audios: [],
          index: 0,
        };
      },
      components: {},
      created() {
        this.getAudio();
        this.loadMusic(this.index);
        this.playType = this.audios.length === 1 ? 0 : 1;
      },
      mounted() {},
      methods: {
        async getAudio() {
          const res = await boardListDetail({
            page: this.page,
            pagesize: this.pagesize,
          });
          this.audios = res.data.items[0].audio_path;
          this.loadMusic(this.index);
        },
        clickProgress(event) {
          console.log(event);
          // 点击进度条时 更新音频时间和进度条
          const e = event || window.event;
          const position = e.clientX - e.currentTarget.offsetLeft; // 当前点击的位置
          const progressWidth = this.$refs.progress.offsetWidth; // 进度条总宽度
          // 第一步确认固定距离 878  减去固定距离就是剩余距离
          const fixedSpace = document.body.clientWidth * 0.74; // 这是根据屏幕估算的
          const space = position - fixedSpace;
          this.$refs.audio.currentTime = (space / progressWidth) * this.duration;
          this.updateProgress(
            (position / progressWidth) * this.duration,
            this.duration
          );
        },
        updateProgress(currentTime, duration) {
          // 更新进度条
          const precent = `${((currentTime / duration) * 100).toFixed(5)}%`;
          this.precent = precent;
        },
        dotEnd(e) {
          this.playSong();
          this.isPlaying = true;
        },
        dotMove(e) {
          console.log(e);
          // 移动的距离
          let moveX = e.touches[0].pageX - 83;
          // console.log(moveX, "kk");
          // 进度条的宽度
          const progressWidth = this.$refs.progress.offsetWidth;
          if (moveX >= progressWidth) moveX = progressWidth;
          this.$refs.audio.currentTime = (moveX / progressWidth) * this.duration;
          this.updateProgress(
            (moveX / progressWidth) * this.duration,
            this.duration
          );
        },
        dotStart(e) {
          // 点击的初始位置
          this.touchInfo.startX = e.touches[0].pageX - 83;
        },
        formatTime(time) {
          if (time === 0) {
            this.curTime = "00:00";
            return;
          }
          const mins =
            Math.floor(time / 60) < 10
              ? `0${Math.floor(time / 60)}`
              : Math.floor(time / 60);
          const sec =
            Math.floor(time % 60) < 10
              ? `0${Math.floor(time % 60)}`
              : Math.floor(time % 60);
          return `${mins}:${sec}`;
        },
        ended() {
          this.$refs.audio.currentTime = 0;
          this.isPlaying = false;
          // if (this.playType === 0) {
          //   this.$message.warning("歌曲列表只有这一首 请返回上一级!");
          //   this.curTime = "00:00";
          //   return;
          // }
          // if (this.index >= this.audios.length - 1) {
          // }
          this.nextSong();
          console.log("播放完毕");
          this.curTime = "00:00";
        },
        updateTime(e) {
          // timeupdate时获取当前播放时间
          const { currentTime } = e.target;
          // console.log(e.target.currentTime, "看看");
          this.currentTime = currentTime;
          this.curTime =
            this.formatTime(currentTime) === "undefined"
              ? "00:00"
              : this.formatTime(currentTime);
          this.updateProgress(currentTime, this.duration);
          // console.log(this.formatTime(currentTime), "k");
        },
        loadMusic(index) {
          // 加载播放地址
          this.musicUrl = this.audios[index];
          console.log(this.musicUrl, this.audios[index]);
        },
        playSong() {
          console.log("5");
          // 手动点击播放歌曲
          const audio = this.$refs.audio;
          this.isPlaying = !this.isPlaying;
          audio.play();
        },
        autoPlaySong() {
          // 自动播放歌曲
          const audio = this.$refs.audio;
          audio.autoplay = true;
          this.isPlaying = true;
        },
        nextSong() {
          console.log("进下一首");
          this.$refs.audio.currentTime = 0;
          // this.isPlaying = false;
          this.curTime = "00:00";
          // 播放下一首歌曲
          this.index++;
          if (this.index > this.audios.length - 1) {
            this.index = 0;
          }
          console.log(this.index);
          this.loadMusic(this.index);
          this.autoPlaySong();
        },
        prevSong() {
          console.log("上一首");
          this.$refs.audio.currentTime = 0;
          // this.isPlaying = false;
          this.curTime = "00:00";
          // 播放上一首歌曲
          this.index--;
          if (this.index < 0) {
            this.index = this.audios.length - 1;
          }
          console.log(this.index, this.curTime);
          this.loadMusic(this.index);
          this.autoPlaySong();
        },
        pauseSong() {
          console.log("6");
          // 暂停歌曲
          this.isPlaying = !this.isPlaying;
          this.$refs.audio.pause();
        },
        getDuration() {
          // canplay时获取音频总时长
          this.duration = this.$refs.audio.duration;
          this.allTime = this.formatTime(this.$refs.audio.duration);
        },
      },
    };
    </script>
    
    <style scoped lang="scss">
    .ckplayer {
      width: 100%;
      height: 25vh;
      position: absolute;
      top: 7%;
      left: 5.5%;
      width: 89%;
      height: 82%;
      .testAudio {
        width: 100%;
        height: 100%;
        background: red;
      }
    }
    
    .bottom {
      height: 20%;
      color: #fff;
      &-line1 {
        font-size: 0.8vw;
        display: flex;
        align-items: center;
        justify-content: space-around;
      }
      &-progress {
        padding: 0 5%;
        // margin: 5% 0;
        display: flex;
        align-items: center;
        justify-content: space-between;
        .progress {
          height: 0.2vh;
          background-color: #fff;
          width: 70%;
          position: relative;
          .line {
            position: absolute;
            left: 0;
            top: 0;
            height: 0.1vh;
            background-color: skyblue;
            transition: width 0.1s;
          }
          .dot {
            width: 0.5vw;
            height: 1vh;
            border-radius: 50%;
            position: absolute;
            top: -0.4vh;
            background-color: #ccc;
            transition: left 0.1s;
          }
        }
      }
      &-controls {
        padding: 0 5%;
        display: flex;
        align-items: center;
        justify-content: space-around;
        font-size: 30px;
        padding: 0 3vw;
        .prev {
          width: 1.3vw;
          height: 2.5vh;
          background: url("../assets/pre.png") no-repeat;
          background-size: 100% 100%;
          cursor: pointer;
        }
        .next {
          width: 1.3vw;
          height: 2.5vh;
          background: url("../assets/next.png") no-repeat;
          background-size: 100% 100%;
          cursor: pointer;
        }
        .pause {
          width: 4vw;
          height: 8vh;
          background: url("../assets/pause.png") no-repeat;
          background-size: 100% 100%;
          cursor: pointer;
        }
        .play {
          width: 4vw;
          height: 8vh;
          background: url("../assets/play.png") no-repeat;
          background-size: 100% 100%;
          cursor: pointer;
        }
      }
    }
    </style>
    你好,我是Jane,如果万幸对您有用,请帮忙点下推荐,谢谢啦~另外,咱们闪存见哦~
  • 相关阅读:
    如何用Java编写一段代码引发内存泄露
    获取一天的开始时间和结束时间
    servlet,jsp,tomcat,jdk对应版本关系,如何查看jsp和servlet版本信息
    什么是元数据?
    什么是Device ID?
    如何查看移动设备标识码
    手机wifi的mac地址是什么??
    MD5摘要
    落地页和离线广告
    广告行业一些常用物料的尺寸
  • 原文地址:https://www.cnblogs.com/jane-panyiyun/p/14628762.html
Copyright © 2011-2022 走看看