音频播放组件:音量控制&循环播放&速率控制交互设计
概述
本节实现音频播放器的音量控制(Slider)、循环播放和速率控制三个核心交互功能,复用 ProgressBar 组件作为基础滑块控件。
音量控制
音量滑块组件
复用进度条组件 ProgressBar,通过 v-model 绑定 0-1 之间的音量值:
<template>
<div class="volume-control">
<el-icon class="volume-icon" @click="toggleMute">
<component :is="volumeIcon" />
</el-icon>
<ProgressBar
v-model="volumePercent"
:duration="1"
:current-time="volumePercent"
class="volume-slider"
/>
</div>
</template>
<script setup lang="ts">
import { computed } from 'vue'
import ProgressBar from './ProgressBar.vue'
interface Props {
modelValue: number // 0-1
muted: boolean
}
const props = defineProps<Props>()
const emit = defineEmits<{
'update:modelValue': [value: number]
'update:muted': [value: boolean]
}>()
const volumePercent = computed({
get: () => props.modelValue,
set: (val: number) => emit('update:modelValue', val)
})
const volumeIcon = computed(() => {
if (props.muted || props.modelValue === 0) return 'Mute'
if (props.modelValue < 0.5) return 'LowVolume'
return 'Microphone'
})
function toggleMute() {
emit('update:muted', !props.muted)
}
</script>
vue
循环播放控制
四种播放模式
| 模式 | 值 | 图标 | 行为 |
|---|---|---|---|
| 顺序播放 | 0 | ▶ | 播放完当前曲目后停止 |
| 列表循环 | 1 | 🔁 | 播放完最后一首后回到第一首 |
| 单曲循环 | 2 | 🔂 | 当前曲目循环播放 |
| 随机播放 | 3 | 🔀 | 随机选择下一首 |
循环模式切换组件
<template>
<el-icon class="loop-control" @click="toggleLoop">
<component :is="loopIcon" />
</el-icon>
</template>
<script setup lang="ts">
import { ref, computed } from 'vue'
const LOOP_ICONS = ['ArrowRight', 'Refresh', 'RefreshRight', 'Sort']
const LOOP_TIPS = ['顺序播放', '列表循环', '单曲循环', '随机播放']
const loopMode = ref(0) // 0: 顺序, 1: 列表循环, 2: 单曲循环, 3: 随机
const loopIcon = computed(() => LOOP_ICONS[loopMode.value])
const loopTip = computed(() => LOOP_TIPS[loopMode.value])
const emit = defineEmits<{
change: [mode: number]
}>()
function toggleLoop() {
loopMode.value = (loopMode.value + 1) % 4
emit('change', loopMode.value)
}
</script>
vue
速率控制
速率档位
| 速率 | 说明 | 适用场景 |
|---|---|---|
| 0.5x | 慢速 | 语言学习、会议记录 |
| 0.75x | 较慢 | 需要仔细听的内容 |
| 1.0x | 正常 | 默认 |
| 1.25x | 略快 | 常规加速 |
| 1.5x | 快速 | 播客/有声书 |
| 2.0x | 倍速 | 快速浏览 |
速率控制组件
<template>
<el-dropdown trigger="click" @command="handleRateChange">
<span class="rate-display">{{ currentRate }}x</span>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item
v-for="rate in RATES"
:key="rate"
:command="rate"
:class="{ 'is-active': rate === currentRate }"
>
{{ rate }}x
</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</template>
<script setup lang="ts">
import { ref } from 'vue'
const RATES = [0.5, 0.75, 1.0, 1.25, 1.5, 2.0]
interface Props {
modelValue: number
}
const props = defineProps<Props>()
const emit = defineEmits<{
'update:modelValue': [value: number]
}>()
const currentRate = ref(props.modelValue)
function handleRateChange(rate: number) {
currentRate.value = rate
emit('update:modelValue', rate)
}
</script>
vue
Howler.js API 调用映射
// 在 AudioPlayer 中连接 Howler.js API
function applyVolume(val: number) {
audioInstance.value?.volume(val)
}
function applyRate(val: number) {
audioInstance.value?.rate(val)
}
function applyLoop(mode: number) {
if (!audioInstance.value) return
switch (mode) {
case 0: // 顺序播放
audioInstance.value.loop(false)
break
case 1: // 列表循环(由上层逻辑处理)
audioInstance.value.loop(false)
break
case 2: // 单曲循环
audioInstance.value.loop(true)
break
case 3: // 随机播放(由上层逻辑处理)
audioInstance.value.loop(false)
break
}
}
typescript
小结
- 音量控制复用 ProgressBar 组件,通过 0-1 百分比值绑定
- 循环播放支持四种模式,通过点击图标循环切换
- 速率控制使用 Dropdown 组件,提供 6 档常用速率
- Howler.js 的
volume()、rate()、loop()方法分别对应三种控制
↑