mirror of
https://github.com/algerkong/AlgerMusicPlayer.git
synced 2026-04-03 14:20:50 +08:00
@@ -58,7 +58,8 @@ export default {
|
||||
next: 'Next',
|
||||
volume: 'Volume',
|
||||
favorite: 'Favorite {name}',
|
||||
unFavorite: 'Unfavorite {name}'
|
||||
unFavorite: 'Unfavorite {name}',
|
||||
playbackSpeed: 'Playback Speed'
|
||||
},
|
||||
eq: {
|
||||
title: 'Equalizer',
|
||||
|
||||
@@ -59,7 +59,8 @@ export default {
|
||||
volume: '音量',
|
||||
favorite: '已收藏{name}',
|
||||
unFavorite: '已取消收藏{name}',
|
||||
miniPlayBar: '迷你播放栏'
|
||||
miniPlayBar: '迷你播放栏',
|
||||
playbackSpeed: '播放速度'
|
||||
},
|
||||
eq: {
|
||||
title: '均衡器',
|
||||
|
||||
@@ -161,6 +161,23 @@
|
||||
</template>
|
||||
{{ t('player.playBar.playList') }}
|
||||
</n-tooltip>
|
||||
<!-- 添加播放速度控制按钮 -->
|
||||
<n-dropdown
|
||||
v-if="!isMobile"
|
||||
:options="playbackRateOptions"
|
||||
@select="handlePlaybackRateChange"
|
||||
trigger="click"
|
||||
:z-index="9999999"
|
||||
>
|
||||
<n-tooltip trigger="hover" :z-index="9999999">
|
||||
<template #trigger>
|
||||
<div class="play-speed">
|
||||
<span class="speed-button">{{ playbackRate }}x</span>
|
||||
</div>
|
||||
</template>
|
||||
{{ t('player.playBar.playbackSpeed') }}
|
||||
</n-tooltip>
|
||||
</n-dropdown>
|
||||
</div>
|
||||
<!-- 播放音乐 -->
|
||||
<music-full ref="MusicFullRef" v-model="musicFullVisible" :background="background" />
|
||||
@@ -319,6 +336,23 @@ const playModeText = computed(() => {
|
||||
}
|
||||
});
|
||||
|
||||
// 播放速度控制
|
||||
const playbackRate = ref(1.0);
|
||||
const playbackRateOptions = [
|
||||
{ label: '0.5x', key: 0.5 },
|
||||
{ label: '0.75x', key: 0.75 },
|
||||
{ label: '1.0x', key: 1.0 },
|
||||
{ label: '1.25x', key: 1.25 },
|
||||
{ label: '1.5x', key: 1.5 },
|
||||
{ label: '2.0x', key: 2.0 }
|
||||
];
|
||||
|
||||
|
||||
const handlePlaybackRateChange = (rate: number) => {
|
||||
playbackRate.value = rate;
|
||||
audioService.setPlaybackRate(rate);
|
||||
};
|
||||
|
||||
// 切换播放模式
|
||||
const togglePlayMode = () => {
|
||||
playerStore.togglePlayMode();
|
||||
@@ -702,4 +736,24 @@ const openPlayListDrawer = () => {
|
||||
color: white;
|
||||
animation: spin 1s linear infinite;
|
||||
}
|
||||
|
||||
.play-speed {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
padding: 0 8px;
|
||||
}
|
||||
|
||||
.speed-button {
|
||||
font-size: 14px;
|
||||
color: var(--text-color);
|
||||
padding: 4px 8px;
|
||||
border-radius: 4px;
|
||||
background: var(--hover-color);
|
||||
}
|
||||
|
||||
.speed-button:hover {
|
||||
background: var(--hover-color-dark);
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -18,6 +18,8 @@ class AudioService {
|
||||
|
||||
private bypass = false;
|
||||
|
||||
private playbackRate = 1.0; // 添加播放速度属性
|
||||
|
||||
// 预设的 EQ 频段
|
||||
private readonly frequencies = [31, 62, 125, 250, 500, 1000, 2000, 4000, 8000, 16000];
|
||||
|
||||
@@ -143,7 +145,7 @@ class AudioService {
|
||||
if ('setPositionState' in navigator.mediaSession) {
|
||||
navigator.mediaSession.setPositionState({
|
||||
duration: this.currentSound.duration(),
|
||||
playbackRate: 1.0,
|
||||
playbackRate: this.playbackRate,
|
||||
position: this.currentSound.seek() as number
|
||||
});
|
||||
}
|
||||
@@ -565,6 +567,7 @@ class AudioService {
|
||||
volume: localStorage.getItem('volume')
|
||||
? parseFloat(localStorage.getItem('volume') as string)
|
||||
: 1,
|
||||
rate: this.playbackRate, // 设置初始播放速度
|
||||
format: ['mp3', 'aac'],
|
||||
onloaderror: (_, error) => {
|
||||
console.error('Audio load error:', error);
|
||||
@@ -747,6 +750,35 @@ class AudioService {
|
||||
public setCurrentPreset(preset: string): void {
|
||||
localStorage.setItem('currentPreset', preset);
|
||||
}
|
||||
|
||||
public setPlaybackRate(rate: number) {
|
||||
if (!this.currentSound) return;
|
||||
this.playbackRate = rate;
|
||||
|
||||
// Howler 的 rate() 在 html5 模式下不生效
|
||||
this.currentSound.rate(rate);
|
||||
|
||||
// 取出底层 HTMLAudioElement,改原生 playbackRate
|
||||
const sounds = (this.currentSound as any)._sounds as any[];
|
||||
sounds.forEach(({ _node }) => {
|
||||
if (_node instanceof HTMLAudioElement) {
|
||||
_node.playbackRate = rate;
|
||||
}
|
||||
});
|
||||
|
||||
// 同步给 Media Session UI
|
||||
if ('mediaSession' in navigator && 'setPositionState' in navigator.mediaSession) {
|
||||
navigator.mediaSession.setPositionState({
|
||||
duration: this.currentSound.duration(),
|
||||
playbackRate: rate,
|
||||
position: this.currentSound.seek() as number
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public getPlaybackRate(): number {
|
||||
return this.playbackRate;
|
||||
}
|
||||
}
|
||||
|
||||
export const audioService = new AudioService();
|
||||
|
||||
@@ -399,6 +399,9 @@ export const usePlayerStore = defineStore('player', () => {
|
||||
value: 0
|
||||
}));
|
||||
|
||||
// 添加播放速度状态
|
||||
const playbackRate = ref(1.0);
|
||||
|
||||
// 清空播放列表
|
||||
const clearPlayAll = async () => {
|
||||
audioService.pause()
|
||||
@@ -1042,6 +1045,23 @@ export const usePlayerStore = defineStore('player', () => {
|
||||
setPlayList(newPlayList);
|
||||
};
|
||||
|
||||
// 设置播放速度
|
||||
const setPlaybackRate = (rate: number) => {
|
||||
playbackRate.value = rate;
|
||||
audioService.setPlaybackRate(rate);
|
||||
// 保存到本地存储
|
||||
localStorage.setItem('playbackRate', rate.toString());
|
||||
};
|
||||
|
||||
// 初始化播放速度
|
||||
const initializePlaybackRate = () => {
|
||||
const savedRate = localStorage.getItem('playbackRate');
|
||||
if (savedRate) {
|
||||
playbackRate.value = parseFloat(savedRate);
|
||||
audioService.setPlaybackRate(playbackRate.value);
|
||||
}
|
||||
};
|
||||
|
||||
// 初始化播放状态
|
||||
const initializePlayState = async () => {
|
||||
const settingStore = useSettingsStore();
|
||||
@@ -1093,6 +1113,7 @@ export const usePlayerStore = defineStore('player', () => {
|
||||
localStorage.removeItem('playProgress');
|
||||
}
|
||||
}
|
||||
initializePlaybackRate();
|
||||
};
|
||||
|
||||
const initializeFavoriteList = async () => {
|
||||
@@ -1343,6 +1364,8 @@ export const usePlayerStore = defineStore('player', () => {
|
||||
playAudio,
|
||||
reparseCurrentSong,
|
||||
setPlayListDrawerVisible,
|
||||
handlePause
|
||||
handlePause,
|
||||
playbackRate,
|
||||
setPlaybackRate
|
||||
};
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user