Merge pull request #320 from Hellodwadawd12312312/feature

修复音频初始化音量问题,完善翻译
This commit is contained in:
Alger
2025-06-17 11:34:26 +08:00
committed by GitHub
5 changed files with 101 additions and 56 deletions

View File

@@ -85,7 +85,7 @@ export default {
login: 'Login',
toLogin: 'To Login',
logout: 'Logout',
set: 'Set',
set: 'Settings',
theme: 'Theme',
restart: 'Restart',
refresh: 'Refresh',
@@ -180,5 +180,13 @@ export default {
clearTasksSuccess: 'Task list cleared',
clearTasksFailed: 'Failed to clear task list'
}
}
},
settings: 'Settings',
user: 'User',
toplist: 'Toplist',
history: 'History',
list: 'Playlist',
mv: 'MV',
home: 'Home',
search: 'Search'
};

View File

@@ -178,5 +178,13 @@ export default {
clearTasksSuccess: '任务列表已清除',
clearTasksFailed: '清除任务列表失败'
}
}
},
settings: '设置',
user: '用户',
toplist: '排行榜',
history: '收藏历史',
list: '歌单',
mv: 'MV',
home: '首页',
search: '搜索'
};

View File

@@ -13,11 +13,10 @@
<template #trigger>
<router-link class="app-menu-item-link" :to="item.path">
<i class="iconfont app-menu-item-icon" :style="iconStyle(index)" :class="item.meta.icon"></i>
<span v-if="isText" class="app-menu-item-text ml-3" :class="isChecked(index) ? 'text-green-500' : ''">{{
item.meta.title }}</span>
<span v-if="isText" class="app-menu-item-text ml-3" :class="isChecked(index) ? 'text-green-500' : ''">{{ t(item.meta.title) }}</span>
</router-link>
</template>
<div v-if="!isText">{{ item.meta.title }}</div>
<div v-if="!isText">{{ t(item.meta.title) }}</div>
</n-tooltip>
</div>
</div>
@@ -28,6 +27,7 @@
<script lang="ts" setup>
import { useRoute } from 'vue-router';
import { ref, watch } from 'vue';
import { useI18n } from 'vue-i18n';
import icon from '@/assets/icon.png';
@@ -59,6 +59,8 @@ watch(
}
);
const { t } = useI18n();
const isChecked = (index: number) => {
return path.value === props.menus[index].path;
};

View File

@@ -3,7 +3,7 @@ const layoutRouter = [
path: '/',
name: 'home',
meta: {
title: '首页',
title: 'comp.home',
icon: 'icon-Home',
keepAlive: true,
isMobile: true
@@ -14,7 +14,7 @@ const layoutRouter = [
path: '/search',
name: 'search',
meta: {
title: '搜索',
title: 'comp.search',
noScroll: true,
icon: 'icon-Search',
keepAlive: true,
@@ -26,7 +26,7 @@ const layoutRouter = [
path: '/list',
name: 'list',
meta: {
title: '歌单',
title: 'comp.list',
icon: 'icon-Paper',
keepAlive: true,
isMobile: true
@@ -37,7 +37,7 @@ const layoutRouter = [
path: '/toplist',
name: 'toplist',
meta: {
title: '排行榜',
title: 'comp.toplist',
icon: 'ri-bar-chart-grouped-fill',
keepAlive: true,
isMobile: true
@@ -48,7 +48,7 @@ const layoutRouter = [
path: '/mv',
name: 'mv',
meta: {
title: 'MV',
title: 'comp.mv',
icon: 'icon-recordfill',
keepAlive: true,
isMobile: false
@@ -60,7 +60,7 @@ const layoutRouter = [
name: 'history',
component: () => import('@/views/historyAndFavorite/index.vue'),
meta: {
title: '收藏历史',
title: 'comp.history',
icon: 'icon-a-TicketStar',
keepAlive: true
}
@@ -69,7 +69,7 @@ const layoutRouter = [
path: '/user',
name: 'user',
meta: {
title: '用户',
title: 'comp.user',
icon: 'icon-Profile',
keepAlive: true,
noScroll: true,
@@ -81,7 +81,7 @@ const layoutRouter = [
path: '/set',
name: 'set',
meta: {
title: '设置',
title: 'comp.settings',
icon: 'ri-settings-3-fill',
keepAlive: true,
noScroll: true,

View File

@@ -330,15 +330,17 @@ class AudioService {
// 应用EQ状态
this.applyBypassState();
// 设置音量
const volume = localStorage.getItem('volume');
if (this.gainNode) {
this.gainNode.gain.value = volume ? parseFloat(volume) : 1;
// 从 localStorage 应用音量到增益节点
const savedVolume = localStorage.getItem('volume');
if (savedVolume) {
this.applyVolume(parseFloat(savedVolume));
} else {
this.applyVolume(1);
}
console.log('EQ初始化成功');
console.log('EQ initialization successful');
} catch (error) {
console.error('EQ初始化失败:', error);
console.error('EQ initialization failed:', error);
await this.disposeEQ();
throw error;
}
@@ -563,11 +565,9 @@ class AudioService {
this.currentSound = new Howl({
src: [url],
html5: true,
autoplay: false, // 修改为 false不自动播放等待完全初始化后手动播放
volume: localStorage.getItem('volume')
? parseFloat(localStorage.getItem('volume') as string)
: 1,
rate: this.playbackRate, // 设置初始播放速度
autoplay: false,
volume: 1, // 禁用 Howler.js 音量控制
rate: this.playbackRate,
format: ['mp3', 'aac'],
onloaderror: (_, error) => {
console.error('Audio load error:', error);
@@ -596,34 +596,43 @@ class AudioService {
}
},
onload: async () => {
// 音频加载成功后设置 EQ 和更新媒体会话
if (this.currentSound) {
try {
if (seekTime > 0) {
this.currentSound.seek(seekTime);
}
console.log('audioService: 音频加载成功,设置 EQ');
await this.setupEQ(this.currentSound);
this.updateMediaSessionMetadata(track);
this.updateMediaSessionPositionState();
this.emit('load');
// 此时音频已完全初始化,根据 isPlay 参数决定是否播放
console.log('audioService: 音频完全初始化isPlay =', isPlay);
if (isPlay) {
console.log('audioService: 开始播放');
this.currentSound.play();
}
resolve(this.currentSound);
} catch (error) {
console.error('设置 EQ 失败:', error);
// 即使 EQ 设置失败,也继续播放(如果需要)
if (isPlay) {
this.currentSound.play();
}
resolve(this.currentSound);
try {
// 初始化音频管道
await this.setupEQ(this.currentSound!);
// 重新应用已保存的音量
const savedVolume = localStorage.getItem('volume');
if (savedVolume) {
this.applyVolume(parseFloat(savedVolume));
}
// 音频加载成功后设置 EQ 和更新媒体会话
if (this.currentSound) {
try {
if (seekTime > 0) {
this.currentSound.seek(seekTime);
}
console.log('audioService: 音频加载成功,设置 EQ');
this.updateMediaSessionMetadata(track);
this.updateMediaSessionPositionState();
this.emit('load');
// 此时音频已完全初始化,根据 isPlay 参数决定是否播放
console.log('audioService: 音频完全初始化isPlay =', isPlay);
if (isPlay) {
console.log('audioService: 开始播放');
this.currentSound.play();
}
resolve(this.currentSound);
} catch (error) {
console.error('Audio initialization failed:', error);
reject(error);
}
}
} catch (error) {
console.error('Audio initialization failed:', error);
reject(error);
}
}
});
@@ -702,10 +711,7 @@ class AudioService {
}
setVolume(volume: number) {
if (this.currentSound) {
this.currentSound.volume(volume);
localStorage.setItem('volume', volume.toString());
}
this.applyVolume(volume);
}
seek(time: number) {
@@ -782,6 +788,27 @@ class AudioService {
public getPlaybackRate(): number {
return this.playbackRate;
}
// 新的音量调节方法
private applyVolume(volume: number) {
// 确保值在0到1之间
const normalizedVolume = Math.max(0, Math.min(1, volume));
// 使用线性缩放音量
const linearVolume = normalizedVolume;
// 将音量应用到所有相关节点
if (this.gainNode) {
// 立即设置音量
this.gainNode.gain.cancelScheduledValues(this.context!.currentTime);
this.gainNode.gain.setValueAtTime(linearVolume, this.context!.currentTime);
}
// 保存值
localStorage.setItem('volume', linearVolume.toString());
console.log('Volume applied (linear):', linearVolume);
}
}
export const audioService = new AudioService();