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

目录
相关文章
|
Web App开发 前端开发 JavaScript
Element UI框架中自定义input组件的placeholder样式。
确保这些样式在你的应用程序CSS文件中定义,且该文件已正确加载到项目中。通过以上方法,可以控制Element UI组件中input的placeholder样式,使其满足特定的设计要求。这些更改都是基于CSS伪元素进行的,因此并不会对DOM结构产生改变,保持了原有结构的简洁和高效。
951 12
|
存储 JavaScript 前端开发
element ui <el-date-picker> 设置展示当前月
在 Element UI 中,使用 `el-date-picker` 的 `value-format` 属性可将日期值格式化为指定字符串。设置 `type=&quot;month&quot;` 时,绑定值默认为 Date 对象,通过 `value-format=&quot;yyyy-MM&quot;` 可将其转为如 &quot;2023-05&quot; 格式,便于存储与处理。
1600 0
|
移动开发 前端开发 Java
Java最新图形化界面开发技术——JavaFx教程(含UI控件用法介绍、属性绑定、事件监听、FXML)
JavaFX是Java的下一代图形用户界面工具包。JavaFX是一组图形和媒体API,我们可以用它们来创建和部署富客户端应用程序。 JavaFX允许开发人员快速构建丰富的跨平台应用程序,允许开发人员在单个编程接口中组合图形,动画和UI控件。本文详细介绍了JavaFx的常见用法,相信读完本教程你一定有所收获!
16473 5
Java最新图形化界面开发技术——JavaFx教程(含UI控件用法介绍、属性绑定、事件监听、FXML)
|
API UED 容器
深入探索 Element UI:自定义滚动条与弹出层管理的技巧
在这篇博客中,我们将深入探讨 Element UI 中的自定义滚动条及弹出层管理技巧。文章详细介绍了 el-scrollbar 组件的使用和参数设置,以及 PopupManager 如何有效管理弹出层的 z-index。我们还将探讨如何实现灵活的全屏组件,利用 vue-popper 创建自定义弹出层,最后介绍 ClickOutside 指令的用法。这些高级技巧将帮助你提升 Element UI 应用程序的用户体验与交互灵活性。
1829 1
深入探索 Element UI:自定义滚动条与弹出层管理的技巧
|
JavaScript 索引
Vue开发中Element UI/Plus使用指南:常见问题(如Missing required prop: “value“)及中文全局组件配置解决方案
Vue开发中Element UI/Plus使用指南:常见问题(如Missing required prop: “value“)及中文全局组件配置解决方案
1419 0
|
开发框架 前端开发 JavaScript
【HarmonyOS Next之旅】基于ArkTS开发(二) -> UI开发一
本文介绍了方舟开发框架(ArkUI)及其两种开发范式:基于ArkTS的声明式开发范式和类Web开发范式。ArkUI是用于构建HarmonyOS应用界面的UI框架,提供极简UI语法和基础设施。声明式开发范式使用ArkTS语言,以组件、动画和状态管理为核心,适合复杂团队协作;类Web开发范式采用HML、CSS、JavaScript三段式开发,适用于简单界面应用,贴近Web开发者习惯。文中还概述了两者的架构和基础能力,帮助开发者选择合适的范式进行高效开发。
520 15
|
编解码 前端开发 Java
【HarmonyOS Next之旅】基于ArkTS开发(二) -> UI开发三
本文介绍了基于声明式UI范式的图形绘制与动画效果实现方法,涵盖绘制图形、添加动画效果及常见组件说明三部分内容。在绘制图形部分,详细讲解了如何通过Circle组件为食物成分表添加圆形标签,以及使用Path组件结合SVG命令绘制自定义图形(如应用Logo)。动画效果部分则展示了如何利用animateTo实现闪屏动画,包括渐出、放大效果,并设置页面跳转;同时介绍了页面间共享元素转场动画的实现方式。最后,文章列举了声明式开发范式中的各类组件及其功能,帮助开发者快速上手构建复杂交互页面。
509 11
|
11月前
|
存储 开发者 容器
鸿蒙 HarmonyOS NEXT星河版APP应用开发-ArkTS面向对象及组件化UI开发使用实例
本文介绍了ArkTS语言中的Class类、泛型、接口、模块化、自定义组件及状态管理等核心概念,并结合代码示例讲解了对象属性、构造方法、继承、静态成员、访问修饰符等内容,同时涵盖了路由管理、生命周期和Stage模型等应用开发关键知识点。
708 1
鸿蒙 HarmonyOS NEXT星河版APP应用开发-ArkTS面向对象及组件化UI开发使用实例
|
前端开发 安全 开发工具
【11】flutter进行了聊天页面的开发-增加了即时通讯聊天的整体页面和组件-切换-朋友-陌生人-vip开通详细页面-即时通讯sdk准备-直播sdk准备-即时通讯有无UI集成的区别介绍-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
【11】flutter进行了聊天页面的开发-增加了即时通讯聊天的整体页面和组件-切换-朋友-陌生人-vip开通详细页面-即时通讯sdk准备-直播sdk准备-即时通讯有无UI集成的区别介绍-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
1154 90
【11】flutter进行了聊天页面的开发-增加了即时通讯聊天的整体页面和组件-切换-朋友-陌生人-vip开通详细页面-即时通讯sdk准备-直播sdk准备-即时通讯有无UI集成的区别介绍-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
|
JavaScript 前端开发 UED
【HarmonyOS Next之旅】基于ArkTS开发(二) -> UI开发四
本文介绍了Web组件开发与性能优化的相关内容。在Web组件开发部分,涵盖创建组件、设置样式与属性、添加事件和方法以及场景示例,如动态播放视频。性能提升方面,推荐使用数据懒加载、条件渲染替代显隐控制、Column/Row替代Flex、设置List组件宽高及调整cachedCount减少滑动白块等方法,以优化应用性能与用户体验。
405 56

热门文章

最新文章