vue + element UI【实战】音乐播放器/语音条(内含音频的加载、控制,事件监听,信息获取,手机网页阴影的去除等技巧)

简介: vue + element UI【实战】音乐播放器/语音条(内含音频的加载、控制,事件监听,信息获取,手机网页阴影的去除等技巧)

相关技巧,详见注释

<template>
  <!-- 音乐播放器 -->
  <div class="container">
    <h2>{{ musicName }}</h2>
    <audio
      ref="Ref_audioPlayer"
      controls
      :src="audioPathDic[musicName]"
      @ended="overAudio"
      @pause="onPause"
      @play="onPlay"
      @loadeddata="loadeddata"
      @timeupdate="timeupdate"
    ></audio>
    <div>
      <el-tag>{{ msg }}</el-tag>
    </div>

    <div class="listBox">
      <h3 class="subTitle">原创面板</h3>

      <div class="myPlayer">
        <el-slider
          @mousedown="isDraging = 'true'"
          @mouseup="isDraging = 'false'"
          @change="currentRateChange"
          v-model="currentRate"
          :marks="marks"
          :show-tooltip="false"
        >
        </el-slider>
        <div class="controlBox">
          <i @click="move(-5)" class="el-icon-d-arrow-left"></i>
          <i
            type="primary"
            v-if="playstatus"
            @click="pause"
            class="el-icon-video-pause"
          ></i>
          <i type="primary" v-else @click="play" class="el-icon-video-play"></i>
          <i @click="replay" class="el-icon-refresh-left"></i>
          <i @click="move(5)" class="el-icon-d-arrow-right"></i>
        </div>
      </div>
      <h3 class="subTitle">播放列表</h3>
      <ul>
        <li
          @click="changeMusice(key)"
          class="musicItem"
          v-for="(value, key) in audioPathDic"
          :key="key"
        >
          {{ key }}
        </li>
      </ul>
      <h3 class="subTitle">获取信息</h3>
      <div class="btnBox">
        <el-button @click="getLength" type="primary" size="small"
          >获取时长</el-button
        >
        <el-button @click="getCurrentTime" type="primary" size="small"
          >获取播放进度</el-button
        >
        <el-button @click="getPlayStatus" type="primary" size="small"
          >获取播放状态</el-button
        >
      </div>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      playstatus: false,
      isDraging: false,
      marks: {
        0: "0",
        100: "100",
      },
      currentRate: 0,
      msg: "待播放",
      // 歌曲名称
      musicName: "祝福你",
      audioPathDic: {
        不再犹豫: require("@/pages/music/cantopop/audios/《不再犹豫》Beyond_粤语.mp3"),
        祝福你: require("@/pages/music/cantopop/audios/《祝福你》群星_粤语.mp3"),
      },
    };
  },
  methods: {
    // 监听audio标签的音频加载完成事件
    loadeddata() {
      // 需等音频加载完成,才能获取到音频的时长
      this.marks["100"] = this.s_to_MS(this.$refs.Ref_audioPlayer.duration);
    },

    // 监听audio标签的播放事件
    onPlay() {
      this.msg = "播放中";
      this.playstatus = true;
    },
    // 监听audio标签的暂停事件
    onPause() {
      this.msg = "已暂停";
      this.playstatus = false;
    },
    // 监听audio标签的停止播放事件
    overAudio() {
      this.msg = "播放结束";
      this.playstatus = false;
    },
    // 监听audio标签的播放进度改变事件
    timeupdate(e) {
      // 使用this.isDraging来控制,当拖拽进度条的过程中,停止对进度的更新——用于解决bug:拖动进度条自动回弹
      if (!this.isDraging) {
        this.currentRate = Math.floor(
          (e.target.currentTime / this.$refs.Ref_audioPlayer.duration) * 100
        );

        this.marks["0"] = this.s_to_MS(e.target.currentTime);
      }
    },

    // 秒数转换分+秒
    s_to_MS(s) {
      let m;
      m = Math.floor(s / 60);
      s = Math.floor(s % 60);
      m += "";
      s += "";
      s = s.length == 1 ? "0" + s : s;
      if (isNaN(m)) {
        return "&infin;";
      }
      return m + ":" + s;
    },

    // 切换音乐
    changeMusice(newMusicName) {
      this.musicName = newMusicName;
      this.$nextTick(() => {
        this.$refs.Ref_audioPlayer.play();
      });
    },

    // 原创面板——播放
    play() {
      this.$refs.Ref_audioPlayer.play();
    },

    // 原创面板——暂停
    pause() {
      this.$refs.Ref_audioPlayer.pause();
    },

    // 原创面板——重新播放
    replay() {
      this.$refs.Ref_audioPlayer.currentTime = 0;
      this.$refs.Ref_audioPlayer.play();
    },

    // 原创面板——前进、后退——改变当前播放位置
    move(val) {
      this.$refs.Ref_audioPlayer.currentTime += val;
      this.$refs.Ref_audioPlayer.play();
    },

    // 原创面板——点击/拖拽原创面板进度条
    currentRateChange(newVal) {
      this.$refs.Ref_audioPlayer.currentTime = Math.round(
        (newVal / 100) * this.$refs.Ref_audioPlayer.duration
      );
      this.$refs.Ref_audioPlayer.play();
    },

    // 获取播放状态
    getPlayStatus() {
      this.$notify.info({
        title: "当前播放状态",
        message: this.$refs.Ref_audioPlayer.paused ? "已暂停" : "播放中",
      });
    },

    // 获取播放进度
    getCurrentTime() {
      // 已播放时长(单位秒s)
      let totalSeconds = this.$refs.Ref_audioPlayer.currentTime;
      // 分钟数
      let minites = Math.floor(totalSeconds / 60);
      // 秒数
      let seconds = Math.floor(totalSeconds % 60);

      this.$notify.info({
        title: "当前进度",
        message: `${minites}分${seconds}秒`,
      });
    },

    // 获取音频时长
    getLength() {
      // 时长(单位秒s)
      let totalSeconds = this.$refs.Ref_audioPlayer.duration;
      // 分钟数
      let minites = Math.floor(totalSeconds / 60);
      // 秒数
      let seconds = Math.floor(totalSeconds % 60);

      this.$notify.info({
        title: "时长",
        message: `${minites}分${seconds}秒`,
      });
    },
  },
};
</script>

<style scoped>
.btnBox {
  display: flex;
  justify-content: space-evenly;
  flex-wrap: wrap;
  align-content: space-around;
}
.container {
  text-align: center;
  max-width: 500px;
  margin: auto;
}
.listBox {
  text-align: left;
}
.subTitle {
  margin-left: 40px;
}
.musicItem {
  line-height: 40px;
  cursor: pointer;
}

.myPlayer {
  border: 4px solid #409eff;
  border-radius: 10px;
  padding: 10px 20px;
  margin: 10px;
}
.controlBox {
  display: flex;
  justify-content: space-evenly;
  font-size: 30px;
  color: #409eff;
}

/* 去除手机网页点击事件的阴影 */
* {
  -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
  -webkit-tap-highlight-color: transparent;
}
</style>

获取播放状态

this.$refs.Ref_audioPlayer.paused
  • true 为暂停
  • false 为播放

获取音频总时长

单位为秒s

this.$refs.Ref_audioPlayer.duration

获取播放进度

单位为秒s

this.$refs.Ref_audioPlayer.currentTime

开始播放

this.$refs.Ref_audioPlayer.play();

暂停播放

this.$refs.Ref_audioPlayer.pause();

改变播放进度–前进、后退

    // 原创面板——前进、后退——改变当前播放位置
    move(val) {
      this.$refs.Ref_audioPlayer.currentTime += val;
      this.$refs.Ref_audioPlayer.play();
    },

重头开始播放

this.$refs.Ref_audioPlayer.currentTime = 0;
 this.$refs.Ref_audioPlayer.play();

audio标签的事件

通过监听事件实现

play:音频或视频文件已经就绪可以开始播放时触发

playing:音频或视频已开始播放时触发

ended:音频或视频文件播放完毕后触发

pause:音频或视频文件暂停时触发

ratechange:播放速度改变进触发

seeked:指示定位已结束时触发

seeking:正在进行指示定位时触发

timeupdate:播放位置改变时触发

volumechange:音量改变时触发

waiting:需要缓冲下一帧而停止时触发

loadstart:浏览器开始寻找指定的音频或视频

progress:浏览器正在下载指定的音频或视频

durationchange:音频或视频的时长已改变

loadedmetadata:音频或视频的元数据已加载

loadeddata:音频或视频的当前帧已加载,但没有足够数据播放下一帧

canplay:浏览器能够开始播放指定的音频或视频

canplaythrough:音频或视频能够不停顿地一直播放

progress:浏览器正在下载指定的音频或视频

abort:在音频或视频终止加载时触发

error:在音频或视频加载发生错误时触发

stalled:在浏览器尝试获取媒体数据,但数据不可用时触发

suspend:在音频或视频数据被阻止加载时触发

empted:在发生故障并且文件突然不可用时触发

play:音频或视频文件已经就绪可以开始播放时触发

playing:音频或视频已开始播放时触发

ended:音频或视频文件播放完毕后触发

pause:音频或视频文件暂停时触发

ratechange:播放速度改变进触发

seeked:指示定位已结束时触发

seeking:正在进行指示定位时触发

timeupdate:播放位置改变时触发

volumechange:音量改变时触发

waiting:需要缓冲下一帧而停止时触发

语音条

请参考

https://www.jianshu.com/p/11a6101d9656

目录
相关文章
|
1天前
|
UED
Element UI 一键校验多表单(v-for循环表单,异步校验规则,v-for 中的 ref 属性,避坑 forEach 不支持异步 await )
Element UI 一键校验多表单(v-for循环表单,异步校验规则,v-for 中的 ref 属性,避坑 forEach 不支持异步 await )
2 0
|
3天前
|
数据安全/隐私保护
Element UI 密码输入框--可切换显示隐藏,自定义图标
Element UI 密码输入框--可切换显示隐藏,自定义图标
7 0
|
3天前
|
前端开发 小程序
【微信小程序-原生开发】实用教程20 - 生成海报(实战范例为生成活动海报,内含生成指定页面的小程序二维码,保存图片到手机,canvas 系列教程)
【微信小程序-原生开发】实用教程20 - 生成海报(实战范例为生成活动海报,内含生成指定页面的小程序二维码,保存图片到手机,canvas 系列教程)
6 0
|
3天前
Element UI 表格【列宽自适应】
Element UI 表格【列宽自适应】
4 0
|
3天前
|
前端开发
ElementPlus卡片如何能够一行呈四,黑马UI前端布局视频资料,element样式具体的细节无法修改,F12找到那个位置,可能在其他组件写了错误,找到那个位置,围绕着位置解决问题最快了,卡片下边
ElementPlus卡片如何能够一行呈四,黑马UI前端布局视频资料,element样式具体的细节无法修改,F12找到那个位置,可能在其他组件写了错误,找到那个位置,围绕着位置解决问题最快了,卡片下边
|
3天前
Element UI 【表格合计】el-table 实战范例 -- 添加单位,自定义计算逻辑
Element UI 【表格合计】el-table 实战范例 -- 添加单位,自定义计算逻辑
6 0
|
2月前
|
前端开发 搜索推荐 开发者
SAP UI5 sap.m.Column 控件的 minScreenWidth 属性介绍
SAP UI5 sap.m.Column 控件的 minScreenWidth 属性介绍
|
2月前
|
JavaScript 前端开发 开发者
SAP UI5 控件 sap.m.ListBase 的 inset 属性的作用介绍
SAP UI5 控件 sap.m.ListBase 的 inset 属性的作用介绍
|
2月前
|
前端开发 JavaScript API
SAP UI5 sap.ui.require.toUrl 的作用介绍
SAP UI5 sap.ui.require.toUrl 的作用介绍
|
2月前
|
JSON 前端开发 测试技术
SAP UI5 sap.ui.core.util.MockServer.simulate 方法介绍
SAP UI5 sap.ui.core.util.MockServer.simulate 方法介绍