howlwer插件官网的地址:有兴趣的可以看一看,根据你的需求查找其中的配置项
一般音频需求可能如下:
- 能够自动/手动播放
- 可以调节音频的音量🔊
- 可以自由拖动进行播放
关于howlwe插件的基础配置如下:
javascript
import {Howl, Howler} from 'howler';
var sound = new Howl({
src: ['sound.webm'],//音频地址
autoplay: true,// 是否自动播放
loop: true, // 是否循环
format:['mp3'], // 音频解析的格式
volume: 0.5, // 音量的大小
onload:()=>{ // 音频加载完成时触发
console.log('success')
},
onplayerror:(error)=>{ // 音频报错触发
console.log(error)
}
onend: function() { // 音频播放完成时触发
console.log('Finished!');
},
});
一定要触发onload回调
onload的触发前提条件是你的音频是加载完成的,不然的话你后续在拖动播放的时候就出现拖动播放问题 ,你的音频的地址可能会出现如下情况:
1.音频需要下载(不推荐这个)
如果你的音频地址放在浏览上是直接下载一个音频文件,那不建议你用这个,因为这个一般触发不了onload,触发不了onload就会在拖动的时候出现问题(你拖动到十分钟以后,但是你的音频位置还是从你拖动前的位置播放) ,解决方式就是要利用 URL.createObjectURL()
生成音频临时播放地址
举例如下(以v3为例):
xml
<template>
<div class="audio-player">
<button @click="handleLoadAudio" :disabled="isLoading">
{{ isLoading ? '加载中...' : '加载音频' }}
</button>
<button @click="playAudio" :disabled="!soundInstance || isLoading">播放</button>
<button @click="pauseAudio" :disabled="!soundInstance || isLoading">暂停</button>
<button @click="cleanup" :disabled="!soundInstance || isLoading">清理资源</button>
<p v-if="errorMessage" class="error-text">{{ errorMessage }}</p>
</div>
</template>
<script setup>
import { Howl } from 'howler';
import { ref, onUnmounted } from 'vue';
// 状态管理
const soundInstance = ref(null);
const tempAudioUrl = ref('');
const isLoading = ref(false);
const errorMessage = ref('');
// 音频地址(实际使用时替换)
const audioSourceUrl = 'https://example.com/audio/sample.mp3';
/**
* 清理资源
*/
const cleanup = () => {
// 销毁Howler实例
if (soundInstance.value) {
soundInstance.value.stop();
soundInstance.value.unload();
soundInstance.value = null;
}
// 释放临时URL
if (tempAudioUrl.value) {
URL.revokeObjectURL(tempAudioUrl.value);
tempAudioUrl.value = '';
}
errorMessage.value = '';
};
/**
* 下载音频并创建临时播放地址
*/
const handleLoadAudio = async () => {
// 重置状态
cleanup();
isLoading.value = true;
errorMessage.value = '';
try {
// 1. 下载音频文件
const response = await fetch(audioSourceUrl, {
headers: { 'Accept': 'audio/*' }
});
if (!response.ok) {
throw new Error(`下载失败: ${response.status} ${response.statusText}`);
}
// 2. 转换为Blob对象
const audioBlob = await response.blob();
if (!audioBlob.type.startsWith('audio/')) {
throw new Error(`无效音频格式: ${audioBlob.type}`);
}
// 3. 创建临时URL
const tempUrl = URL.createObjectURL(audioBlob);
tempAudioUrl.value = tempUrl;
// 4. 初始化Howler
soundInstance.value = new Howl({
src: [tempUrl],
format: ['mp3'],
autoplay: false,
loop: false,
volume: 0.6,
onload: () => {
console.log('音频加载完成');
isLoading.value = false;
},
onplayerror: (err) => {
errorMessage.value = `播放错误: ${err}`;
isLoading.value = false;
},
onend: () => {
console.log('播放结束');
}
});
} catch (err) {
errorMessage.value = err.message;
isLoading.value = false;
}
};
/**
* 播放音频
*/
const playAudio = () => {
if (soundInstance.value && !soundInstance.value.playing()) {
soundInstance.value.play();
}
};
/**
* 暂停音频
*/
const pauseAudio = () => {
if (soundInstance.value && soundInstance.value.playing()) {
soundInstance.value.pause();
}
};
// 组件卸载时清理资源
onUnmounted(cleanup);
</script>
<style scoped>
.audio-player {
display: flex;
gap: 12px;
padding: 20px;
flex-wrap: wrap;
}
button {
padding: 8px 16px;
cursor: pointer;
background: #42b983;
color: white;
border: none;
border-radius: 4px;
transition: background 0.3s;
}
button:disabled {
background: #cccccc;
cursor: not-allowed;
}
.error-text {
color: #ff4d4f;
margin-top: 12px;
width: 100%;
}
</style>
这个时候你就可以看到在你使用临时生成的地址后你就有百分之50的可能性成功的触发onload ,另外的百分之50就要看音频格式啦
在移动端各家厂商的录音格式是不尽相同的:小米 华为 oppo vivo 这些基本上录音的格式都不太相同。
常见的音频格式如下:
- mp3
- wav
- m4a
- amr
所以我们还要正确的配置选项format
less
src: [tempUrl],
format: ['mp3','m4a','wav','amr'],
autoplay: false,
loop: false,
volume: 0.6,
当然音频格式不止这些,根据你的实际项目情况来就好啦。
2.音频可以在线播放(推荐这个)
这个非常推荐使用,这个可以轻松触发onlad,你可以自由的滑动播放。
拖动播放与seek的异步性
如果拖动完成后立即调用了play去进行播放,但是播放的时候确是你拖动之前的位置,这是因为你拖动的位置尚未缓冲到。
解决方式如下:
- 严格等待
seek()
完成后再播放(关键)
howler
的 seek()
是异步操作(即使音频已加载),必须在其完成后调用 play()
。通过 seek()
返回的 Promise 或 seek
事件确保时序:
javascript
scss
// 拖动进度回调
function handleSeek(newTime) {
// 等待 seek 完成后再播放
sound.seek(newTime).then(() => {
sound.play();
});
}
// 或监听 seek 事件(兼容旧版本)
sound.on('seek', () => {
sound.play(); // 定位完成后自动播放
});
- 检查拖动位置是否已缓冲
即使 onload
触发,拖动到未缓冲的区域仍需等待缓冲。可通过 howler
的 state()
或 buffered()
检查:
javascript
scss
function handleSeek(newTime) {
// 检查当前位置是否已缓冲
const buffered = sound.buffered(); // 返回已缓冲的时间范围数组
const isBuffered = buffered.some(range => range[0] <= newTime && newTime <= range[1]);
if (isBuffered) {
sound.seek(newTime).then(() => sound.play());
} else {
// 未缓冲:先缓冲再播放(可加 loading 提示)
sound.seek(newTime);
sound.once('buffer', () => sound.play()); // 监听缓冲事件
}
}
当然项目中遇到的问题是多种多样的,你可以回调官网提供的onplayerror去查看出现的问题,逐步的去解决。