mirror of
https://github.com/imsyy/SPlayer.git
synced 2025-11-25 03:14:57 +08:00
fix: 修复部分歌曲无法下载
This commit is contained in:
@@ -451,6 +451,7 @@ onMounted(() => {
|
||||
align-items: center;
|
||||
.n-icon {
|
||||
margin-right: 2px;
|
||||
transform: translateY(1px);
|
||||
}
|
||||
.des {
|
||||
line-height: normal;
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
<SmallSongData ref="smallSongDataRef" :songData="songData" notJump />
|
||||
<n-radio-group
|
||||
class="downloadGroup"
|
||||
v-model:value="downloadCheck"
|
||||
v-model:value="downloadChoose"
|
||||
name="downloadGroup"
|
||||
>
|
||||
<n-space vertical>
|
||||
@@ -19,9 +19,17 @@
|
||||
v-for="item in downloadLevel"
|
||||
:key="item"
|
||||
:value="item.value"
|
||||
:disabled="checkLevel(item.value)"
|
||||
:disabled="item.disabled"
|
||||
>
|
||||
{{ item.label }}
|
||||
<div :class="item.disabled ? 'text disabled' : 'text'">
|
||||
<n-text class="name">{{ item.label }}</n-text>
|
||||
<n-text v-if="item.size" class="size" :depth="3">
|
||||
{{ item.size }}
|
||||
</n-text>
|
||||
<n-text v-else-if="!item.disabled" class="error" :depth="3">
|
||||
文件大小获取失败
|
||||
</n-text>
|
||||
</div>
|
||||
</n-radio>
|
||||
</n-space>
|
||||
</n-radio-group>
|
||||
@@ -33,13 +41,13 @@
|
||||
<n-space justify="end">
|
||||
<n-button @click="closeDownloadModel"> 取消 </n-button>
|
||||
<n-button
|
||||
:disabled="!downloadCheck"
|
||||
:disabled="!downloadChoose"
|
||||
:loading="downloadStatus"
|
||||
type="primary"
|
||||
@click="
|
||||
toSongDownload(
|
||||
songId,
|
||||
downloadCheck,
|
||||
downloadChoose,
|
||||
songData.artist[0].name + '-' + songData.name
|
||||
)
|
||||
"
|
||||
@@ -65,83 +73,126 @@ const songId = ref(null);
|
||||
const songData = ref(null);
|
||||
const downloadStatus = ref(false);
|
||||
const downloadModel = ref(false);
|
||||
const downloadCheck = ref(null);
|
||||
const downloadLevel = [
|
||||
{
|
||||
value: "128000",
|
||||
label: "标准音质",
|
||||
},
|
||||
{
|
||||
value: "192000",
|
||||
label: "较高音质",
|
||||
},
|
||||
{
|
||||
value: "320000",
|
||||
label: "极高音质",
|
||||
},
|
||||
{
|
||||
value: "flac",
|
||||
label: "无损音质",
|
||||
},
|
||||
{
|
||||
value: "999000",
|
||||
label: "Hi-Res",
|
||||
},
|
||||
];
|
||||
const downloadChoose = ref(null);
|
||||
const downloadLevel = ref(null);
|
||||
|
||||
// 歌曲下载
|
||||
const toSongDownload = (id, br, name) => {
|
||||
downloadStatus.value = true;
|
||||
getSongDownload(id, br).then((res) => {
|
||||
console.log(name, res);
|
||||
if (res.data.url) {
|
||||
const type = res.data.type.toLowerCase();
|
||||
const songName = name ? name : "未知曲目";
|
||||
fetch(res.data.url)
|
||||
.then((response) => response.blob())
|
||||
.then((blob) => {
|
||||
const url = window.URL.createObjectURL(blob);
|
||||
const a = document.createElement("a");
|
||||
a.href = url;
|
||||
a.download = `${songName}.${type}`;
|
||||
document.body.appendChild(a);
|
||||
a.click();
|
||||
a.remove();
|
||||
closeDownloadModel();
|
||||
downloadStatus.value = false;
|
||||
$message.success(name + " 下载完成");
|
||||
});
|
||||
} else {
|
||||
downloadStatus.value = false;
|
||||
$message.error("下载失败,请尝试其他音质");
|
||||
}
|
||||
});
|
||||
getSongDownload(id, br)
|
||||
.then((res) => {
|
||||
console.log(name, res);
|
||||
if (res.data.url) {
|
||||
const type = res.data.type.toLowerCase();
|
||||
const songName = name ? name : "未知曲目";
|
||||
fetch(res.data.url)
|
||||
.then((response) => response.blob())
|
||||
.then((blob) => {
|
||||
const url = window.URL.createObjectURL(blob);
|
||||
const a = document.createElement("a");
|
||||
a.href = url;
|
||||
a.download = `${songName}.${type}`;
|
||||
document.body.appendChild(a);
|
||||
a.click();
|
||||
a.remove();
|
||||
closeDownloadModel();
|
||||
downloadStatus.value = false;
|
||||
$message.success(name + " 下载完成");
|
||||
});
|
||||
} else {
|
||||
downloadStatus.value = false;
|
||||
$message.error("下载失败,请尝试其他音质");
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
closeDownloadModel();
|
||||
console.error("下载出现错误:" + err);
|
||||
$message.error("下载出现错误,请重试");
|
||||
});
|
||||
};
|
||||
|
||||
// 获取歌曲详情
|
||||
const getMusicDetailData = (id) => {
|
||||
getMusicDetail(id).then((res) => {
|
||||
if (res.songs[0] && res.privileges[0]) {
|
||||
songData.value = {
|
||||
album: res.songs[0].al,
|
||||
artist: res.songs[0].ar,
|
||||
name: res.songs[0].name,
|
||||
id: res.songs[0].id,
|
||||
br: res.privileges[0].downloadMaxbr,
|
||||
};
|
||||
} else {
|
||||
$message.error("歌曲信息获取失败");
|
||||
}
|
||||
});
|
||||
getMusicDetail(id)
|
||||
.then((res) => {
|
||||
if (res.songs[0] && res.privileges[0]) {
|
||||
songData.value = {
|
||||
album: res.songs[0].al,
|
||||
artist: res.songs[0].ar,
|
||||
name: res.songs[0].name,
|
||||
id: res.songs[0].id,
|
||||
};
|
||||
// 生成音质列表
|
||||
generateLists(res);
|
||||
} else {
|
||||
$message.error("歌曲信息获取失败");
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
closeDownloadModel();
|
||||
console.error("歌曲信息获取出现错误:" + err);
|
||||
$message.error("歌曲信息获取出现错误,请重试");
|
||||
});
|
||||
};
|
||||
|
||||
// 判断音质是否可以下载
|
||||
const checkLevel = (val) => {
|
||||
if (val !== "flac") {
|
||||
const level = Number(val);
|
||||
return level <= songData.value?.br ? false : true;
|
||||
// 生成可下载列表
|
||||
const generateLists = (data) => {
|
||||
const br = data.privileges[0].downloadMaxbr;
|
||||
downloadLevel.value = [
|
||||
{
|
||||
value: "128000",
|
||||
label: "标准音质",
|
||||
disabled: br >= 128000 ? false : true,
|
||||
size: getSongSize(data, "l"),
|
||||
},
|
||||
{
|
||||
value: "192000",
|
||||
label: "较高音质",
|
||||
disabled: br >= 192000 ? false : true,
|
||||
size: getSongSize(data, "m"),
|
||||
},
|
||||
{
|
||||
value: "320000",
|
||||
label: "极高音质",
|
||||
disabled: br >= 320000 ? false : true,
|
||||
size: getSongSize(data, "h"),
|
||||
},
|
||||
{
|
||||
value: "420000",
|
||||
label: "无损音质",
|
||||
disabled: [128000, 192000, 320000].includes(parseInt(br)),
|
||||
size: getSongSize(data, "sq"),
|
||||
},
|
||||
{
|
||||
value: "999000",
|
||||
label: "Hi-Res",
|
||||
disabled: br >= 999000 ? false : true,
|
||||
size: getSongSize(data, "hr"),
|
||||
},
|
||||
];
|
||||
console.log(downloadLevel.value);
|
||||
};
|
||||
|
||||
// 获取下载大小
|
||||
const getSongSize = (data, type) => {
|
||||
let fileSize = 0;
|
||||
// 转换文件大小
|
||||
const convertSize = (num) => {
|
||||
if (!num) return 0;
|
||||
return (num / (1024 * 1024)).toFixed(2);
|
||||
};
|
||||
if (type === "l") {
|
||||
fileSize = convertSize(data.songs[0]?.l?.size);
|
||||
} else if (type === "m") {
|
||||
fileSize = convertSize(data.songs[0]?.m?.size);
|
||||
} else if (type === "h") {
|
||||
fileSize = convertSize(data.songs[0]?.h?.size);
|
||||
} else if (type === "sq") {
|
||||
fileSize = convertSize(data.songs[0]?.sq?.size);
|
||||
} else if (type === "hr") {
|
||||
fileSize = convertSize(data.songs[0]?.hr?.size);
|
||||
}
|
||||
return false;
|
||||
return fileSize;
|
||||
};
|
||||
|
||||
// 开启歌曲下载
|
||||
@@ -166,8 +217,11 @@ const openDownloadModel = (data) => {
|
||||
|
||||
// 关闭歌曲下载
|
||||
const closeDownloadModel = () => {
|
||||
songId.value = null;
|
||||
songData.value = null;
|
||||
downloadStatus.value = false;
|
||||
downloadModel.value = false;
|
||||
downloadCheck.value = null;
|
||||
downloadChoose.value = null;
|
||||
};
|
||||
|
||||
// 暴露方法
|
||||
@@ -179,5 +233,30 @@ defineExpose({
|
||||
<style lang="scss" scoped>
|
||||
.downloadGroup {
|
||||
margin-top: 20px;
|
||||
.text {
|
||||
&.disabled {
|
||||
span {
|
||||
color: var(--n-text-color-disabled);
|
||||
}
|
||||
}
|
||||
.size {
|
||||
font-size: 13px;
|
||||
&::before {
|
||||
content: "-";
|
||||
margin: 0 4px;
|
||||
}
|
||||
&::after {
|
||||
content: "Mb";
|
||||
margin-left: 4px;
|
||||
}
|
||||
}
|
||||
.error {
|
||||
font-size: 13px;
|
||||
&::before {
|
||||
content: "-";
|
||||
margin: 0 4px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -31,6 +31,12 @@
|
||||
: 'all noLrc'
|
||||
"
|
||||
>
|
||||
<!-- 提示文本 -->
|
||||
<Transition name="lrc">
|
||||
<div class="tip" v-show="lrcMouseStatus">
|
||||
<n-text>点击选中的歌词以调整播放进度</n-text>
|
||||
</div>
|
||||
</Transition>
|
||||
<div class="left">
|
||||
<PlayerCover v-if="setting.playerStyle === 'cover'" />
|
||||
<PlayerRecord v-else />
|
||||
@@ -88,9 +94,15 @@
|
||||
? { textAlign: 'center', paddingRight: '0' }
|
||||
: null
|
||||
"
|
||||
@mouseenter="lrcMouseStatus = true"
|
||||
@mouseenter="
|
||||
lrcMouseStatus = setting.lrcMousePause ? true : false
|
||||
"
|
||||
@mouseleave="lrcAllLeave"
|
||||
>
|
||||
<!-- 提示文本 -->
|
||||
<div class="tip">
|
||||
<n-text>点击选中的歌词以调整播放进度</n-text>
|
||||
</div>
|
||||
<div class="placeholder"></div>
|
||||
<div
|
||||
:class="
|
||||
@@ -356,6 +368,7 @@ watch(
|
||||
cursor: pointer;
|
||||
border-radius: 8px;
|
||||
transition: all 0.3s;
|
||||
z-index: 2;
|
||||
&:hover {
|
||||
background-color: #ffffff20;
|
||||
transform: scale(1.05);
|
||||
@@ -379,6 +392,7 @@ watch(
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
transition: all 0.3s ease-in-out;
|
||||
position: relative;
|
||||
&.noLrc {
|
||||
.left {
|
||||
padding-right: 0;
|
||||
@@ -416,6 +430,22 @@ watch(
|
||||
}
|
||||
}
|
||||
}
|
||||
.tip {
|
||||
position: absolute;
|
||||
top: 24px;
|
||||
left: calc(50% - 150px);
|
||||
width: 300px;
|
||||
height: 40px;
|
||||
border-radius: 25px;
|
||||
background-color: #ffffff20;
|
||||
backdrop-filter: blur(20px);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
span {
|
||||
color: #ffffffc7;
|
||||
}
|
||||
}
|
||||
.left {
|
||||
// flex: 1;
|
||||
// padding: 0 4vw;
|
||||
|
||||
@@ -30,7 +30,10 @@
|
||||
content-style="padding: 0"
|
||||
>
|
||||
<n-scrollbar>
|
||||
<div class="history-list" v-if="music.getSearchHistory[0]">
|
||||
<div
|
||||
class="history-list"
|
||||
v-if="music.getSearchHistory[0] && setting.searchHistory"
|
||||
>
|
||||
<div class="list-title">
|
||||
<n-icon size="16" :component="HistoryRound" />
|
||||
<n-text>搜索历史</n-text>
|
||||
@@ -181,9 +184,10 @@ import {
|
||||
import CollapseTransition from "@ivanv/vue-collapse-transition/src/CollapseTransition.vue";
|
||||
import debounce from "@/utils/debounce";
|
||||
import { useRouter } from "vue-router";
|
||||
import { musicStore } from "@/store";
|
||||
import { musicStore, settingStore } from "@/store";
|
||||
const router = useRouter();
|
||||
const music = musicStore();
|
||||
const setting = settingStore();
|
||||
|
||||
// 输入框内容
|
||||
const inputValue = ref(null);
|
||||
|
||||
@@ -385,7 +385,7 @@ const useMusicDataStore = defineStore("musicData", {
|
||||
$message.info("单曲循环");
|
||||
} else {
|
||||
this.persistData.playSongMode = "normal";
|
||||
$message.info("循环播放");
|
||||
$message.info("列表循环");
|
||||
}
|
||||
},
|
||||
// 上下曲调整
|
||||
|
||||
@@ -8,6 +8,8 @@ const useSettingDataStore = defineStore("settingData", {
|
||||
// 全局主题
|
||||
theme: "light",
|
||||
themeAuto: true,
|
||||
// 搜索历史
|
||||
searchHistory: true,
|
||||
// 轮播图显示
|
||||
bannerShow: true,
|
||||
// 自动签到
|
||||
@@ -32,6 +34,8 @@ const useSettingDataStore = defineStore("settingData", {
|
||||
lyricsBlur: false,
|
||||
// 音乐频谱
|
||||
musicFrequency: false,
|
||||
// 鼠标移入歌词区域暂停滚动
|
||||
lrcMousePause: true,
|
||||
};
|
||||
},
|
||||
getters: {
|
||||
|
||||
@@ -231,7 +231,7 @@ watch(
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
@media (max-width: 370px) {
|
||||
@media (max-width: 768px) {
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
@@ -330,7 +330,7 @@ watch(
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
@media (max-width: 370px) {
|
||||
@media (max-width: 768px) {
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
@@ -29,12 +29,17 @@
|
||||
/>
|
||||
</n-card>
|
||||
<n-card class="set-item">
|
||||
<div class="name">轮播图显示</div>
|
||||
<div class="name">显示轮播图</div>
|
||||
<n-switch v-model:value="bannerShow" :round="false" />
|
||||
</n-card>
|
||||
<n-card class="set-item">
|
||||
<div class="name">显示搜索历史</div>
|
||||
<n-switch v-model:value="searchHistory" :round="false" />
|
||||
</n-card>
|
||||
<n-card class="set-item">
|
||||
<div class="name">
|
||||
底栏歌词显示 <span class="tip">是否在播放时显示歌词</span>
|
||||
显示底栏歌词
|
||||
<span class="tip">是否在播放时显示歌词</span>
|
||||
</div>
|
||||
<n-switch v-model:value="bottomLyricShow" :round="false" />
|
||||
</n-card>
|
||||
@@ -54,6 +59,13 @@
|
||||
<div class="name">显示歌词翻译</div>
|
||||
<n-switch v-model:value="showTransl" :round="false" />
|
||||
</n-card>
|
||||
<n-card class="set-item">
|
||||
<div class="name">
|
||||
智能暂停滚动
|
||||
<span class="tip">鼠标移入歌词区域是否暂停滚动</span>
|
||||
</div>
|
||||
<n-switch v-model:value="lrcMousePause" :round="false" />
|
||||
</n-card>
|
||||
<n-card class="set-item">
|
||||
<div class="name">播放器样式</div>
|
||||
<n-select
|
||||
@@ -173,6 +185,8 @@ const {
|
||||
bannerShow,
|
||||
lyricsBlur,
|
||||
autoSignIn,
|
||||
lrcMousePause,
|
||||
searchHistory,
|
||||
} = storeToRefs(setting);
|
||||
|
||||
// 深浅模式
|
||||
@@ -243,7 +257,7 @@ const lyricsPositionOptions = [
|
||||
// 歌词滚动位置
|
||||
const lyricsBlockOptions = [
|
||||
{
|
||||
label: "顶部",
|
||||
label: "靠近顶部",
|
||||
value: "start",
|
||||
},
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user