feat(Player): 替换暂停图标为音频可视化效果

在播放按钮中,将原有的暂停图标替换为音频可视化效果,提升用户交互体验。同时,在音频可视化工具中新增了响度门槛和最小高度配置,优化了频段范围和增强逻辑。
This commit is contained in:
Astrian Zheng 2025-05-25 21:44:07 +10:00
parent 427fc5905c
commit e9c807e01b
Signed by: Astrian
SSH Key Fingerprint: SHA256:rVnhx3DAKjujCwWE13aDl7uV6+9U1MvydLkNRXJrBiA
2 changed files with 43 additions and 16 deletions

View File

@ -5,7 +5,6 @@ import { useTemplateRef, watch, nextTick } from 'vue'
import { useRoute } from 'vue-router'
import PlayIcon from '../assets/icons/play.vue'
import PauseIcon from '../assets/icons/pause.vue'
import LoadingIndicator from '../assets/icons/loadingindicator.vue'
import { audioVisualizer } from '../utils'
@ -183,12 +182,16 @@ watch(() => error.value, (newError) => {
</div>
</RouterLink>
<button class="h-9 w-9 flex justify-center items-center" @click.stop="() => {
<button class="h-9 w-12 flex justify-center items-center" @click.stop="() => {
playQueueStore.isPlaying = !playQueueStore.isPlaying
}">
<div v-if="playQueueStore.isPlaying">
<LoadingIndicator v-if="playQueueStore.isBuffering === true" :size="4" />
<PauseIcon v-else :size="4" />
<div v-else class="h-4 flex justify-center items-center gap-[.125rem]">
<div class="bg-white/75 w-[.125rem] rounded-full" v-for="(bar, index) in playQueueStore.visualizer" :key="index" :style="{
height: `${Math.max(10, bar)}%`
}" />
</div>
</div>
<PlayIcon v-else :size="4" />
</button>

View File

@ -9,6 +9,8 @@ interface AudioVisualizerOptions {
bassBoost?: number // 低音增强倍数 (默认 0.7,降低低音)
midBoost?: number // 中音增强倍数 (默认 1.2)
trebleBoost?: number // 高音增强倍数 (默认 1.5)
threshold?: number // 响度门槛 (0-255默认 15)
minHeight?: number // 最小高度百分比 (默认 0)
}
export function audioVisualizer(options: AudioVisualizerOptions = {}) {
@ -19,7 +21,9 @@ export function audioVisualizer(options: AudioVisualizerOptions = {}) {
debug = false,
bassBoost = 0.7, // 降低低音权重
midBoost = 1.2, // 提升中音
trebleBoost = 1.5 // 提升高音
trebleBoost = 1.5, // 提升高音
threshold = 0, // 响度门槛,低于此值不产生波动
minHeight = 0 // 最小高度百分比
} = options
console.log('[AudioVisualizer] 初始化平衡频谱,选项:', options)
@ -86,7 +90,7 @@ export function audioVisualizer(options: AudioVisualizerOptions = {}) {
analyser.fftSize = 2048 // 增加分辨率
analyser.smoothingTimeConstant = smoothing
analyser.minDecibels = -100 // 更低的最小分贝
analyser.maxDecibels = -30 // 调整最大分贝范围
analyser.maxDecibels = -10 // 调整最大分贝范围
log('分析器配置:', {
fftSize: analyser.fftSize,
@ -164,9 +168,11 @@ export function audioVisualizer(options: AudioVisualizerOptions = {}) {
// 定义人耳感知的频率范围 (Hz)
const frequencyRanges = [
{ min: 20, max: 250, name: '低音' }, // 低音
{ min: 250, max: 2000, name: '中低音' }, // 中低音
{ min: 2000, max: 8000, name: '中高音' }, // 中高音
{ min: 20, max: 150, name: '超低音' }, // 超低音
{ min: 150, max: 400, name: '低音' }, // 低音
{ min: 400, max: 1500, name: '中低音' }, // 中低音
{ min: 1500, max: 4000, name: '中音' }, // 中音
{ min: 4000, max: 8000, name: '中高音' }, // 中高音
{ min: 8000, max: 20000, name: '高音' } // 高音
]
@ -202,18 +208,26 @@ export function audioVisualizer(options: AudioVisualizerOptions = {}) {
return result
}
// 应用频段特定的增强
// 应用频段特定的增强和门槛
function applyFrequencyEnhancement(bands: number[]): number[] {
const boosts = [bassBoost, midBoost, trebleBoost, trebleBoost]
return bands.map((value, index) => {
// 应用响度门槛
if (value < threshold) {
if (debug && Math.random() < 0.01) {
log(`频段 ${index} 低于门槛: ${Math.round(value)} < ${threshold}`)
}
return minHeight * 255 / 100 // 返回最小高度对应的值
}
const boost = boosts[index] || 1
let enhanced = value * boost
// 应用压缩曲线,防止过度增强
enhanced = 255 * Math.tanh(enhanced / 255)
return Math.min(255, Math.max(0, enhanced))
return Math.min(255, Math.max(threshold, enhanced))
})
}
@ -303,12 +317,21 @@ export function audioVisualizer(options: AudioVisualizerOptions = {}) {
}, 100)
}
// 动态调整增强参数
function updateEnhancement(bass: number, mid: number, treble: number) {
// 动态调整增强参数和门槛
function updateEnhancement(bass: number, mid: number, treble: number, newThreshold?: number) {
options.bassBoost = bass
options.midBoost = mid
options.trebleBoost = treble
log('更新频段增强:', { bass, mid, treble })
if (newThreshold !== undefined) {
options.threshold = newThreshold
}
log('更新频段增强:', { bass, mid, treble, threshold: options.threshold })
}
// 设置响度门槛
function setThreshold(newThreshold: number) {
options.threshold = Math.max(0, Math.min(255, newThreshold))
log('更新响度门槛:', options.threshold)
}
// 组件卸载时清理
@ -326,6 +349,7 @@ export function audioVisualizer(options: AudioVisualizerOptions = {}) {
startAnalysis,
stopAnalysis,
testWithFakeData,
updateEnhancement
updateEnhancement,
setThreshold
}
}