Vue 使用Audio或AudioContext播放本地音频

使用Audio 第一种 使用标签方式
复制代码
    <audio src="./tests.mp3" ref="audio"></audio>
    <el-button @click="audioPlay()">播放Audio</el-button>
    audioPlay() {
      this.$refs.audio.currentTime = 0;
      this.$refs.audio.play();
      // this.$refs.audio.pause(); //暂停
    },
使用Audio 第二种 利用js构建Audio对象
复制代码
audioJs() {
    var audio = new Audio();
    var url = require("./tests.mp3");
    audio.src = url;
    // audio.loop = true; //设置循环播放
    audio.play();
    // audio.pause(); //暂停
},
使用AudioContext播放
复制代码
<template>
  <div>
    <el-button @click="playAudio()" v-show="!hasPlay">播放</el-button>
    <el-button @click="resumeAudio()" v-show="hasPlay">{{
      isPause ? "继续" : "暂停"
    }}</el-button>
    <el-button @click="stopAudio()" v-show="hasPlay">结束</el-button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      ctx: null,
      source: null,
      loop: false, //是否循环
      hasPlay: false, //是否播放 助变量 可忽略辅
      isPause: false, //是否暂停 助变量 可忽略辅
    };
  },
  methods: {
    // 播放
    async playAudio() {
      this.ctx = new (window.AudioContext || window.webkitAudioContext())();
      this.source = this.ctx.createBufferSource(); // 创建音频源头姐点
      const audioBuffer = await this.loadAudio();
      this.playSound(audioBuffer);
    },
    async loadAudio() {
      // const audioUrl = require("./test.mp3");
      const audioUrl = require("./tests.mp3");
      const res = await fetch(audioUrl);
      const arrayBuffer = await res.arrayBuffer(); // byte array字节数组
      const audioBuffer = await this.ctx.decodeAudioData(
        arrayBuffer,
        function (decodeData) {
          return decodeData;
        }
      );
      return audioBuffer;
    },
    async playSound(audioBuffer) {
      this.source.buffer = audioBuffer; // 设置数据
      this.source.loop = this.loop; //设置,循环播放
      this.source.connect(this.ctx.destination); // 头尾相连
      // 可以对音频做任何控制
      this.source.start(0); //立即播放
      this.hasPlay = true;
    },
    // 暂停
    async resumeAudio() {
      if (this.ctx.state === "running") {
        this.ctx.suspend();
        this.isPause = true;
      } else if (this.ctx.state === "suspended") {
        this.ctx.resume();
        this.isPause = false;
      }
    },
    // 结束
    async stopAudio() {
      this.source.stop();
      this.hasPlay = false;
      this.isPause = false;
    },
  },
};
</script>
需要注意的是,以谷歌播放器为例,用户还没有跟document产生交互时,不允许播放器执行播放操作的,具体解决方案可另行查询,这边建议做一个类似弹窗的东西,引导用户产生交互动作。以上三个例子均由点击事件触发播放,因此不存在上述问题。
相关推荐
卸任10 小时前
Vibe coding工具使用心得
前端·ai编程
brien910 小时前
为什么模型标称 1M,Google Antigravity 聊到 256K 却突然失忆?我们给它做了个原生行内监控圆环
前端
修炼的dance11 小时前
录屏关键帧间隔多少合适?六档实测,2秒到10秒小了75.6%
前端
Lank_M11 小时前
关键帧从1秒拉到10秒,录屏小87.3%,摄像头小10.8%
前端
补码缩写11 小时前
用 ffprobe 拆录屏,八成字节在 29 个关键帧上
前端
百思不得小李11 小时前
一个复杂的动态表单是如何实现的
前端·设计模式
陈随易11 小时前
Cmder 停更 17 个月,2.0 支持 Windows Terminal
前端·后端·程序员
风骏时光牛马11 小时前
前沿视界
前端
kyriewen11 小时前
我扫了 814 个依赖,97 个还敢要 Node 10
前端·javascript·程序员
陈随易12 小时前
3000 万人在用的翻译插件,重写一遍就是一门生意
前端·后端·程序员