From da6b7cdd95c5e2bfbe44653238c95e15946b77fe Mon Sep 17 00:00:00 2001 From: qier222 Date: Sat, 31 Oct 2020 12:02:50 +0800 Subject: [PATCH] feat: cache songs --- src/store/actions.js | 23 ++++++++++----- src/utils/common.js | 24 +++++++++++++++- src/utils/db.js | 57 ++++++++++++++++++++++++++++++++++++ src/views/settings.vue | 65 ++++++++++++++++++++++++++++++++++++++++-- 4 files changed, 159 insertions(+), 10 deletions(-) create mode 100644 src/utils/db.js diff --git a/src/store/actions.js b/src/store/actions.js index 7d61fb5..177c59e 100644 --- a/src/store/actions.js +++ b/src/store/actions.js @@ -1,13 +1,16 @@ import { updateMediaSessionMetaData } from "@/utils/mediaSession"; -import { getTrackDetail, scrobble, getMP3 } from "@/api/track"; +import { getTrackDetail, scrobble } from "@/api/track"; import { isAccountLoggedIn } from "@/utils/auth"; -import { updateHttps } from "@/utils/common"; +// import { updateHttps } from "@/utils/common"; +import localforage from "localforage"; +import { cacheTrack } from "@/utils/db"; export default { switchTrack({ state, dispatch, commit }, basicTrack) { getTrackDetail(basicTrack.id).then((data) => { let track = data.songs[0]; track.sort = basicTrack.sort; + // 获取当前的播放时间。初始化为 loading 状态时返回 howler 的实例而不是浮点数时间,比如 1.332 let time = state.howler.seek(); let currentTime = 0; @@ -26,6 +29,7 @@ export default { sourceid: state.player.listInfo.id, time: currentTime, }); + commit("updateCurrentTrack", track); updateMediaSessionMetaData(track); document.title = `${track.name} · ${track.ar[0].name} - YesPlayMusic`; @@ -42,11 +46,16 @@ export default { }); } if (isAccountLoggedIn()) { - getMP3(track.id).then((data) => { - // 未知情况下会没有返回数据导致报错,增加防范逻辑 - if (data.data[0]) { - const url = updateHttps(data.data[0].url); - commitMP3(url); + let tracks = localforage.createInstance({ + name: "tracks", + }); + tracks.getItem(`${track.id}`).then((t) => { + if (t !== null) { + commitMP3(URL.createObjectURL(t.mp3)); + } else { + cacheTrack(`${track.id}`).then((t) => { + commitMP3(URL.createObjectURL(t.mp3)); + }); } }); } else { diff --git a/src/utils/common.js b/src/utils/common.js index 5424a28..e529dd8 100644 --- a/src/utils/common.js +++ b/src/utils/common.js @@ -115,6 +115,7 @@ export function splitSoundtrackAlbumTitle(title) { "Original MGM Motion Picture Soundtrack", "Complete Original Motion Picture Score", "Original Music From The Motion Picture", + "Music From The Disney+ Original Movie", "Original Music From The Netflix Film", "Original Score to the Motion Picture", "Original Motion Picture Soundtrack", @@ -153,7 +154,13 @@ export function splitSoundtrackAlbumTitle(title) { } export function splitAlbumTitle(title) { - let keywords = ["Bonus Tracks Edition", "Complete Edition", "Deluxe Edition"]; + let keywords = [ + "Bonus Tracks Edition", + "Complete Edition", + "Deluxe Edition", + "Deluxe Version", + "Tour Edition", + ]; for (let keyword of keywords) { if (title.includes(keyword) === false) continue; return { @@ -171,3 +178,18 @@ export function splitAlbumTitle(title) { subtitle: "", }; } + +export function bytesToSize(bytes) { + var marker = 1024; // Change to 1000 if required + var decimal = 2; // Change as required + var kiloBytes = marker; + var megaBytes = marker * marker; + var gigaBytes = marker * marker * marker; + + if (bytes < kiloBytes) return bytes + " Bytes"; + else if (bytes < megaBytes) + return (bytes / kiloBytes).toFixed(decimal) + " KB"; + else if (bytes < gigaBytes) + return (bytes / megaBytes).toFixed(decimal) + " MB"; + else return (bytes / gigaBytes).toFixed(decimal) + " GB"; +} diff --git a/src/utils/db.js b/src/utils/db.js new file mode 100644 index 0000000..83feeb5 --- /dev/null +++ b/src/utils/db.js @@ -0,0 +1,57 @@ +import axios from "axios"; +import localforage from "localforage"; +import { getMP3 } from "@/api/track"; + +export function cacheTrack(id) { + let tracks = localforage.createInstance({ + name: "tracks", + }); + + // TODO: limit cache songs number + // tracks.length().then(function (length) { + // if (length > 2) { + // tracks.keys().then(function (keys) { + // tracks.removeItem(keys[keys.length - 2]); + // }); + // } + // }); + + // TODO: cache track details + return getMP3(id).then((data) => { + return axios + .get(data.data[0].url.replace(/^http:/, "https:"), { + responseType: "blob", + }) + .then((data) => { + tracks.setItem(`${id}`, { mp3: data.data }); + return { mp3: data.data }; + }); + }); +} + +export function countDBSize(dbName) { + let db = localforage.createInstance({ + name: dbName, + }); + let trackSizes = []; + return db + .iterate((value) => { + trackSizes.push(value.mp3.size); + }) + .then(() => { + return { + bytes: trackSizes.reduce((s1, s2) => s1 + s2), + length: trackSizes.length, + }; + }) + .catch((err) => { + console.log(err); + }); +} + +export function clearDB(dbName) { + let db = localforage.createInstance({ + name: dbName, + }); + return db.clear(); +} diff --git a/src/views/settings.vue b/src/views/settings.vue index 1080a25..da02c6c 100644 --- a/src/views/settings.vue +++ b/src/views/settings.vue @@ -74,6 +74,16 @@ +
+
+
Cached {{ tracksCache.length }} songs ({{ tracksCache.size }})
+
+
+ +
+
Show Github Icon
@@ -129,10 +139,19 @@ @@ -329,6 +375,21 @@ h2 { background: var(--color-primary-bg); } } + + button { + color: var(--color-text); + background: var(--color-secondary-bg); + padding: 8px 12px 8px 12px; + font-weight: 600; + border-radius: 8px; + transition: 0.2s; + &:hover { + transform: scale(1.06); + } + &:active { + transform: scale(0.94); + } + } } .beforeAnimation {