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

目录
相关文章
|
7月前
|
JavaScript 数据安全/隐私保护
Vue Amazing UI 组件库(Vue3+TypeScript+Vite 等最新技术栈开发)
Vue Amazing UI 是一个基于 Vue 3、TypeScript、Vite 等最新技术栈开发构建的现代化组件库,包含丰富的 UI 组件和常用工具函数,并且持续不断维护更新中。另外,组件库全量使用 TypeScript,支持自动按需引入和 Tree Shaking 等,能够显著提升开发效率,降低开发成本。
467 5
Vue Amazing UI 组件库(Vue3+TypeScript+Vite 等最新技术栈开发)
|
9月前
|
移动开发 前端开发 Java
Java最新图形化界面开发技术——JavaFx教程(含UI控件用法介绍、属性绑定、事件监听、FXML)
JavaFX是Java的下一代图形用户界面工具包。JavaFX是一组图形和媒体API,我们可以用它们来创建和部署富客户端应用程序。 JavaFX允许开发人员快速构建丰富的跨平台应用程序,允许开发人员在单个编程接口中组合图形,动画和UI控件。本文详细介绍了JavaFx的常见用法,相信读完本教程你一定有所收获!
8795 5
Java最新图形化界面开发技术——JavaFx教程(含UI控件用法介绍、属性绑定、事件监听、FXML)
Ant Design Vue UI框架的基础使用,及通用后台管理模板的小demo【简单】
这篇文章介绍了如何使用Ant Design Vue UI框架创建一个简单的后台管理模板,包括创建Vue项目、安装和使用ant-design-vue、以及编写后台管理通用页面的代码和样式。
Ant Design Vue UI框架的基础使用,及通用后台管理模板的小demo【简单】
|
11月前
|
JavaScript 索引
Vue开发中Element UI/Plus使用指南:常见问题(如Missing required prop: “value“)及中文全局组件配置解决方案
Vue开发中Element UI/Plus使用指南:常见问题(如Missing required prop: “value“)及中文全局组件配置解决方案
861 0
|
JavaScript 前端开发 安全
[译] 在 Vue 组件中分离 UI 和业务逻辑。
[译] 在 Vue 组件中分离 UI 和业务逻辑。
|
4月前
|
开发框架 前端开发 JavaScript
【HarmonyOS Next之旅】基于ArkTS开发(二) -> UI开发一
本文介绍了方舟开发框架(ArkUI)及其两种开发范式:基于ArkTS的声明式开发范式和类Web开发范式。ArkUI是用于构建HarmonyOS应用界面的UI框架,提供极简UI语法和基础设施。声明式开发范式使用ArkTS语言,以组件、动画和状态管理为核心,适合复杂团队协作;类Web开发范式采用HML、CSS、JavaScript三段式开发,适用于简单界面应用,贴近Web开发者习惯。文中还概述了两者的架构和基础能力,帮助开发者选择合适的范式进行高效开发。
160 15
|
4月前
|
编解码 前端开发 Java
【HarmonyOS Next之旅】基于ArkTS开发(二) -> UI开发三
本文介绍了基于声明式UI范式的图形绘制与动画效果实现方法,涵盖绘制图形、添加动画效果及常见组件说明三部分内容。在绘制图形部分,详细讲解了如何通过Circle组件为食物成分表添加圆形标签,以及使用Path组件结合SVG命令绘制自定义图形(如应用Logo)。动画效果部分则展示了如何利用animateTo实现闪屏动画,包括渐出、放大效果,并设置页面跳转;同时介绍了页面间共享元素转场动画的实现方式。最后,文章列举了声明式开发范式中的各类组件及其功能,帮助开发者快速上手构建复杂交互页面。
150 11
|
10天前
|
存储 开发者 容器
鸿蒙 HarmonyOS NEXT星河版APP应用开发-ArkTS面向对象及组件化UI开发使用实例
本文介绍了ArkTS语言中的Class类、泛型、接口、模块化、自定义组件及状态管理等核心概念,并结合代码示例讲解了对象属性、构造方法、继承、静态成员、访问修饰符等内容,同时涵盖了路由管理、生命周期和Stage模型等应用开发关键知识点。
103 0
鸿蒙 HarmonyOS NEXT星河版APP应用开发-ArkTS面向对象及组件化UI开发使用实例
|
3月前
|
JavaScript 前端开发 UED
【HarmonyOS Next之旅】基于ArkTS开发(二) -> UI开发四
本文介绍了Web组件开发与性能优化的相关内容。在Web组件开发部分,涵盖创建组件、设置样式与属性、添加事件和方法以及场景示例,如动态播放视频。性能提升方面,推荐使用数据懒加载、条件渲染替代显隐控制、Column/Row替代Flex、设置List组件宽高及调整cachedCount减少滑动白块等方法,以优化应用性能与用户体验。
174 56
|
3月前
|
编解码 UED 开发者
【HarmonyOS Next之旅】基于ArkTS开发(二) -> UI开发之常见布局
本文主要介绍了自适应布局与响应式布局的相关内容。自适应布局部分涵盖线性布局、层叠布局、弹性布局和网格布局,详细说明了各布局的特性及使用方法,例如线性布局中的排列、拉伸与缩放,弹性布局的方向、换行与对齐方式等。响应式布局则重点讲解了栅格系统和媒体查询,阐述如何通过栅格组件和媒体查询条件实现不同设备上的适配效果。这些技术帮助开发者灵活应对多尺寸屏幕的设计需求,提升用户体验。
204 55

热门文章

最新文章