Vue3与uniapp中如何实现声音播放

需求是要求在接口请求成功后发出提示音,请求失败发出报警的声音。下面介绍一下在VUE3和uniapp中如何实现播放音频。

一、Vue3播放音频

直接上代码

<template>
	<div>
        <audio ref="audio">
            <source src="/mp3/dingdong.mp3" type="audio/ogg" />
        </audio>
	</div>
</template>
<script lang="ts" setup name="audio">
    const audio = ref();
    const playSuccessVoice = () => {
		if (audio.value) {
	    	audio.value.play();
	  	}
	}
    //在接口请求成功后,调用playSuccessVoice()即可。
    //需要暂停,调用audio.value.pause()方法即可。
</script>

开发中需要注意一下几点:

1、音频文件形式

如果src是超链接的形式,则需要注意音频是否加载,可以通过以下几种方式确认

(1)添加监听事件

if (errorAudio.value) {
    //针对dom元素添加监听canplay或canplaythrough事件
    errorAudio.value.addEventListener('canplaythrough', () => {
      try {
        errorAudio.value.play().catch((error) => {
          console.error('音频播放失败:', error);
          // 根据错误类型决定是否需要重试或其他操作
        });
      } catch (error) {
        console.error('音频播放失败:', error);
      }
    });
    // 如果音频还没加载,可以在这里触发加载
    if (errorAudio.value.readyState === 0) {
      // 触发加载,例如设置src或利用preload属性
    }
  }

(2)判断媒体资源是否加载

通过判断媒体资源HTMLMediaElement中readyState的状态进行检测是否加载,readyState共有五种状态,如下表所示:

ConstantValueDescription
HAVE_NOTHING0没有关于音频/视频是否就绪的信息
HAVE_METADATA1音频/视频已初始化
HAVE_CURRENT_DATA2数据已经可以播放 (当前位置已经加载) 但没有数据能播放下一帧的内容
HAVE_FUTURE_DATA3当前及至少下一帧的数据是可用的 (换句话来说至少有两帧的数据)
HAVE_ENOUGH_DATA4可用数据足以开始播放 - 如果网速得到保障 那么视频可以一直播放到底
//通过判断音频dom的readyState属性
if (errorAudio.value.readyState >= 4) { // 4 表示已加载完成,可以播放
      try {
        await new Promise((resolve, reject) => {
          errorAudio.value.oncanplaythrough = resolve;
          errorAudio.value.onerror = reject;
        });
        errorAudio.value.play();
      } catch (error) {
        console.error('音频播放失败:', error);
      }
    } else {
      console.log('音频文件仍在加载中...');
      // 可以考虑在这里设置一个定时器或监听加载完成事件后再尝试播放
    }
2、媒体存放位置

如果src不是链接而是文件,需要注意音频文件的存放位置,在 Vue3 项目中,音频文件通常放在 publicsrc/assets 目录下,推荐放在public 文件夹下, 这样目录下的内容会直接映射到服务器的根目录,静态文件不会被解析。确保在项目中引用音频文件时,路径正确且符合 Vite 或 Webpack 等构建工具的路径处理规则。可以在 vite.config.js 中配置 assetsInclude,确保 .mp3 文件被正确处理和复制。如果位置存放错误,打包时会解析音频文件,出现如下问题。

在这里插入图片描述

3、动态配置音频

当使用动态绑定的src属性进行音频播放时,也需要确保src中的音频文件被正常的加载。Vue对数据变化的监听和更新有时可能会有细微的延迟,可以使用Vue的$nextTick来确保DOM已经更新后再执行播放操作。在vue3中需要引入nextTick方法实现在下一个渲染周期播放,上代码。

<source :src="state.audioSource" type="audio/mpeg">
import { nextTick, ref, onMounted } from 'vue';
export default {
  setup() {
    const errorAudio = ref(null);
    const state = reactive({
      audioSource: '/mp3/xxxxxx.mp3',
    });
    const playErrorVoice = async () => {
      // 确保DOM更新后再尝试播放
      await nextTick();
      if (errorAudio.value) {
        try {
          errorAudio.value.play();
        } catch (error) {
          console.error('音频播放失败:', error);
        }
      }
    };
    onMounted(() => {
      // 初始化逻辑可以放在这里,如果需要
    });
    return {
      errorAudio,
      playErrorVoice,
      state,
    };
  },
};

如果还存在无法播放的情况,可以尝试让audio标签执行load()方法,再一次手动加载音频资源。

errorAudio.value.load()
errorAudio.value.play()

二、Uniapp播放音频

在uniapp中播放音频,可以使用<audio>组件或者API uni.createInnerAudioContext。使用<audio>组件的例子:

官方文档

<template>
  <view>
    <audio src="/static/audio/message.mp3" controls="true"></audio>
  </view>
</template>

<script>
export default {
  methods: {
    playAudio() {
      const innerAudioContext = uni.createInnerAudioContext();
      innerAudioContext.autoplay = true;
      innerAudioContext.src = '/static/audio/message.mp3';
      innerAudioContext.onPlay(() => {
        console.log('开始播放');
      });
      innerAudioContext.onError((err) => {
        console.log(err);
      });
    }
  }
}
</script>

如果想要控制播放、暂停等,可以使用innerAudioContext提供的相关方法,如playpausestop等。

注意事项:

如果出现播放声音失败的情况,先检查一下音频是否导入,或者换成import导入音频

import mp3 from "/static/audio/message.mp3"

或者换成import导入音频

import mp3 from "/static/audio/message.mp3"

然后再检查一下设备声音是否开启,音频播放是否跟随设备开关开启,打开这个功能后应该就没问题了。

GitHub 加速计划 / vu / vue
207.54 K
33.66 K
下载
vuejs/vue: 是一个用于构建用户界面的 JavaScript 框架,具有简洁的语法和丰富的组件库,可以用于开发单页面应用程序和多页面应用程序。
最近提交(Master分支:2 个月前 )
73486cb5 * chore: fix link broken Signed-off-by: snoppy <michaleli@foxmail.com> * Update packages/template-compiler/README.md [skip ci] --------- Signed-off-by: snoppy <michaleli@foxmail.com> Co-authored-by: Eduardo San Martin Morote <posva@users.noreply.github.com> 4 个月前
e428d891 Updated Browser Compatibility reference. The previous currently returns HTTP 404. 5 个月前
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐