fix: 修复部分歌曲无法下载

This commit is contained in:
imsyy
2023-04-04 18:21:50 +08:00
parent f43d8f4641
commit 0411f5dc71
9 changed files with 213 additions and 81 deletions

View File

@@ -451,6 +451,7 @@ onMounted(() => {
align-items: center;
.n-icon {
margin-right: 2px;
transform: translateY(1px);
}
.des {
line-height: normal;

View File

@@ -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>

View File

@@ -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;

View File

@@ -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);

View File

@@ -385,7 +385,7 @@ const useMusicDataStore = defineStore("musicData", {
$message.info("单曲循环");
} else {
this.persistData.playSongMode = "normal";
$message.info("循环播放");
$message.info("列表循环");
}
},
// 上下曲调整

View File

@@ -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: {

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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",
},
{