mirror of
https://github.com/algerkong/AlgerMusicPlayer.git
synced 2026-04-05 07:20:50 +08:00
✨ feat: 优化音频监听器初始化和设置保存逻辑
- 在 App.vue 中引入 initAudioListeners 函数,确保在播放音乐时初始化音频监听器。 - 在 MusicHook.ts 中重构音频监听器的初始化逻辑,增加音频加载的超时处理。 - 在设置页面中实现防抖保存功能,避免频繁更新设置,提高性能和用户体验。 这些更改旨在提升音频播放的稳定性和设置管理的效率。
This commit is contained in:
@@ -12,7 +12,7 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import { darkTheme, lightTheme } from 'naive-ui';
|
||||
import { computed, onMounted, watch } from 'vue';
|
||||
import { computed, nextTick, watch } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
|
||||
import homeRouter from '@/router/home';
|
||||
@@ -21,6 +21,7 @@ import { usePlayerStore } from '@/store/modules/player';
|
||||
import { useSettingsStore } from '@/store/modules/settings';
|
||||
import { isElectron } from '@/utils';
|
||||
|
||||
import { initAudioListeners } from './hooks/MusicHook';
|
||||
import { isMobile } from './utils';
|
||||
|
||||
const { locale } = useI18n();
|
||||
@@ -61,18 +62,27 @@ const handleSetLanguage = (_: any, value: string) => {
|
||||
// settingsStore.setLanguage(value);
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
settingsStore.initializeSettings();
|
||||
handleSetLanguage(null, settingsStore.setData.language);
|
||||
settingsStore.initializeTheme();
|
||||
settingsStore.initializeSystemFonts();
|
||||
playerStore.initializePlayState();
|
||||
if (isMobile.value) {
|
||||
menuStore.setMenus(homeRouter.filter((item) => item.meta.isMobile));
|
||||
}
|
||||
settingsStore.initializeSettings();
|
||||
handleSetLanguage(null, settingsStore.setData.language);
|
||||
settingsStore.initializeTheme();
|
||||
settingsStore.initializeSystemFonts();
|
||||
if (isMobile.value) {
|
||||
menuStore.setMenus(homeRouter.filter((item) => item.meta.isMobile));
|
||||
}
|
||||
|
||||
if (isElectron) {
|
||||
window.electron.ipcRenderer.on('language-changed', handleSetLanguage);
|
||||
if (isElectron) {
|
||||
window.electron.ipcRenderer.on('language-changed', handleSetLanguage);
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
// 先初始化播放状态
|
||||
await playerStore.initializePlayState();
|
||||
|
||||
// 如果有正在播放的音乐,则初始化音频监听器
|
||||
if (playerStore.playMusic && playerStore.playMusic.id) {
|
||||
// 使用 nextTick 确保 DOM 更新后再初始化
|
||||
await nextTick();
|
||||
initAudioListeners();
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { createDiscreteApi } from 'naive-ui';
|
||||
import { computed, nextTick, onMounted, onUnmounted, ref, watch } from 'vue';
|
||||
import { computed, nextTick, onUnmounted, ref, watch } from 'vue';
|
||||
|
||||
import i18n from '@/../i18n/renderer';
|
||||
import useIndexedDB from '@/hooks/IndexDBHook';
|
||||
@@ -763,37 +763,74 @@ if (isElectron) {
|
||||
}
|
||||
|
||||
// 在组件挂载时设置监听器
|
||||
onMounted(() => {
|
||||
// 初始化音频监听器
|
||||
setupAudioListeners();
|
||||
|
||||
// 监听歌词窗口关闭事件
|
||||
if (isElectron) {
|
||||
window.api.onLyricWindowClosed(() => {
|
||||
isLyricWindowOpen.value = false;
|
||||
});
|
||||
}
|
||||
|
||||
// 检查是否需要初始化 sound 对象
|
||||
if (!sound.value && audioService.getCurrentSound()) {
|
||||
sound.value = audioService.getCurrentSound();
|
||||
|
||||
// 如果当前处于播放状态,启动进度更新
|
||||
if (playerStore.play && sound.value) {
|
||||
// 如果有保存的播放进度,应用它
|
||||
if (playerStore.savedPlayProgress !== undefined && sound.value) {
|
||||
try {
|
||||
// 设置音频位置
|
||||
sound.value.seek(playerStore.savedPlayProgress);
|
||||
// 同时更新时间显示,这样进度条也会更新
|
||||
nowTime.value = playerStore.savedPlayProgress;
|
||||
console.log('恢复播放进度:', playerStore.savedPlayProgress);
|
||||
} catch (e) {
|
||||
console.error('恢复播放进度失败:', e);
|
||||
}
|
||||
}
|
||||
|
||||
startProgressAnimation();
|
||||
export const initAudioListeners = async () => {
|
||||
try {
|
||||
// 确保有正在播放的音乐
|
||||
if (!playerStore.playMusic || !playerStore.playMusic.id) {
|
||||
console.log('没有正在播放的音乐,跳过音频监听器初始化');
|
||||
return;
|
||||
}
|
||||
|
||||
// 确保有音频实例
|
||||
const initialSound = audioService.getCurrentSound();
|
||||
if (!initialSound) {
|
||||
console.log('没有音频实例,等待音频加载...');
|
||||
// 等待音频加载完成
|
||||
await new Promise<void>((resolve) => {
|
||||
const checkInterval = setInterval(() => {
|
||||
const sound = audioService.getCurrentSound();
|
||||
if (sound) {
|
||||
clearInterval(checkInterval);
|
||||
resolve();
|
||||
}
|
||||
}, 100);
|
||||
|
||||
// 设置超时
|
||||
setTimeout(() => {
|
||||
clearInterval(checkInterval);
|
||||
console.log('等待音频加载超时');
|
||||
resolve();
|
||||
}, 5000);
|
||||
});
|
||||
}
|
||||
|
||||
// 初始化音频监听器
|
||||
setupAudioListeners();
|
||||
|
||||
// 监听歌词窗口关闭事件
|
||||
if (isElectron) {
|
||||
window.api.onLyricWindowClosed(() => {
|
||||
isLyricWindowOpen.value = false;
|
||||
});
|
||||
}
|
||||
|
||||
// 获取最新的音频实例
|
||||
const finalSound = audioService.getCurrentSound();
|
||||
if (finalSound) {
|
||||
// 更新全局 sound 引用
|
||||
sound.value = finalSound;
|
||||
|
||||
// 如果当前处于播放状态,启动进度更新
|
||||
if (playerStore.play) {
|
||||
// 如果有保存的播放进度,应用它
|
||||
if (playerStore.savedPlayProgress !== undefined) {
|
||||
try {
|
||||
// 设置音频位置
|
||||
finalSound.seek(playerStore.savedPlayProgress);
|
||||
// 同时更新时间显示
|
||||
nowTime.value = playerStore.savedPlayProgress;
|
||||
console.log('恢复播放进度:', playerStore.savedPlayProgress);
|
||||
} catch (e) {
|
||||
console.error('恢复播放进度失败:', e);
|
||||
}
|
||||
}
|
||||
|
||||
startProgressAnimation();
|
||||
}
|
||||
} else {
|
||||
console.warn('无法获取音频实例,跳过进度更新初始化');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('初始化音频监听器失败:', error);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
@@ -359,7 +359,7 @@ export const usePlayerStore = defineStore('player', () => {
|
||||
try {
|
||||
console.log('settingStore.setData', settingStore.setData);
|
||||
const isPlaying = settingStore.setData.autoPlay;
|
||||
await handlePlayMusic(savedPlayMusic, isPlaying);
|
||||
await handlePlayMusic({ ...savedPlayMusic, playMusicUrl: undefined }, isPlaying);
|
||||
|
||||
if (savedProgress) {
|
||||
try {
|
||||
|
||||
@@ -37,6 +37,7 @@ export const useSettingsStore = defineStore('settings', () => {
|
||||
|
||||
if (isElectron) {
|
||||
window.electron.ipcRenderer.send('set-store-value', 'set', cloneDeep(mergedData));
|
||||
console.log('mergedData', mergedData);
|
||||
setData.value = cloneDeep(mergedData);
|
||||
} else {
|
||||
localStorage.setItem('appSettings', JSON.stringify(cloneDeep(mergedData)));
|
||||
|
||||
@@ -461,9 +461,11 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useDebounceFn } from '@vueuse/core';
|
||||
import { debounce } from 'lodash';
|
||||
import type { FormRules } from 'naive-ui';
|
||||
import { useMessage } from 'naive-ui';
|
||||
import { computed, h, nextTick, onMounted, ref, watch } from 'vue';
|
||||
import { computed, h, nextTick, onMounted, onUnmounted, ref, watch } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
|
||||
import localData from '@/../main/set.json';
|
||||
@@ -483,6 +485,15 @@ import config from '../../../../package.json';
|
||||
const settingsStore = useSettingsStore();
|
||||
const userStore = useUserStore();
|
||||
|
||||
// 创建一个本地缓存的setData,避免频繁更新
|
||||
const localSetData = ref({ ...settingsStore.setData });
|
||||
|
||||
// 在组件卸载时保存设置
|
||||
onUnmounted(() => {
|
||||
// 确保最终设置被保存
|
||||
settingsStore.setSetData(localSetData.value);
|
||||
});
|
||||
|
||||
const checking = ref(false);
|
||||
const updateInfo = ref<UpdateResult>({
|
||||
hasUpdate: false,
|
||||
@@ -493,14 +504,44 @@ const updateInfo = ref<UpdateResult>({
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
// 创建一个防抖的保存函数
|
||||
// const debouncedSaveSettings = debounce((newData) => {
|
||||
// settingsStore.setSetData(newData);
|
||||
// }, 500);
|
||||
|
||||
const saveSettings = useDebounceFn((data) => {
|
||||
settingsStore.setSetData(data);
|
||||
}, 500);
|
||||
|
||||
// 使用计算属性来管理设置数据
|
||||
const setData = computed({
|
||||
get: () => settingsStore.setData,
|
||||
get: () => localSetData.value,
|
||||
set: (newData) => {
|
||||
settingsStore.setSetData(newData);
|
||||
localSetData.value = newData;
|
||||
}
|
||||
});
|
||||
|
||||
// 监听localSetData变化,保存设置
|
||||
watch(
|
||||
() => localSetData.value,
|
||||
(newValue) => {
|
||||
saveSettings(newValue);
|
||||
},
|
||||
{ deep: true }
|
||||
);
|
||||
|
||||
// 监听store中setData的变化,同步到本地
|
||||
watch(
|
||||
() => settingsStore.setData,
|
||||
(newValue) => {
|
||||
// 只在初始加载时更新本地数据,避免循环更新
|
||||
if (JSON.stringify(localSetData.value) !== JSON.stringify(newValue)) {
|
||||
localSetData.value = { ...newValue };
|
||||
}
|
||||
},
|
||||
{ deep: true, immediate: true }
|
||||
);
|
||||
|
||||
const isDarkTheme = computed({
|
||||
get: () => settingsStore.theme === 'dark',
|
||||
set: () => settingsStore.toggleTheme()
|
||||
|
||||
Reference in New Issue
Block a user