feat: 添加音质选择 优化灰色歌曲解析

This commit is contained in:
alger
2025-01-06 20:54:42 +08:00
parent fcc47dc0ff
commit 020aca7384
12 changed files with 78 additions and 54 deletions

View File

@@ -12,8 +12,8 @@ if (!fs.existsSync(path.resolve(os.tmpdir(), 'anonymous_token'))) {
}
// 处理解锁音乐请求
ipcMain.handle('unblock-music', async (_, id) => {
return unblockMusic(id);
ipcMain.handle('unblock-music', async (_, id, data) => {
return unblockMusic(id, data);
});
import server from 'netease-cloud-music-api-alger/server';

View File

@@ -6,12 +6,13 @@
"host": "127.0.0.1",
"port": 7890
},
"enableRealIP":false,
"realIP":"",
"enableRealIP": false,
"realIP": "",
"noAnimate": false,
"animationSpeed": 1,
"author": "Alger",
"authorUrl": "https://github.com/algerkong",
"musicApiPort": 30488,
"closeAction": "ask"
"closeAction": "ask",
"musicQuality": "higher"
}

View File

@@ -1,8 +1,8 @@
import match from '@unblockneteasemusic/server';
const unblockMusic = async (id: any): Promise<any> => {
const unblockMusic = async (id: any, songData: any): Promise<any> => {
return new Promise((resolve, reject) => {
match(parseInt(id, 10), ['qq', 'migu', 'kugou', 'joox'])
match(parseInt(id, 10), ['qq', 'migu', 'kugou', 'joox'], songData)
.then((data) => {
resolve({
data: {

View File

@@ -12,7 +12,7 @@ declare global {
dragStart: (data: string) => void;
miniTray: () => void;
restart: () => void;
unblockMusic: (id: number) => Promise<any>;
unblockMusic: (id: number, data: any) => Promise<any>;
};
}
}

View File

@@ -3,9 +3,32 @@ import { IPlayMusicUrl } from '@/type/music';
import { isElectron } from '@/utils';
import request from '@/utils/request';
import requestMusic from '@/utils/request_music';
import store from '@/store';
// 获取音乐音质详情
export const getMusicQualityDetail = (id: number) => {
return request.get('/song/music/detail', { params: { id } });
};
// 根据音乐Id获取音乐播放URl
export const getMusicUrl = (id: number) => {
return request.get<IPlayMusicUrl>('/song/url', { params: { id } });
export const getMusicUrl = async (id: number) => {
const res = await request.get('/song/download/url/v1', {
params: {
id,
level: store.state.setData.musicQuality || 'higher'
}
});
if (res.data.data.url) {
return {data:{ data:[{url:res.data.data.url}]}};
}
return await request.get('/song/url/v1', {
params: {
id,
level: store.state.setData.musicQuality || 'higher'
}
});
};
// 获取歌曲详情
@@ -18,9 +41,9 @@ export const getMusicLrc = (id: number) => {
return request.get<ILyric>('/lyric', { params: { id } });
};
export const getParsingMusicUrl = (id: number) => {
export const getParsingMusicUrl = (id: number, data: any) => {
if (isElectron) {
return window.api.unblockMusic(id);
return window.api.unblockMusic(id, data);
}
return requestMusic.get<any>('/music', { params: { id } });
};

View File

@@ -26,9 +26,12 @@ declare module 'vue' {
NMessageProvider: typeof import('naive-ui')['NMessageProvider']
NModal: typeof import('naive-ui')['NModal']
NPopover: typeof import('naive-ui')['NPopover']
NRadio: typeof import('naive-ui')['NRadio']
NRadioGroup: typeof import('naive-ui')['NRadioGroup']
NScrollbar: typeof import('naive-ui')['NScrollbar']
NSelect: typeof import('naive-ui')['NSelect']
NSlider: typeof import('naive-ui')['NSlider']
NSpace: typeof import('naive-ui')['NSpace']
NSpin: typeof import('naive-ui')['NSpin']
NSwitch: typeof import('naive-ui')['NSwitch']
NTag: typeof import('naive-ui')['NTag']

View File

@@ -81,6 +81,7 @@ import type { SongResult } from '@/type/music';
import { getImgUrl, isElectron } from '@/utils';
import { getImageBackground } from '@/utils/linearColor';
import { getSongUrl } from '@/hooks/MusicListHook';
import { cloneDeep } from 'lodash';
const props = withDefaults(
defineProps<{
@@ -148,7 +149,7 @@ const downloadMusic = async () => {
isDownloading.value = true;
const loadingMessage = message.loading('正在下载中...', { duration: 0 });
const url = await getSongUrl(props.item.id);
const url = await getSongUrl(props.item.id, cloneDeep(props.item));
if (!url) {
loadingMessage.destroy();
message.error('获取音乐下载地址失败');

View File

@@ -4,31 +4,31 @@ import { getMusicLrc, getMusicUrl, getParsingMusicUrl } from '@/api/music';
import { useMusicHistory } from '@/hooks/MusicHistoryHook';
import { audioService } from '@/services/audioService';
import type { ILyric, ILyricText, SongResult } from '@/type/music';
import { getImgUrl, getMusicProxyUrl } from '@/utils';
import { getImgUrl } from '@/utils';
import { getImageLinearBackground } from '@/utils/linearColor';
import { cloneDeep } from 'lodash';
const musicHistory = useMusicHistory();
// 获取歌曲url
export const getSongUrl = async (id: number) => {
export const getSongUrl = async (id: number, songData: any) => {
const { data } = await getMusicUrl(id);
let url = '';
try {
if (data.data[0].freeTrialInfo || !data.data[0].url) {
const res = await getParsingMusicUrl(id);
console.log('res', res);
const res = await getParsingMusicUrl(id, songData);
url = res.data.data.url;
}
} catch (error) {
console.error('error', error);
}
url = url || data.data[0].url;
return getMusicProxyUrl(url);
return url;
};
const getSongDetail = async (playMusic: SongResult) => {
playMusic.playLoading = true;
const playMusicUrl = await getSongUrl(playMusic.id);
const playMusicUrl = await getSongUrl(playMusic.id, cloneDeep(playMusic));
const { backgroundColor, primaryColor } =
playMusic.backgroundColor && playMusic.primaryColor
? playMusic

View File

@@ -6,15 +6,10 @@ import type { SongResult } from '@/type/music';
import { applyTheme, getCurrentTheme, ThemeType } from '@/utils/theme';
import { isElectron } from '@/utils';
import { likeSong, getLikedList } from '@/api/music';
import setData from '@/../main/set.json'
// 默认设置
const defaultSettings = {
isProxy: false,
noAnimate: false,
animationSpeed: 1,
author: 'Alger',
authorUrl: 'https://github.com/algerkong'
};
const defaultSettings = setData;
function getLocalStorageItem<T>(key: string, defaultValue: T): T {
const item = localStorage.getItem(key);
@@ -139,7 +134,6 @@ const mutations = {
const actions = {
initializeSettings({ commit }: { commit: any }) {
if (isElectron) {
// const setData = (window as any).electron.ipcRenderer.getStoreValue('set');
const setData = window.electron.ipcRenderer.sendSync('get-store-value', 'set');
commit('setSetData', setData || defaultSettings);
} else {

View File

@@ -54,34 +54,9 @@ export const formatNumber = (num: string | number) => {
return num.toString();
};
const windowData = window as any;
export const getIsMc = () => {
if (!windowData.electron) {
return false;
}
const setData = window.electron.ipcRenderer.sendSync('get-store-value', 'set');
if (setData.isProxy) {
return true;
}
return false;
};
const ProxyUrl = import.meta.env.VITE_API_PROXY;
export const getMusicProxyUrl = (url: string) => {
if (!getIsMc()) {
return url;
}
const PUrl = url.split('').join('+');
return `${ProxyUrl}/mc?url=${PUrl}`;
};
export const getImgUrl = (url: string | undefined, size: string = '') => {
const bdUrl = 'https://image.baidu.com/search/down?url=';
const imgUrl = `${url}?param=${size}`;
if (!getIsMc()) {
return imgUrl;
}
return `${bdUrl}${encodeURIComponent(imgUrl)}`;
return imgUrl;
};
export const isMobile = computed(() => {

View File

@@ -44,7 +44,9 @@ request.interceptors.request.use(
};
const token = localStorage.getItem('token');
if (token) {
config.params.cookie = token;
config.params.cookie = token + ' os=pc;';
}else{
config.params.cookie = 'os=pc;';
}
}

View File

@@ -168,6 +168,27 @@
/>
</div>
</div>
<div class="set-item">
<div>
<div class="set-item-title">音质设置</div>
<div class="set-item-content">选择音乐播放音质VIP</div>
</div>
<n-select
v-model:value="setData.musicQuality"
:options="[
{ label: '标准', value: 'standard' },
{ label: '较高', value: 'higher' },
{ label: '极高', value: 'exhigh' },
{ label: '无损', value: 'lossless' },
{ label: 'Hi-Res', value: 'hires' },
{ label: '高清环绕声', value: 'jyeffect' },
{ label: '沉浸环绕声', value: 'sky' },
{ label: '杜比全景声', value: 'dolby' },
{ label: '超清母带', value: 'jymaster' }
]"
style="width: 160px"
/>
</div>
</div>
<PlayBottom/>
<n-modal
@@ -247,6 +268,10 @@ const setData = computed(() => {
port: 7890
};
}
// 确保音质设置存在
if (!data.musicQuality) {
data.musicQuality = 'higher';
}
return data;
});