Vue3与uniapp中如何实现声音播放
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
共有五种状态,如下表所示:
Constant | Value | Description |
---|---|---|
HAVE_NOTHING | 0 | 没有关于音频/视频是否就绪的信息 |
HAVE_METADATA | 1 | 音频/视频已初始化 |
HAVE_CURRENT_DATA | 2 | 数据已经可以播放 (当前位置已经加载) 但没有数据能播放下一帧的内容 |
HAVE_FUTURE_DATA | 3 | 当前及至少下一帧的数据是可用的 (换句话来说至少有两帧的数据) |
HAVE_ENOUGH_DATA | 4 | 可用数据足以开始播放 - 如果网速得到保障 那么视频可以一直播放到底 |
//通过判断音频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 项目中,音频文件通常放在 public
或 src/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
提供的相关方法,如play
、pause
、stop
等。
注意事项:
如果出现播放声音失败的情况,先检查一下音频是否导入,或者换成import导入音频
import mp3 from "/static/audio/message.mp3"
或者换成import导入音频
import mp3 from "/static/audio/message.mp3"
然后再检查一下设备声音是否开启,音频播放是否跟随设备开关开启,打开这个功能后应该就没问题了。
更多推荐
所有评论(0)