本文修改主题为AnZhiYu
主题,若使用其他主题,请自行确认修改位置。
写在前面
AnZhiYu
主题自动生成的的音乐馆页面只提供了音乐的播放功能,并不能直接下载歌曲(虽然你可以自己用开发者工具抓包下载,但这不是一个好习惯)。因此,我们需要在音乐馆页面添加歌曲下载的功能。但是,AnZhiYu
主题的音乐馆页面是通过Aplayer
插件生成的,因此直接修改主题文件无法直接修改播放页面。故我们另辟蹊径,通过修改其在此页面外挂的按钮来添加歌曲下载功能。
预览
修改
添加下载按钮
修改[BlogRoot]\themes\anzhiyu\layout\includes\page\music.pug
文件,添加下载按钮和下载加载动画。
1 2 3 4 5 6 7 8 9 10 11 12
| #anMusic-page #anMusicBtnGetSong(title="随机单曲,打开异世界的大门") i(class="anzhiyufont anzhiyu-icon-shuffle") #anMusicRefreshBtn(title="立即刷新最新歌单") i(class="anzhiyufont anzhiyu-icon-arrows-rotate") #anMusicSwitching(title="切换歌单") i(class="anzhiyufont anzhiyu-icon-repeat") + #anMusicDownloadBtn(title="下载歌曲") + i(class="fa-solid fa-download") + #download-loader + i(class="fa-solid fa-spin") #anMusic-page-meting
|
调整样式
修改[BlogRoot]\themes\anzhiyu\source\css\_page\music.styl
文件,调整下载按钮的样式。
从76行左右开始,调整如下代码,调整下载按钮的样式。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
| @media screen and (max-width: 1400px) body #anMusic-page - #anMusicSwitching, #anMusicRefreshBtn, #anMusicBtnGetSong + #anMusicSwitching, #anMusicRefreshBtn, #anMusicBtnGetSong, #anMusicDownloadBtn right 7vw #anMusicSwitching bottom: 100px #anMusicRefreshBtn bottom: 160px #anMusicBtnGetSong bottom: 220px + #anMusicDownloadBtn + bottom: 280px
#anMusic-page - #anMusicRefreshBtn, #anMusicBtnGetSong, #anMusicSwitching + #anMusicRefreshBtn, #anMusicBtnGetSong, #anMusicSwitching, #anMusicDownloadBtn position: fixed; display: flex; width: 50px; height: 50px; bottom: 100px; padding: 5px; background: var(--anzhiyu-white-op); backdrop-filter: saturate(180%) blur(20px); -webkit-backdrop-filter: blur(20px); border-radius: 50%; color: #fff; text-align: center; justify-content: center; align-items: center; cursor: pointer; z-index 2 #anMusicBtnGetSong right: 11vw; #anMusicRefreshBtn right: 7vw; #anMusicSwitching right: 15vw; + #anMusicDownloadBtn + right: 19vw; +maxWidth768() div#anMusicBtnGetSong right: 80px; bottom: 150px; div#anMusicRefreshBtn right: 20px; bottom: 150px; div#anMusicSwitching right: 140px; bottom: 150px; + div#anMusicDownloadBtn + right: 200px; + bottom: 150px;
|
添加[BlogRoot]\themes\anzhiyu\source\css\custom\music.css
文件或者修改你自定义的CSS文件,添加如下代码,添加点击下载按钮后的动画效果。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| #download-loader { display: none; border: 16px solid #f3f3f3; border-top: 16px solid #3498db; border-radius: 50%; width: 120px; height: 120px; animation: loader-spin 2s linear infinite; position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); }
@keyframes loader-spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } }
|
添加下载功能
修改[BlogRoot]\themes\anzhiyu\source\js\utils.js
文件,添加下载歌曲的功能。
在约879行左右,添加如下代码,加入下载歌曲按钮的监听事件。
1 2 3 4 5 6 7 8 9
| // 监听音乐背景改变 addEventListenerMusic: function () { const anMusicPage = document.getElementById("anMusic-page"); const aplayerIconMenu = anMusicPage.querySelector(".aplayer-info .aplayer-time .aplayer-icon-menu"); const anMusicBtnGetSong = anMusicPage.querySelector("#anMusicBtnGetSong"); const anMusicRefreshBtn = anMusicPage.querySelector("#anMusicRefreshBtn"); const anMusicSwitchingBtn = anMusicPage.querySelector("#anMusicSwitching"); + const anMusicDownloadBtn = anMusicPage.querySelector("#anMusicDownloadBtn"); const metingAplayer = anMusicPage.querySelector("meting-js").aplayer;
|
在约904行左右,添加如下代码,先用fetch请求歌曲的下载地址,然后用createObjectURL将歌曲数据转化为blob对象,最后用a标签下载歌曲。
注意:由于使用了fetch请求下载地址,因此你的音乐资源地址需要支持跨域请求,否则可能下载失败。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
| // 监听增加单曲按钮 anMusicBtnGetSong.addEventListener("click", () => { if (changeMusicListFlag) { const anMusicPage = document.getElementById("anMusic-page"); const metingAplayer = anMusicPage.querySelector("meting-js").aplayer; const allAudios = metingAplayer.list.audios; const randomIndex = Math.floor(Math.random() * allAudios.length); // 随机播放一首 metingAplayer.list.switch(randomIndex); } else { anzhiyu.cacheAndPlayMusic(); } }); anMusicRefreshBtn.addEventListener("click", () => { localStorage.removeItem("musicData"); anzhiyu.snackbarShow("已移除相关缓存歌曲"); }); anMusicSwitchingBtn.addEventListener("click", () => { anzhiyu.changeMusicList(); });
+ anMusicDownloadBtn.addEventListener("click", async () => { + // 下载当前播放的歌曲 + const loader = document.getElementById('download-loader'); + const timeout = 10000; // 超时时间设置为10秒 + loader.style.display = 'block'; // 显示加载动画 + const controller = new AbortController(); + const timeoutId = setTimeout(() => controller.abort(), timeout); + + const anMusicPage = document.getElementById("anMusic-page"); + const metingAplayer = anMusicPage.querySelector("meting-js").aplayer; + const currentSong = metingAplayer.list.audios[metingAplayer.list.index]; + const downloadUrl = currentSong.url; + + let format = ''; + if (downloadUrl.endsWith('.flac')) { + format = '.flac'; + } else if (downloadUrl.endsWith('.mp3')) { + format = '.mp3'; + } else if (downloadUrl.endsWith('.m4a')) { + format = '.m4a'; + } else if (downloadUrl.endsWith('.ogg')) { + format = '.ogg'; + } else if (downloadUrl.endsWith('.wav')) { + format = '.wav'; + } else { + format = '.mp3'; + } + + downloadName = currentSong.name + " - " + currentSong.artist + format; + console.log("下载地址:", downloadUrl); + console.log("文件名:", downloadName); + + try { + const response = await fetch(downloadUrl, { signal: controller.signal }); + clearTimeout(timeoutId); + + if (!response.ok) { + throw new Error(`网络错误,状态码: ${response.status}`); + } + + const blob = await response.blob(); + const downloadLink = document.createElement("a"); + const objectUrl = URL.createObjectURL(blob); + downloadLink.href = objectUrl; + downloadLink.download = downloadName; + downloadLink.click(); + URL.revokeObjectURL(downloadLink.href); // 释放内存 + + } catch (error) { + if (error.name === 'AbortError') { + if (GLOBAL_CONFIG.Snackbar !== undefined) { + anzhiyu.snackbarShow("下载超时,请稍后再试"); + } + } else { + if (GLOBAL_CONFIG.Snackbar !== undefined) { + anzhiyu.snackbarShow("下载失败" + error.message); + } + } + } finally { + loader.style.display = 'none'; // 隐藏加载动画 + } + });
|