vue3+howler.js实现音频播放,兼容大多数音频格式
howler.js中文网址:http://www.npmdoc.org/howlerzhongwenwendanghowler-jszhongwenjiaochengjiexi.htmlhowler.js官网:https://howlerjs.com/本例子使用技术如下:Vue3+Ant Design Vue+howler实现音频播放对话框howler安装:npm i howler实现效果如下:代
·
howler.js中文网址:http://www.npmdoc.org/howlerzhongwenwendanghowler-jszhongwenjiaochengjiexi.html
howler.js官网:
本例子使用技术如下:
Vue3+Ant Design Vue+howler
实现音频播放对话框
howler安装:npm i howler
实现效果如下:
代码如下:
<template>
<a-modal v-model:visible="visible" :footer="null" destroyOnClose closable>
<div class="audio-top">
<span class="audio-top-time">{{startTime}}</span>
<a-slider v-model:value="value" :tip-formatter="formatter"
@change="timeChange" />
<span class="audio-top-time">{{endTime}}</span>
</div>
<div class="audio-buttom">
<div class="audio-buttom-btn">
<a-button type="primary" shape="circle" @click="backUp">
<template #icon> <FastBackwardFilled :style="{fontSize:'20px'}"/></template>
</a-button>
<a-button v-if="!playing" type="primary" shape="circle" @click="play">
<template #icon> <CaretRightOutlined :style="{fontSize:'20px'}"/></template>
</a-button>
<a-button v-if="playing" type="primary" shape="circle" @click="pause">
<template #icon> <PauseOutlined :style="{fontSize:'20px'}"/></template>
</a-button>
<a-button type="primary" shape="circle" @click="advance">
<template #icon> <FastForwardFilled :style="{fontSize:'20px'}"/></template>
</a-button>
</div>
<a-slider v-model:value="volume" @change="volumeChange"/>
</div>
</a-modal>
</template>
<script>
import { Modal, Slider } from 'ant-design-vue';
import {
reactive, toRefs, watch, ref,
} from 'vue';
import {
FastBackwardFilled, CaretRightOutlined, FastForwardFilled, PauseOutlined,
} from '@ant-design/icons-vue';
import { Howl } from 'howler';
export default {
components: {
FastBackwardFilled,
CaretRightOutlined,
FastForwardFilled,
PauseOutlined,
[Modal.name]: Modal,
[Slider.name]: Slider,
},
setup() {
const state = reactive({
visible: false,
loading: false,
volume: 50,
loudness: 0.5, // 音量
audioSrc: [ // 播放列表
],
value: 0, // 播放进度条
playing: false, // 播放状态 false停止 true播放
startTime: '00.00', // 开始时间
endTime: '00.00', // 结束时间
});
const sound = ref();
// 分秒转化
const formatTime = (secs) => {
const minutes = Math.floor(secs / 60) || 0;
const seconds = Math.floor(secs - minutes * 60) || 0;
return `${minutes}:${seconds < 10 ? '0' : ''}${seconds}`;
};
// 计算出 当前进度条时间 以及进度条位置
const setTimerAndValue = () => {
const seek = sound.value.seek();
if (typeof seek === 'number') {
const startTimer = formatTime(Math.round(seek));
// eslint-disable-next-line no-underscore-dangle
const endTimer = formatTime(Math.round(sound.value._duration));
// eslint-disable-next-line no-underscore-dangle
state.value = Math.round((seek / sound.value._duration) * 100) || 0;
state.startTime = startTimer;
state.endTime = endTimer;
}
};
const step = () => {
setTimerAndValue();
requestAnimationFrame(step);
};
// 监听 对话框打开
watch(() => state.visible, (newValue) => {
if (newValue === true) {
state.playing = true;
sound.value.play();// 播放
} else {
state.playing = false;
sound.value.stop();// 结束
}
});
// 抽屉开启
const showModal = (e) => {
state.loading = true;
state.volume = 50;
state.loudness = 0.5;
state.audioSrc = e.audioSrc;
sound.value = new Howl({
src: state.audioSrc,
volume: state.loudness,
autoplay: true,
loop: true,
html5: true,
preload: true,
onplay: onplay = () => {
step();
},
});
state.visible = true;
};
// 播放
const play = () => { state.playing = true; sound.value.play(); };
// 暂停
const pause = () => { state.playing = false; sound.value.pause(); step(); };
// 前进
// eslint-disable-next-line no-underscore-dangle
const advance = () => { sound.value.seek(sound.value._duration * (state.value / 100) + 5); };
// 后退
// eslint-disable-next-line no-underscore-dangle
const backUp = () => { sound.value.seek(sound.value._duration * (state.value / 100) - 5); };
// 音量设置
const volumeChange = (e) => { sound.value.volume(e * 0.01); };
// 时间进度条变化事件
// eslint-disable-next-line no-underscore-dangle
const timeChange = (e) => { sound.value.seek((sound.value._duration * e) / 100); };
// 时间进度条提示
// eslint-disable-next-line no-underscore-dangle
const formatter = (value) => formatTime((value / 100) * sound.value._duration);
return {
...toRefs(state),
sound,
showModal,
formatter,
formatTime,
play,
pause,
advance,
backUp,
volumeChange,
setTimerAndValue,
timeChange,
};
},
};
</script>
<style lang="less" scoped>
.audio-buttom{
display: flex;
justify-content: space-between;
align-items: center;
:deep(.ant-slider){
width: 300px;
}
&-btn{
width: 120px;
display: flex;
justify-content: space-around;
}
}
.audio-top{
display: flex;
justify-content: space-around;
align-items: center;
&-time{
width: 40px;
}
:deep(.ant-slider){
width: 100%;
}
}
</style>
更多推荐
已为社区贡献6条内容
所有评论(0)