From 7d29458d7101ed53d5c5fbf7c83fc061af2f073b Mon Sep 17 00:00:00 2001 From: lyswhut Date: Sat, 23 Nov 2024 14:26:34 +0800 Subject: [PATCH 01/11] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E6=AD=8C=E6=9B=B2?= =?UTF-8?q?=E9=A2=84=E5=8A=A0=E8=BD=BD=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- publish/changeLog.md | 1 + src/core/init/player/index.ts | 2 + src/core/init/player/preloadNextMusic.ts | 66 +++++++++++ src/core/init/userApi/request.js | 2 +- src/core/music/utils.ts | 9 +- src/core/player/player.ts | 138 +++++++++++++++++++---- src/utils/request.js | 10 ++ 7 files changed, 202 insertions(+), 26 deletions(-) create mode 100644 src/core/init/player/preloadNextMusic.ts diff --git a/publish/changeLog.md b/publish/changeLog.md index 594201d..84742f3 100644 --- a/publish/changeLog.md +++ b/publish/changeLog.md @@ -4,6 +4,7 @@ ### 优化 +- 优化正常播放结束时的下一首歌曲播放衔接度,在歌曲即将播放结束时将预获取下一首歌曲的播放链接,减少自动切歌时的等待时间 - 首次使用的提示窗口可以点击背景或者返回键关闭(#577) - 上移 Toast 位置避免遮挡播放模式图标(#603 @sibojia) diff --git a/src/core/init/player/index.ts b/src/core/init/player/index.ts index ccdd609..5f3084f 100644 --- a/src/core/init/player/index.ts +++ b/src/core/init/player/index.ts @@ -4,6 +4,7 @@ import initPlayStatus from './playStatus' import initPlayerEvent from './playerEvent' import initWatchList from './watchList' import initPlayProgress from './playProgress' +import initPreloadNextMusic from './preloadNextMusic' import initLyric from './lyric' export default async(setting: LX.AppSetting) => { @@ -14,4 +15,5 @@ export default async(setting: LX.AppSetting) => { initPlayerEvent() initWatchList() initPlayProgress() + initPreloadNextMusic() } diff --git a/src/core/init/player/preloadNextMusic.ts b/src/core/init/player/preloadNextMusic.ts new file mode 100644 index 0000000..7583b95 --- /dev/null +++ b/src/core/init/player/preloadNextMusic.ts @@ -0,0 +1,66 @@ +import { getMusicUrl } from '@/core/music' +import { getNextPlayMusicInfo, resetRandomNextMusicInfo } from '@/core/player/player' +import { checkUrl } from '@/utils/request' +import playerState from '@/store/player/state' + + +const preloadMusicInfo = { + isLoading: false, + preProgress: 0, + info: null as LX.Player.PlayMusicInfo | null, +} +const resetPreloadInfo = () => { + preloadMusicInfo.preProgress = 0 + preloadMusicInfo.info = null + preloadMusicInfo.isLoading = false +} +const preloadNextMusicUrl = async(curTime: number) => { + if (preloadMusicInfo.isLoading || curTime - preloadMusicInfo.preProgress < 3) return + preloadMusicInfo.isLoading = true + console.log('preload next music url') + const info = await getNextPlayMusicInfo() + if (info) { + preloadMusicInfo.info = info + const url = await getMusicUrl({ musicInfo: info.musicInfo }).catch(() => '') + if (url) { + console.log('preload url', url) + const result = await checkUrl(url).then(() => true).catch(() => false) + if (!result) { + const url = await getMusicUrl({ musicInfo: info.musicInfo, isRefresh: true }).catch(() => '') + console.log('preload url refresh', url) + } + } + } + preloadMusicInfo.isLoading = false +} + +export default () => { + const setProgress = (time: number) => { + if (!playerState.musicInfo.id) return + preloadMusicInfo.preProgress = time + } + + const handleSetPlayInfo = () => { + resetPreloadInfo() + } + + const handleConfigUpdated: typeof global.state_event.configUpdated = (keys, settings) => { + if (!keys.includes('player.togglePlayMethod')) return + if (!preloadMusicInfo.info || preloadMusicInfo.info.isTempPlay) return + resetRandomNextMusicInfo() + preloadMusicInfo.info = null + preloadMusicInfo.preProgress = playerState.progress.nowPlayTime + } + + const handlePlayProgressChanged: typeof global.state_event.playProgressChanged = (progress) => { + const duration = progress.maxPlayTime + if (duration > 10 && duration - progress.nowPlayTime < 10 && !preloadMusicInfo.info) { + void preloadNextMusicUrl(progress.nowPlayTime) + } + } + + global.app_event.on('setProgress', setProgress) + global.app_event.on('musicToggled', handleSetPlayInfo) + global.state_event.on('configUpdated', handleConfigUpdated) + global.state_event.on('playProgressChanged', handlePlayProgressChanged) +} diff --git a/src/core/init/userApi/request.js b/src/core/init/userApi/request.js index 8fa5b3e..1d0f9af 100644 --- a/src/core/init/userApi/request.js +++ b/src/core/init/userApi/request.js @@ -71,7 +71,7 @@ const blobToBuffer = (blob) => { }) } -export const fetchData = (url, { timeout = 15000, ...options }) => { +export const fetchData = (url, { timeout = 13_000, ...options }) => { // console.log('---start---', url) const controller = new global.AbortController() diff --git a/src/core/music/utils.ts b/src/core/music/utils.ts index fc0d6f9..c38c539 100644 --- a/src/core/music/utils.ts +++ b/src/core/music/utils.ts @@ -15,12 +15,14 @@ import { apis } from '@/utils/musicSdk/api-source' const getOtherSourcePromises = new Map() export const existTimeExp = /\[\d{1,2}:.*\d{1,4}\]/ +const otherSourceCache = new Map() export const getOtherSource = async(musicInfo: LX.Music.MusicInfo | LX.Download.ListItem, isRefresh = false): Promise => { // if (!isRefresh) { // const cachedInfo = await getOtherSourceFromStore(musicInfo.id) // if (cachedInfo.length) return cachedInfo // } + if (otherSourceCache.has(musicInfo)) return otherSourceCache.get(musicInfo)! let key: string let searchMusicInfo: { name: string @@ -54,9 +56,12 @@ export const getOtherSource = async(musicInfo: LX.Music.MusicInfo | LX.Download. let timeout: null | number = BackgroundTimer.setTimeout(() => { timeout = null reject(new Error('find music timeout')) - }, 15_000) + }, 12_000) findMusic(searchMusicInfo).then((otherSource) => { - resolve(otherSource.map(toNewMusicInfo) as LX.Music.MusicInfoOnline[]) + if (otherSourceCache.size > 100) otherSourceCache.clear() + const source = otherSource.map(toNewMusicInfo) as LX.Music.MusicInfoOnline[] + otherSourceCache.set(musicInfo, source) + resolve(source) }).catch(reject).finally(() => { if (timeout) BackgroundTimer.clearTimeout(timeout) }) diff --git a/src/core/player/player.ts b/src/core/player/player.ts index 306281f..947c1d7 100644 --- a/src/core/player/player.ts +++ b/src/core/player/player.ts @@ -238,6 +238,7 @@ const handlePlay = async() => { } global.lx.isPlayedStop &&= false + resetRandomNextMusicInfo() if (global.lx.restorePlayInfo) { void handleRestorePlay(global.lx.restorePlayInfo) @@ -284,6 +285,108 @@ const handleToggleStop = async() => { }) } + +const randomNextMusicInfo = { + info: null as LX.Player.PlayMusicInfo | null, + index: -1, +} +export const resetRandomNextMusicInfo = () => { + if (randomNextMusicInfo.info) { + randomNextMusicInfo.info = null + randomNextMusicInfo.index = -1 + } +} + +export const getNextPlayMusicInfo = async(): Promise => { + if (playerState.tempPlayList.length) { // 如果稍后播放列表存在歌曲则直接播放改列表的歌曲 + const playMusicInfo = playerState.tempPlayList[0] + return playMusicInfo + } + + if (playerState.playMusicInfo.musicInfo == null) return null + + if (randomNextMusicInfo.info) return randomNextMusicInfo.info + + const playMusicInfo = playerState.playMusicInfo + const playInfo = playerState.playInfo + // console.log(playInfo.playerListId) + const currentListId = playInfo.playerListId + if (!currentListId) return null + const currentList = getList(currentListId) + + const playedList = playerState.playedList + if (playedList.length) { // 移除已播放列表内不存在原列表的歌曲 + let currentId: string + if (playMusicInfo.isTempPlay) { + const musicInfo = currentList[playInfo.playerPlayIndex] + if (musicInfo) currentId = musicInfo.id + } else { + currentId = playMusicInfo.musicInfo!.id + } + // 从已播放列表移除播放列表已删除的歌曲 + let index + for (index = playedList.findIndex(m => m.musicInfo.id === currentId) + 1; index < playedList.length; index++) { + const playMusicInfo = playedList[index] + const currentId = playMusicInfo.musicInfo.id + if (playMusicInfo.listId == currentListId && !currentList.some(m => m.id === currentId)) { + removePlayedList(index) + continue + } + break + } + + if (index < playedList.length) return playedList[index] + } + // const isCheckFile = findNum > 2 // 针对下载列表,如果超过两次都碰到无效歌曲,则过滤整个列表内的无效歌曲 + let { filteredList, playerIndex } = await filterList({ // 过滤已播放歌曲 + listId: currentListId, + list: currentList, + playedList, + playerMusicInfo: currentList[playInfo.playerPlayIndex], + isNext: true, + }) + + if (!filteredList.length) return null + // let currentIndex: number = filteredList.indexOf(currentList[playInfo.playerPlayIndex]) + if (playerIndex == -1 && filteredList.length) playerIndex = 0 + let nextIndex = playerIndex + + let togglePlayMethod = settingState.setting['player.togglePlayMethod'] + switch (togglePlayMethod) { + case 'listLoop': + nextIndex = playerIndex === filteredList.length - 1 ? 0 : playerIndex + 1 + break + case 'random': + nextIndex = getRandom(0, filteredList.length) + break + case 'list': + nextIndex = playerIndex === filteredList.length - 1 ? -1 : playerIndex + 1 + break + case 'singleLoop': + break + default: + return null + } + if (nextIndex < 0) return null + + const nextPlayMusicInfo = { + musicInfo: filteredList[nextIndex], + listId: currentListId, + isTempPlay: false, + } + + if (togglePlayMethod == 'random') { + randomNextMusicInfo.info = nextPlayMusicInfo + randomNextMusicInfo.index = nextIndex + } + return nextPlayMusicInfo +} + +const handlePlayNext = async(playMusicInfo: LX.Player.PlayMusicInfo) => { + await pause() + setPlayMusicInfo(playMusicInfo.listId, playMusicInfo.musicInfo, playMusicInfo.isTempPlay) + await handlePlay() +} /** * 下一曲 * @param isAutoToggle 是否自动切换 @@ -293,9 +396,7 @@ export const playNext = async(isAutoToggle = false): Promise => { if (playerState.tempPlayList.length) { // 如果稍后播放列表存在歌曲则直接播放改列表的歌曲 const playMusicInfo = playerState.tempPlayList[0] removeTempPlayList(0) - await pause() - setPlayMusicInfo(playMusicInfo.listId, playMusicInfo.musicInfo, playMusicInfo.isTempPlay) - await handlePlay() + await handlePlayNext(playMusicInfo) return } @@ -331,13 +432,14 @@ export const playNext = async(isAutoToggle = false): Promise => { } if (index < playedList.length) { - const playMusicInfo = playedList[index] - await pause() - setPlayMusicInfo(playMusicInfo.listId, playMusicInfo.musicInfo, playMusicInfo.isTempPlay) - await handlePlay() + await handlePlayNext(playedList[index]) return } } + if (randomNextMusicInfo.info) { + await handlePlayNext(randomNextMusicInfo.info) + return + } // const isCheckFile = findNum > 2 // 针对下载列表,如果超过两次都碰到无效歌曲,则过滤整个列表内的无效歌曲 let { filteredList, playerIndex } = await filterList({ // 过滤已播放歌曲 listId: currentListId, @@ -379,15 +481,11 @@ export const playNext = async(isAutoToggle = false): Promise => { } if (nextIndex < 0) return - const nextPlayMusicInfo = { + await handlePlayNext({ musicInfo: filteredList[nextIndex], listId: currentListId, isTempPlay: false, - } - - await pause() - setPlayMusicInfo(nextPlayMusicInfo.listId, nextPlayMusicInfo.musicInfo) - await handlePlay() + }) } /** @@ -424,10 +522,7 @@ export const playPrev = async(isAutoToggle = false): Promise => { } if (index > -1) { - const playMusicInfo = playedList[index] - await pause() - setPlayMusicInfo(playMusicInfo.listId, playMusicInfo.musicInfo, playMusicInfo.isTempPlay) - await handlePlay() + await handlePlayNext(playedList[index]) return } } @@ -472,15 +567,12 @@ export const playPrev = async(isAutoToggle = false): Promise => { if (nextIndex < 0) return } - const nextPlayMusicInfo = { + + await handlePlayNext({ musicInfo: filteredList[nextIndex], listId: currentListId, isTempPlay: false, - } - - await pause() - setPlayMusicInfo(nextPlayMusicInfo.listId, nextPlayMusicInfo.musicInfo) - await handlePlay() + }) } /** diff --git a/src/utils/request.js b/src/utils/request.js index 37c3e61..5ba2cc3 100644 --- a/src/utils/request.js +++ b/src/utils/request.js @@ -215,3 +215,13 @@ const fetchData = (url, { timeout = 15000, ...options }) => { }, } } + +export const checkUrl = async(url, options = {}) => { + return fetchData(url, { method: 'head', ...options }).request.then(resp => { + if (resp.statusCode === 200) { + return Promise.resolve() + } else { + throw new Error(resp.statusCode) + } + }) +} From ade8d4f2df9514ab53f8df718e63e9ebaaa5a18b Mon Sep 17 00:00:00 2001 From: lyswhut Date: Sat, 23 Nov 2024 14:33:27 +0800 Subject: [PATCH 02/11] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E4=BE=9D=E8=B5=96&?= =?UTF-8?q?=E7=89=88=E6=9C=AC=E5=8F=B7=EF=BC=881.7.0-beta.1=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package-lock.json | 81 ++++++++++++++++++++++++----------------------- package.json | 10 +++--- 2 files changed, 46 insertions(+), 45 deletions(-) diff --git a/package-lock.json b/package-lock.json index 88e504d..0037534 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,15 +10,15 @@ "license": "Apache-2.0", "dependencies": { "@craftzdog/react-native-buffer": "^6.0.5", - "@react-native-async-storage/async-storage": "^2.0.0", - "@react-native-clipboard/clipboard": "^1.14.3", + "@react-native-async-storage/async-storage": "^2.1.0", + "@react-native-clipboard/clipboard": "^1.15.0", "@react-native-community/slider": "^4.5.5", "iconv-lite": "^0.6.3", "lrc-file-parser": "^2.4.1", "message2call": "^0.1.3", "pako": "^2.1.0", "react": "18.2.0", - "react-native": "0.73.10", + "react-native": "0.73.11", "react-native-background-timer": "github:lyswhut/react-native-background-timer#55ecaa80880e9cec1fff81f3ce10e6250ab3c40c", "react-native-exception-handler": "^2.10.10", "react-native-fast-image": "^8.6.3", @@ -52,7 +52,7 @@ "eslint-config-standard-with-typescript": "^43.0.1", "eslint-plugin-react": "^7.37.2", "eslint-plugin-react-hooks": "^5.0.0", - "typescript": "^5.6.3" + "typescript": "^5.7.2" }, "engines": { "node": ">= 18", @@ -2747,9 +2747,9 @@ } }, "node_modules/@react-native-async-storage/async-storage": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@react-native-async-storage/async-storage/-/async-storage-2.0.0.tgz", - "integrity": "sha512-af6H9JjfL6G/PktBfUivvexoiFKQTJGQCtSWxMdivLzNIY94mu9DdiY0JqCSg/LyPCLGKhHPUlRQhNvpu3/KVA==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@react-native-async-storage/async-storage/-/async-storage-2.1.0.tgz", + "integrity": "sha512-eAGQGPTAuFNEoIQSB5j2Jh1zm5NPyBRTfjRMfCN0W1OakC5WIB5vsDyIQhUweKN9XOE2/V07lqTMGsL0dGXNkA==", "license": "MIT", "dependencies": { "merge-options": "^3.0.4" @@ -2759,9 +2759,9 @@ } }, "node_modules/@react-native-clipboard/clipboard": { - "version": "1.14.3", - "resolved": "https://registry.npmjs.org/@react-native-clipboard/clipboard/-/clipboard-1.14.3.tgz", - "integrity": "sha512-EVWxJfCSyBN2SH5b3JrA/w1qlYu3vihQOfdD7fs/BYp63xL6qy93CvbFDHzF8ooFpGM6f67hkAN+gxl1RfOKuw==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@react-native-clipboard/clipboard/-/clipboard-1.15.0.tgz", + "integrity": "sha512-YDMC3E956jn9zE11uKGcQDKS1SO9q72iNHxZyrKY5y9XYwZcA9vo3Xk74+zRnf7cM48drDO0s9lyAPUlOvyhrw==", "license": "MIT", "workspaces": [ "example" @@ -5969,9 +5969,9 @@ } }, "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "license": "MIT", "dependencies": { "path-key": "^3.1.0", @@ -10561,9 +10561,9 @@ "integrity": "sha512-txfpPCQYiazVdcbMRhatqWKcAxJweUu2wDXvts5/7Wyp6+Y9cHojqXHsLPEckzutfHlxZhG8Oiundbmp8Fd6eQ==" }, "node_modules/react-native": { - "version": "0.73.10", - "resolved": "https://registry.npmjs.org/react-native/-/react-native-0.73.10.tgz", - "integrity": "sha512-ucr9GO6iAUi3A1KZ7DjxLtS91QqTw2gJdKwvz5wNK4DCVF3neJyNUPs7fgpGngYtBsio4PaefVOXyrWAklTBXA==", + "version": "0.73.11", + "resolved": "https://registry.npmjs.org/react-native/-/react-native-0.73.11.tgz", + "integrity": "sha512-yvQIX+ZXOHMFnhmwZ1fBpRI/53k+iLN8DxVf24Fx4ABU63RGAYfyCZC0/3W+5OUVx4KSIZUv4Tv+/NGIieBOwg==", "license": "MIT", "dependencies": { "@jest/create-cache-key-function": "^29.6.3", @@ -12729,9 +12729,9 @@ } }, "node_modules/typescript": { - "version": "5.6.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.3.tgz", - "integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==", + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.2.tgz", + "integrity": "sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg==", "dev": true, "license": "Apache-2.0", "bin": { @@ -12869,9 +12869,10 @@ } }, "node_modules/username/node_modules/cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "version": "6.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.6.tgz", + "integrity": "sha512-VqCUuhcd1iB+dsv8gxPttb5iZh/D0iubSP21g36KXdEuf6I5JiioesUVjpCdHV9MZRUfVFlvwtIUyPfxo5trtw==", + "license": "MIT", "optional": true, "peer": true, "dependencies": { @@ -15120,17 +15121,17 @@ "peer": true }, "@react-native-async-storage/async-storage": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@react-native-async-storage/async-storage/-/async-storage-2.0.0.tgz", - "integrity": "sha512-af6H9JjfL6G/PktBfUivvexoiFKQTJGQCtSWxMdivLzNIY94mu9DdiY0JqCSg/LyPCLGKhHPUlRQhNvpu3/KVA==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@react-native-async-storage/async-storage/-/async-storage-2.1.0.tgz", + "integrity": "sha512-eAGQGPTAuFNEoIQSB5j2Jh1zm5NPyBRTfjRMfCN0W1OakC5WIB5vsDyIQhUweKN9XOE2/V07lqTMGsL0dGXNkA==", "requires": { "merge-options": "^3.0.4" } }, "@react-native-clipboard/clipboard": { - "version": "1.14.3", - "resolved": "https://registry.npmjs.org/@react-native-clipboard/clipboard/-/clipboard-1.14.3.tgz", - "integrity": "sha512-EVWxJfCSyBN2SH5b3JrA/w1qlYu3vihQOfdD7fs/BYp63xL6qy93CvbFDHzF8ooFpGM6f67hkAN+gxl1RfOKuw==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@react-native-clipboard/clipboard/-/clipboard-1.15.0.tgz", + "integrity": "sha512-YDMC3E956jn9zE11uKGcQDKS1SO9q72iNHxZyrKY5y9XYwZcA9vo3Xk74+zRnf7cM48drDO0s9lyAPUlOvyhrw==", "requires": {} }, "@react-native-community/cli": { @@ -17591,9 +17592,9 @@ } }, "cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "requires": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -20927,9 +20928,9 @@ "integrity": "sha512-txfpPCQYiazVdcbMRhatqWKcAxJweUu2wDXvts5/7Wyp6+Y9cHojqXHsLPEckzutfHlxZhG8Oiundbmp8Fd6eQ==" }, "react-native": { - "version": "0.73.10", - "resolved": "https://registry.npmjs.org/react-native/-/react-native-0.73.10.tgz", - "integrity": "sha512-ucr9GO6iAUi3A1KZ7DjxLtS91QqTw2gJdKwvz5wNK4DCVF3neJyNUPs7fgpGngYtBsio4PaefVOXyrWAklTBXA==", + "version": "0.73.11", + "resolved": "https://registry.npmjs.org/react-native/-/react-native-0.73.11.tgz", + "integrity": "sha512-yvQIX+ZXOHMFnhmwZ1fBpRI/53k+iLN8DxVf24Fx4ABU63RGAYfyCZC0/3W+5OUVx4KSIZUv4Tv+/NGIieBOwg==", "requires": { "@jest/create-cache-key-function": "^29.6.3", "@react-native-community/cli": "12.3.7", @@ -22575,9 +22576,9 @@ } }, "typescript": { - "version": "5.6.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.3.tgz", - "integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==", + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.2.tgz", + "integrity": "sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg==", "dev": true }, "unbox-primitive": { @@ -22657,9 +22658,9 @@ }, "dependencies": { "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "version": "6.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.6.tgz", + "integrity": "sha512-VqCUuhcd1iB+dsv8gxPttb5iZh/D0iubSP21g36KXdEuf6I5JiioesUVjpCdHV9MZRUfVFlvwtIUyPfxo5trtw==", "optional": true, "peer": true, "requires": { diff --git a/package.json b/package.json index 7342194..1567020 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "lx-music-mobile", - "version": "1.7.0-beta.0", + "version": "1.7.0-beta.1", "versionCode": 69, "private": true, "scripts": { @@ -45,15 +45,15 @@ "homepage": "https://github.com/lyswhut/lx-music-mobile#readme", "dependencies": { "@craftzdog/react-native-buffer": "^6.0.5", - "@react-native-async-storage/async-storage": "^2.0.0", - "@react-native-clipboard/clipboard": "^1.14.3", + "@react-native-async-storage/async-storage": "^2.1.0", + "@react-native-clipboard/clipboard": "^1.15.0", "@react-native-community/slider": "^4.5.5", "iconv-lite": "^0.6.3", "lrc-file-parser": "^2.4.1", "message2call": "^0.1.3", "pako": "^2.1.0", "react": "18.2.0", - "react-native": "0.73.10", + "react-native": "0.73.11", "react-native-background-timer": "github:lyswhut/react-native-background-timer#55ecaa80880e9cec1fff81f3ce10e6250ab3c40c", "react-native-exception-handler": "^2.10.10", "react-native-fast-image": "^8.6.3", @@ -87,6 +87,6 @@ "eslint-config-standard-with-typescript": "^43.0.1", "eslint-plugin-react": "^7.37.2", "eslint-plugin-react-hooks": "^5.0.0", - "typescript": "^5.6.3" + "typescript": "^5.7.2" } } From cda9302eb39a78869633b66b9b207cd262e8c3f0 Mon Sep 17 00:00:00 2001 From: lyswhut Date: Sat, 23 Nov 2024 17:23:09 +0800 Subject: [PATCH 03/11] =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=AD=8C=E6=9B=B2?= =?UTF-8?q?=E7=BC=93=E5=AD=98=E6=9C=BA=E5=88=B6=E5=8F=8A=E6=AD=8C=E6=9B=B2?= =?UTF-8?q?=E7=BC=93=E5=AD=98=E6=A3=80=E6=9F=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package-lock.json | 16 ++++++++-------- package.json | 2 +- publish/changeLog.md | 8 +++++++- src/core/init/player/preloadNextMusic.ts | 5 +++-- src/lang/en_us.json | 1 + src/lang/zh_cn.json | 1 + src/plugins/player/index.ts | 3 ++- src/plugins/player/utils.ts | 19 +++++++++++++++++++ .../Setting/settings/Other/ResourceCache.tsx | 7 +++++-- src/utils/fs.ts | 2 +- 10 files changed, 48 insertions(+), 16 deletions(-) diff --git a/package-lock.json b/package-lock.json index 0037534..c7171ca 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "lx-music-mobile", - "version": "1.7.0-beta.0", + "version": "1.7.0-beta.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "lx-music-mobile", - "version": "1.7.0-beta.0", + "version": "1.7.0-beta.1", "license": "Apache-2.0", "dependencies": { "@craftzdog/react-native-buffer": "^6.0.5", @@ -29,7 +29,7 @@ "react-native-pager-view": "6.3.0", "react-native-quick-base64": "^2.1.2", "react-native-quick-md5": "^3.0.6", - "react-native-track-player": "github:lyswhut/react-native-track-player#930681ab40fdb50f3d0eedff6ecd29b1666fd3ff", + "react-native-track-player": "github:lyswhut/react-native-track-player#23ad66e239170bd9be1b21047f50150ea26f8fd0", "react-native-vector-icons": "^10.2.0" }, "devDependencies": { @@ -10873,8 +10873,8 @@ }, "node_modules/react-native-track-player": { "version": "2.1.2", - "resolved": "git+ssh://git@github.com/lyswhut/react-native-track-player.git#930681ab40fdb50f3d0eedff6ecd29b1666fd3ff", - "integrity": "sha512-i268ePGmDQvImXWi7mRttFnyA3ReIoMY12/40g4qj1OQgkDScDi/00O0QCYfL3pHCQc36pfi40GWNLM4i02Ziw==", + "resolved": "git+ssh://git@github.com/lyswhut/react-native-track-player.git#23ad66e239170bd9be1b21047f50150ea26f8fd0", + "integrity": "sha512-TLiUKfi3LCAzNxv+Qk9a6QCDEaZh2TiCYmqb/dsLqDbXhUnv2KHRBS9f3/IE6n+xXBzOnk5/8khHgn95SSvhRw==", "license": "Apache-2.0", "peerDependencies": { "react": ">=16.8.6", @@ -21483,9 +21483,9 @@ } }, "react-native-track-player": { - "version": "git+ssh://git@github.com/lyswhut/react-native-track-player.git#930681ab40fdb50f3d0eedff6ecd29b1666fd3ff", - "integrity": "sha512-i268ePGmDQvImXWi7mRttFnyA3ReIoMY12/40g4qj1OQgkDScDi/00O0QCYfL3pHCQc36pfi40GWNLM4i02Ziw==", - "from": "react-native-track-player@github:lyswhut/react-native-track-player#930681ab40fdb50f3d0eedff6ecd29b1666fd3ff", + "version": "git+ssh://git@github.com/lyswhut/react-native-track-player.git#23ad66e239170bd9be1b21047f50150ea26f8fd0", + "integrity": "sha512-TLiUKfi3LCAzNxv+Qk9a6QCDEaZh2TiCYmqb/dsLqDbXhUnv2KHRBS9f3/IE6n+xXBzOnk5/8khHgn95SSvhRw==", + "from": "react-native-track-player@github:lyswhut/react-native-track-player#23ad66e239170bd9be1b21047f50150ea26f8fd0", "requires": {} }, "react-native-vector-icons": { diff --git a/package.json b/package.json index 1567020..4b6bfac 100644 --- a/package.json +++ b/package.json @@ -64,7 +64,7 @@ "react-native-pager-view": "6.3.0", "react-native-quick-base64": "^2.1.2", "react-native-quick-md5": "^3.0.6", - "react-native-track-player": "github:lyswhut/react-native-track-player#930681ab40fdb50f3d0eedff6ecd29b1666fd3ff", + "react-native-track-player": "github:lyswhut/react-native-track-player#23ad66e239170bd9be1b21047f50150ea26f8fd0", "react-native-vector-icons": "^10.2.0" }, "devDependencies": { diff --git a/publish/changeLog.md b/publish/changeLog.md index 84742f3..7cc3d59 100644 --- a/publish/changeLog.md +++ b/publish/changeLog.md @@ -1,16 +1,22 @@ +为了防止歌曲缓存被当做第三方软件当做垃圾意外清理,歌曲缓存地址不再存储到缓存目录,若想清理缓存,需去 设置-其他-资源缓存管理 清理。 + +更新到该版本首次播放歌曲时,会将之前的歌曲缓存迁移到新位置,需要等待的时间取决于你已缓存资源的大小。 + ### 新增 - 新增蓝牙歌词支持,可以去 设置-播放设置-显示蓝牙歌词 启用(#615) ### 优化 +- 防止歌曲缓存被当做第三方软件当做垃圾意外清理 - 优化正常播放结束时的下一首歌曲播放衔接度,在歌曲即将播放结束时将预获取下一首歌曲的播放链接,减少自动切歌时的等待时间 - 首次使用的提示窗口可以点击背景或者返回键关闭(#577) - 上移 Toast 位置避免遮挡播放模式图标(#603 @sibojia) ### 变更 -- 不再缓存换源歌曲信息 +- 歌曲缓存地址不再存储到缓存目录 +- 不再长期缓存换源歌曲信息 ### 其他 diff --git a/src/core/init/player/preloadNextMusic.ts b/src/core/init/player/preloadNextMusic.ts index 7583b95..be3b54e 100644 --- a/src/core/init/player/preloadNextMusic.ts +++ b/src/core/init/player/preloadNextMusic.ts @@ -2,6 +2,7 @@ import { getMusicUrl } from '@/core/music' import { getNextPlayMusicInfo, resetRandomNextMusicInfo } from '@/core/player/player' import { checkUrl } from '@/utils/request' import playerState from '@/store/player/state' +import { isCached } from '@/plugins/player/utils' const preloadMusicInfo = { @@ -24,8 +25,8 @@ const preloadNextMusicUrl = async(curTime: number) => { const url = await getMusicUrl({ musicInfo: info.musicInfo }).catch(() => '') if (url) { console.log('preload url', url) - const result = await checkUrl(url).then(() => true).catch(() => false) - if (!result) { + const [cached, available] = await Promise.all([isCached(url), checkUrl(url).then(() => true).catch(() => false)]) + if (!cached && !available) { const url = await getMusicUrl({ musicInfo: info.musicInfo, isRefresh: true }).catch(() => '') console.log('preload url refresh', url) } diff --git a/src/lang/en_us.json b/src/lang/en_us.json index d47e274..bd29a54 100644 --- a/src/lang/en_us.json +++ b/src/lang/en_us.json @@ -201,6 +201,7 @@ "player__geting_url_delay_retry": "The server is busy, try again in {time} seconds...", "player__loading": "Music loading...", "player__refresh_url": "The URL has expired, refreshing the URL...", + "player_cache_migrating": "Song cache is being migrated, please wait ⌛️", "quality_high_quality": "HQ", "quality_lossless": "SQ", "quality_lossless_24bit": "Hires", diff --git a/src/lang/zh_cn.json b/src/lang/zh_cn.json index bc02416..71299d7 100644 --- a/src/lang/zh_cn.json +++ b/src/lang/zh_cn.json @@ -201,6 +201,7 @@ "player__geting_url_delay_retry": "服务器繁忙,{time}秒后重试...", "player__loading": "音乐加载中...", "player__refresh_url": "URL过期,正在刷新URL...", + "player_cache_migrating": "歌曲缓存迁移中,请稍等 ⌛️", "quality_high_quality": "HQ", "quality_lossless": "SQ", "quality_lossless_24bit": "Hires", diff --git a/src/plugins/player/index.ts b/src/plugins/player/index.ts index 1e22f11..2b60f39 100644 --- a/src/plugins/player/index.ts +++ b/src/plugins/player/index.ts @@ -1,5 +1,5 @@ import TrackPlayer from 'react-native-track-player' -import { updateOptions, setVolume, setPlaybackRate } from './utils' +import { updateOptions, setVolume, setPlaybackRate, migratePlayerCache } from './utils' // const listenEvent = () => { // TrackPlayer.addEventListener('playback-error', err => { @@ -26,6 +26,7 @@ const initial = async({ volume, playRate, cacheSize, isHandleAudioFocus, isEnabl if (global.lx.playerStatus.isIniting || global.lx.playerStatus.isInitialized) return global.lx.playerStatus.isIniting = true console.log('Cache Size', cacheSize * 1024) + await migratePlayerCache() await TrackPlayer.setupPlayer({ maxCacheSize: cacheSize * 1024, maxBuffer: 1000, diff --git a/src/plugins/player/utils.ts b/src/plugins/player/utils.ts index 1fe278d..6bb55ff 100644 --- a/src/plugins/player/utils.ts +++ b/src/plugins/player/utils.ts @@ -1,6 +1,8 @@ import TrackPlayer, { Capability, Event, RepeatMode, State } from 'react-native-track-player' import BackgroundTimer from 'react-native-background-timer' import { playMusic as handlePlayMusic } from './playList' +import { existsFile, moveFile, privateStorageDirectoryPath, temporaryDirectoryPath } from '@/utils/fs' +import { toast } from '@/utils/tools' // import { PlayerMusicInfo } from '@/store/modules/player/playInfo' @@ -173,6 +175,23 @@ export const updateNowPlayingTitles = async(duration: number, title: string, art export const resetPlay = async() => Promise.all([setPause(), setCurrentTime(0)]) +export const isCached = async(url: string) => TrackPlayer.isCached(url) +export const getCacheSize = async() => TrackPlayer.getCacheSize() +export const clearCache = async() => TrackPlayer.clearCache() +export const migratePlayerCache = async() => { + const newCachePath = privateStorageDirectoryPath + '/TrackPlayer' + if (await existsFile(newCachePath)) return + const oldCachePath = temporaryDirectoryPath + '/TrackPlayer' + if (!await existsFile(oldCachePath)) return + let timeout: number | null = BackgroundTimer.setTimeout(() => { + timeout = null + toast(global.i18n.t('player_cache_migrating'), 'long') + }, 2_000) + await moveFile(oldCachePath, newCachePath).finally(() => { + if (timeout) BackgroundTimer.clearTimeout(timeout) + }) +} + export const destroy = async() => { if (global.lx.playerStatus.isIniting || !global.lx.playerStatus.isInitialized) return await TrackPlayer.destroy() diff --git a/src/screens/Home/Views/Setting/settings/Other/ResourceCache.tsx b/src/screens/Home/Views/Setting/settings/Other/ResourceCache.tsx index e507dfc..4f05533 100644 --- a/src/screens/Home/Views/Setting/settings/Other/ResourceCache.tsx +++ b/src/screens/Home/Views/Setting/settings/Other/ResourceCache.tsx @@ -7,6 +7,7 @@ import SubTitle from '../../components/SubTitle' import Button from '../../components/Button' import { toast, resetNotificationPermissionCheck, confirmDialog, resetIgnoringBatteryOptimizationCheck } from '@/utils/tools' import { getAppCacheSize, clearAppCache } from '@/utils/nativeModules/cache' +import { getCacheSize, clearCache } from '@/plugins/player/utils' import { sizeFormate } from '@/utils' import { useI18n } from '@/lang' import Text from '@/components/common/Text' @@ -21,8 +22,9 @@ export default memo(() => { // const clearCache = useDispatch('list', 'clearCache') const handleGetAppCacheSize = () => { - void getAppCacheSize().then(size => { - setCacheSize(sizeFormate(size)) + void Promise.all([getAppCacheSize(), getCacheSize()]).then(([size, size2]) => { + const count = size + size2 + setCacheSize(sizeFormate(count as number)) }) } @@ -36,6 +38,7 @@ export default memo(() => { setCleaning(true) void Promise.all([ clearAppCache(), + clearCache(), clearMusicUrl(), resetNotificationPermissionCheck(), resetIgnoringBatteryOptimizationCheck(), diff --git a/src/utils/fs.ts b/src/utils/fs.ts index 1fc400e..161a1ee 100644 --- a/src/utils/fs.ts +++ b/src/utils/fs.ts @@ -43,7 +43,7 @@ export const readFile = async(path: string, encoding?: Encoding) => FileSystem.r // export const copyFile = async(fromPath: string, toPath: string) => FileSystem.cp(fromPath, toPath) -// export const moveFile = async(fromPath: string, toPath: string) => FileSystem.mv(fromPath, toPath) +export const moveFile = async(fromPath: string, toPath: string) => FileSystem.mv(fromPath, toPath) export const gzipFile = async(fromPath: string, toPath: string) => FileSystem.gzipFile(fromPath, toPath) export const unGzipFile = async(fromPath: string, toPath: string) => FileSystem.unGzipFile(fromPath, toPath) export const gzipString = async(data: string, encoding?: Encoding) => FileSystem.gzipString(data, encoding) From e237e2540e7ed9273f627c0d21542126a30a8293 Mon Sep 17 00:00:00 2001 From: lyswhut Date: Sun, 24 Nov 2024 00:06:13 +0800 Subject: [PATCH 04/11] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E5=85=B3=E4=BA=8E?= =?UTF-8?q?=E8=AF=B4=E6=98=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Home/Views/Setting/settings/About.tsx | 26 +++++++++++-------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/src/screens/Home/Views/Setting/settings/About.tsx b/src/screens/Home/Views/Setting/settings/About.tsx index 98798af..1f177ba 100644 --- a/src/screens/Home/Views/Setting/settings/About.tsx +++ b/src/screens/Home/Views/Setting/settings/About.tsx @@ -11,9 +11,9 @@ import { useI18n } from '@/lang' import Text from '@/components/common/Text' import { showPactModal } from '@/core/common' -const qqGroupUrl = 'mqqopensdkapi://bizAgent/qm/qr?url=http%3A%2F%2Fqm.qq.com%2Fcgi-bin%2Fqm%2Fqr%3Ffrom%3Dapp%26p%3Dandroid%26jump_from%3Dwebapi%26k%3Du1zyxek8roQAwic44nOkBXtG9CfbAxFw' +// const qqGroupUrl = 'mqqopensdkapi://bizAgent/qm/qr?url=http%3A%2F%2Fqm.qq.com%2Fcgi-bin%2Fqm%2Fqr%3Ffrom%3Dapp%26p%3Dandroid%26jump_from%3Dwebapi%26k%3Du1zyxek8roQAwic44nOkBXtG9CfbAxFw' // const qqGroupUrl2 = 'mqqopensdkapi://bizAgent/qm/qr?url=http%3A%2F%2Fqm.qq.com%2Fcgi-bin%2Fqm%2Fqr%3Ffrom%3Dapp%26p%3Dandroid%26jump_from%3Dwebapi%26k%3D-l4kNZ2bPQAuvfCQFFhl1UoibvF5wcrQ' -const qqGroupWebUrl = 'https://qm.qq.com/cgi-bin/qm/qr?k=jRZkyFSZ4FmUuTHA3P_RAXbbUO_Rrn5e&jump_from=webapi' +// const qqGroupWebUrl = 'https://qm.qq.com/cgi-bin/qm/qr?k=jRZkyFSZ4FmUuTHA3P_RAXbbUO_Rrn5e&jump_from=webapi' // const qqGroupWebUrl2 = 'https://qm.qq.com/cgi-bin/qm/qr?k=HPNJEfrZpBZ9T8szYWbe2d5JrAAeOt_l&jump_from=webapi' export default memo(() => { @@ -22,6 +22,9 @@ export default memo(() => { const openHomePage = () => { void openUrl('https://github.com/lyswhut/lx-music-mobile#readme') } + const openIssuePage = () => { + void openUrl('https://github.com/lyswhut/lx-music-mobile/issues') + } const openNetdiskPage = () => { void openUrl('https://www.lanzoui.com/b0bf2cfa/') } @@ -38,11 +41,11 @@ export default memo(() => { void openUrl('https://github.com/lyswhut/lx-music-mobile#%E9%A1%B9%E7%9B%AE%E5%8D%8F%E8%AE%AE') } - const goToQQGroup = () => { - openUrl(qqGroupUrl).catch(() => { - void openUrl(qqGroupWebUrl) - }) - } + // const goToQQGroup = () => { + // openUrl(qqGroupUrl).catch(() => { + // void openUrl(qqGroupWebUrl) + // }) + // } // const goToQQGroup2 = () => { // openUrl(qqGroupUrl2).catch(() => { // void openUrl(qqGroupWebUrl2) @@ -66,7 +69,7 @@ export default memo(() => { - 最新版网盘下载地址: + 最新版网盘下载地址: 网盘地址(密码:glqw) @@ -79,10 +82,11 @@ export default memo(() => { 本软件没有客服,但我们整理了一些常见的使用问题,仔细 仔细 仔细 地阅读常见问题后, - 仍有问题可加企鹅群 - 830125506 + 仍有问题可到 GitHub 发 + + issue + 反馈。 - 注意:为免满人,无事勿加,入群先看群公告 目前本项目的原始发布地址只有GitHub蓝奏网盘,其他渠道均为第三方转载发布,可信度请自行鉴别。 From 27d7fba3b3d0b975c7b580dd38c94ed470a3a1af Mon Sep 17 00:00:00 2001 From: lyswhut Date: Sun, 24 Nov 2024 14:28:49 +0800 Subject: [PATCH 05/11] =?UTF-8?q?=E6=9B=B4=E6=96=B0=20android=20=E4=BE=9D?= =?UTF-8?q?=E8=B5=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- android/app/build.gradle | 2 +- android/build.gradle | 4 ++-- package-lock.json | 12 ++++++------ package.json | 2 +- publish/changeLog.md | 4 ++-- 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/android/app/build.gradle b/android/app/build.gradle index 06c47e1..81f37a5 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -193,7 +193,7 @@ dependencies { implementation("com.facebook.react:flipper-integration") // implementation "androidx.javascriptengine:javascriptengine:1.0.0-alpha07" // implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3") - implementation group: 'wang.harlon.quickjs', name: 'wrapper-android', version: '1.0.0' + implementation 'wang.harlon.quickjs:wrapper-android:2.4.0' if (hermesEnabled.toBoolean()) { implementation("com.facebook.react:hermes-android") diff --git a/android/build.gradle b/android/build.gradle index 3fecac4..6ea5951 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -2,9 +2,9 @@ buildscript { ext { - buildToolsVersion = "34.0.0" + buildToolsVersion = "35.0.0" minSdkVersion = 21 - compileSdkVersion = 34 + compileSdkVersion = 35 targetSdkVersion = 29 ndkVersion = "25.1.8937393" diff --git a/package-lock.json b/package-lock.json index c7171ca..a3bd09c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -29,7 +29,7 @@ "react-native-pager-view": "6.3.0", "react-native-quick-base64": "^2.1.2", "react-native-quick-md5": "^3.0.6", - "react-native-track-player": "github:lyswhut/react-native-track-player#23ad66e239170bd9be1b21047f50150ea26f8fd0", + "react-native-track-player": "github:lyswhut/react-native-track-player#bbd330795e9b06177f00441286a4f4cab72d5ed5", "react-native-vector-icons": "^10.2.0" }, "devDependencies": { @@ -10873,8 +10873,8 @@ }, "node_modules/react-native-track-player": { "version": "2.1.2", - "resolved": "git+ssh://git@github.com/lyswhut/react-native-track-player.git#23ad66e239170bd9be1b21047f50150ea26f8fd0", - "integrity": "sha512-TLiUKfi3LCAzNxv+Qk9a6QCDEaZh2TiCYmqb/dsLqDbXhUnv2KHRBS9f3/IE6n+xXBzOnk5/8khHgn95SSvhRw==", + "resolved": "git+ssh://git@github.com/lyswhut/react-native-track-player.git#bbd330795e9b06177f00441286a4f4cab72d5ed5", + "integrity": "sha512-jMJPaI8o3trtxE9QL/RAXoCHRhp148oz4tUsoxK4lXkw6Kg+Ij1x0RxFJHaK1T4vkrCGyoe+AJvXvY7Ni0HUUA==", "license": "Apache-2.0", "peerDependencies": { "react": ">=16.8.6", @@ -21483,9 +21483,9 @@ } }, "react-native-track-player": { - "version": "git+ssh://git@github.com/lyswhut/react-native-track-player.git#23ad66e239170bd9be1b21047f50150ea26f8fd0", - "integrity": "sha512-TLiUKfi3LCAzNxv+Qk9a6QCDEaZh2TiCYmqb/dsLqDbXhUnv2KHRBS9f3/IE6n+xXBzOnk5/8khHgn95SSvhRw==", - "from": "react-native-track-player@github:lyswhut/react-native-track-player#23ad66e239170bd9be1b21047f50150ea26f8fd0", + "version": "git+ssh://git@github.com/lyswhut/react-native-track-player.git#bbd330795e9b06177f00441286a4f4cab72d5ed5", + "integrity": "sha512-jMJPaI8o3trtxE9QL/RAXoCHRhp148oz4tUsoxK4lXkw6Kg+Ij1x0RxFJHaK1T4vkrCGyoe+AJvXvY7Ni0HUUA==", + "from": "react-native-track-player@github:lyswhut/react-native-track-player#bbd330795e9b06177f00441286a4f4cab72d5ed5", "requires": {} }, "react-native-vector-icons": { diff --git a/package.json b/package.json index 4b6bfac..c44ce05 100644 --- a/package.json +++ b/package.json @@ -64,7 +64,7 @@ "react-native-pager-view": "6.3.0", "react-native-quick-base64": "^2.1.2", "react-native-quick-md5": "^3.0.6", - "react-native-track-player": "github:lyswhut/react-native-track-player#23ad66e239170bd9be1b21047f50150ea26f8fd0", + "react-native-track-player": "github:lyswhut/react-native-track-player#bbd330795e9b06177f00441286a4f4cab72d5ed5", "react-native-vector-icons": "^10.2.0" }, "devDependencies": { diff --git a/publish/changeLog.md b/publish/changeLog.md index 7cc3d59..747cbb7 100644 --- a/publish/changeLog.md +++ b/publish/changeLog.md @@ -1,4 +1,4 @@ -为了防止歌曲缓存被当做第三方软件当做垃圾意外清理,歌曲缓存地址不再存储到缓存目录,若想清理缓存,需去 设置-其他-资源缓存管理 清理。 +为了防止歌曲缓存被第三方软件当做垃圾意外清理,歌曲缓存地址不再存储到缓存目录,若想清理缓存,需去 设置-其他-资源缓存管理 清理。 更新到该版本首次播放歌曲时,会将之前的歌曲缓存迁移到新位置,需要等待的时间取决于你已缓存资源的大小。 @@ -8,7 +8,7 @@ ### 优化 -- 防止歌曲缓存被当做第三方软件当做垃圾意外清理 +- 防止歌曲缓存被第三方软件当做垃圾意外清理 - 优化正常播放结束时的下一首歌曲播放衔接度,在歌曲即将播放结束时将预获取下一首歌曲的播放链接,减少自动切歌时的等待时间 - 首次使用的提示窗口可以点击背景或者返回键关闭(#577) - 上移 Toast 位置避免遮挡播放模式图标(#603 @sibojia) From c21122a753de853e0ec6d9348c6e65571968bd4a Mon Sep 17 00:00:00 2001 From: lyswhut Date: Mon, 25 Nov 2024 18:23:04 +0800 Subject: [PATCH 06/11] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E8=93=9D=E7=89=99?= =?UTF-8?q?=E6=AD=8C=E8=AF=8D=E5=9C=A8=E6=9B=B4=E6=96=B0=E6=98=AF=E5=B0=81?= =?UTF-8?q?=E9=9D=A2=E4=B8=A2=E5=A4=B1=E7=9A=84=E9=97=AE=E9=A2=98=EF=BC=88?= =?UTF-8?q?1.7.0-beta.2=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package-lock.json | 12 ++++++------ package.json | 4 ++-- publish/changeLog.md | 2 +- src/core/music/utils.ts | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/package-lock.json b/package-lock.json index a3bd09c..0269540 100644 --- a/package-lock.json +++ b/package-lock.json @@ -29,7 +29,7 @@ "react-native-pager-view": "6.3.0", "react-native-quick-base64": "^2.1.2", "react-native-quick-md5": "^3.0.6", - "react-native-track-player": "github:lyswhut/react-native-track-player#bbd330795e9b06177f00441286a4f4cab72d5ed5", + "react-native-track-player": "github:lyswhut/react-native-track-player#01873f81e30de85ab96363ad7351cf4bdcd39e37", "react-native-vector-icons": "^10.2.0" }, "devDependencies": { @@ -10873,8 +10873,8 @@ }, "node_modules/react-native-track-player": { "version": "2.1.2", - "resolved": "git+ssh://git@github.com/lyswhut/react-native-track-player.git#bbd330795e9b06177f00441286a4f4cab72d5ed5", - "integrity": "sha512-jMJPaI8o3trtxE9QL/RAXoCHRhp148oz4tUsoxK4lXkw6Kg+Ij1x0RxFJHaK1T4vkrCGyoe+AJvXvY7Ni0HUUA==", + "resolved": "git+ssh://git@github.com/lyswhut/react-native-track-player.git#01873f81e30de85ab96363ad7351cf4bdcd39e37", + "integrity": "sha512-bJJiUPEXkSJ9mVkitfgTh7/7jONRZorktn1rpGpHTZzqaL4qKpiCgUy0y1w0uhMZvubmASlgujAHu6lxl2ZGaA==", "license": "Apache-2.0", "peerDependencies": { "react": ">=16.8.6", @@ -21483,9 +21483,9 @@ } }, "react-native-track-player": { - "version": "git+ssh://git@github.com/lyswhut/react-native-track-player.git#bbd330795e9b06177f00441286a4f4cab72d5ed5", - "integrity": "sha512-jMJPaI8o3trtxE9QL/RAXoCHRhp148oz4tUsoxK4lXkw6Kg+Ij1x0RxFJHaK1T4vkrCGyoe+AJvXvY7Ni0HUUA==", - "from": "react-native-track-player@github:lyswhut/react-native-track-player#bbd330795e9b06177f00441286a4f4cab72d5ed5", + "version": "git+ssh://git@github.com/lyswhut/react-native-track-player.git#01873f81e30de85ab96363ad7351cf4bdcd39e37", + "integrity": "sha512-bJJiUPEXkSJ9mVkitfgTh7/7jONRZorktn1rpGpHTZzqaL4qKpiCgUy0y1w0uhMZvubmASlgujAHu6lxl2ZGaA==", + "from": "react-native-track-player@github:lyswhut/react-native-track-player#01873f81e30de85ab96363ad7351cf4bdcd39e37", "requires": {} }, "react-native-vector-icons": { diff --git a/package.json b/package.json index c44ce05..53a53d0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "lx-music-mobile", - "version": "1.7.0-beta.1", + "version": "1.7.0-beta.2", "versionCode": 69, "private": true, "scripts": { @@ -64,7 +64,7 @@ "react-native-pager-view": "6.3.0", "react-native-quick-base64": "^2.1.2", "react-native-quick-md5": "^3.0.6", - "react-native-track-player": "github:lyswhut/react-native-track-player#bbd330795e9b06177f00441286a4f4cab72d5ed5", + "react-native-track-player": "github:lyswhut/react-native-track-player#01873f81e30de85ab96363ad7351cf4bdcd39e37", "react-native-vector-icons": "^10.2.0" }, "devDependencies": { diff --git a/publish/changeLog.md b/publish/changeLog.md index 747cbb7..f0d6b8e 100644 --- a/publish/changeLog.md +++ b/publish/changeLog.md @@ -20,4 +20,4 @@ ### 其他 -react-native → 0.73.10 +react-native → 0.73.11 diff --git a/src/core/music/utils.ts b/src/core/music/utils.ts index c38c539..ad10782 100644 --- a/src/core/music/utils.ts +++ b/src/core/music/utils.ts @@ -58,7 +58,7 @@ export const getOtherSource = async(musicInfo: LX.Music.MusicInfo | LX.Download. reject(new Error('find music timeout')) }, 12_000) findMusic(searchMusicInfo).then((otherSource) => { - if (otherSourceCache.size > 100) otherSourceCache.clear() + if (otherSourceCache.size > 10) otherSourceCache.clear() const source = otherSource.map(toNewMusicInfo) as LX.Music.MusicInfoOnline[] otherSourceCache.set(musicInfo, source) resolve(source) From 6c6571e704412f81d007826e44a1b2912fd88dc3 Mon Sep 17 00:00:00 2001 From: lyswhut Date: Wed, 27 Nov 2024 13:02:52 +0800 Subject: [PATCH 07/11] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=90=AF=E7=94=A8?= =?UTF-8?q?=E6=A1=8C=E9=9D=A2=E6=AD=8C=E8=AF=8D=E6=97=B6=E8=93=9D=E7=89=99?= =?UTF-8?q?=E6=AD=8C=E8=AF=8D=E5=9C=A8=E9=94=81=E5=B1=8F=E5=90=8E=E8=A2=AB?= =?UTF-8?q?=E6=9A=82=E5=81=9C=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cn/toside/music/mobile/lyric/Lyric.java | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/android/app/src/main/java/cn/toside/music/mobile/lyric/Lyric.java b/android/app/src/main/java/cn/toside/music/mobile/lyric/Lyric.java index 3503d23..08ab659 100644 --- a/android/app/src/main/java/cn/toside/music/mobile/lyric/Lyric.java +++ b/android/app/src/main/java/cn/toside/music/mobile/lyric/Lyric.java @@ -30,6 +30,7 @@ public class Lyric extends LyricPlayer { boolean isShowRoma; boolean isShowLyricView = false; boolean isSendLyricTextEvent = false; + boolean isScreenOff = false; String lyricText = ""; String translationText = ""; String romaLyricText = ""; @@ -102,22 +103,20 @@ public class Lyric extends LyricPlayer { // } // } + private boolean isDisableAutoPause() { + return !isRunPlayer || isSendLyricTextEvent; + } private void handleScreenOff() { - if (!isRunPlayer || !isShowLyricView) return; + isScreenOff = true; + if (isDisableAutoPause()) return; setTempPause(true); - - if (lyricView != null) { - lyricView.runOnUiThread(() -> { - lyricView.destroyView(); - }); - } } private void handleScreenOn() { - if (!isRunPlayer || !isShowLyricView) return; + isScreenOff = false; + if (isDisableAutoPause()) return; if (lyricView == null) lyricView = new LyricView(reactAppContext, lyricEvent); lyricView.runOnUiThread(() -> { - lyricView.showLyricView(); handleGetCurrentLyric(lastLine); setTempPause(false); }); @@ -130,7 +129,7 @@ public class Lyric extends LyricPlayer { } private void setCurrentLyric(String lyric, ArrayList extendedLyrics) { - if (isShowLyricView && lyricView != null) { + if (isShowLyricView && !isScreenOff && lyricView != null) { lyricView.setLyric(lyric, extendedLyrics); } if (isSendLyricTextEvent) { From c79e521b29a04c3f9fc9f9c75821e1ee8ba6df60 Mon Sep 17 00:00:00 2001 From: lyswhut Date: Wed, 27 Nov 2024 13:04:11 +0800 Subject: [PATCH 08/11] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E7=89=88=E6=9C=AC?= =?UTF-8?q?=E5=8F=B7=EF=BC=881.7.0-beta.3=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 0269540..fb66d66 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "lx-music-mobile", - "version": "1.7.0-beta.1", + "version": "1.7.0-beta.3", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "lx-music-mobile", - "version": "1.7.0-beta.1", + "version": "1.7.0-beta.3", "license": "Apache-2.0", "dependencies": { "@craftzdog/react-native-buffer": "^6.0.5", diff --git a/package.json b/package.json index 53a53d0..8dc74b8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "lx-music-mobile", - "version": "1.7.0-beta.2", + "version": "1.7.0-beta.3", "versionCode": 69, "private": true, "scripts": { From e74771761e6f6022be6b6df3e9297857e7235e95 Mon Sep 17 00:00:00 2001 From: lyswhut Date: Fri, 29 Nov 2024 12:12:09 +0800 Subject: [PATCH 09/11] =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=AD=8C=E6=9B=B2?= =?UTF-8?q?=E6=8D=A2=E6=BA=90=E6=9C=BA=E5=88=B6=EF=BC=8C=E6=8F=90=E5=8D=87?= =?UTF-8?q?=E6=8D=A2=E6=BA=90=E6=AD=A3=E7=A1=AE=E7=8E=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- publish/changeLog.md | 1 + src/utils/musicSdk/index.js | 98 +++++++++++++++++++++---------------- 2 files changed, 57 insertions(+), 42 deletions(-) diff --git a/publish/changeLog.md b/publish/changeLog.md index f0d6b8e..e50fde6 100644 --- a/publish/changeLog.md +++ b/publish/changeLog.md @@ -10,6 +10,7 @@ - 防止歌曲缓存被第三方软件当做垃圾意外清理 - 优化正常播放结束时的下一首歌曲播放衔接度,在歌曲即将播放结束时将预获取下一首歌曲的播放链接,减少自动切歌时的等待时间 +- 优化歌曲换源机制,提升换源正确率 - 首次使用的提示窗口可以点击背景或者返回键关闭(#577) - 上移 Toast 位置避免遮挡播放模式图标(#603 @sibojia) diff --git a/src/utils/musicSdk/index.js b/src/utils/musicSdk/index.js index ae2d683..14d38ee 100644 --- a/src/utils/musicSdk/index.js +++ b/src/utils/musicSdk/index.js @@ -78,15 +78,16 @@ export const findMusic = async(musicInfo) => { const singersRxp = /、|&|;|;|\/|,|,|\|/ const sortSingle = singer => singersRxp.test(singer) ? singer.split(singersRxp).sort((a, b) => a.localeCompare(b)).join('、') - : singer + : (singer || '') const sortMusic = (arr, callback) => { const tempResult = [] for (let i = arr.length - 1; i > -1; i--) { const item = arr[i] if (callback(item)) { - delete item.sortedSinger - delete item.lowerCaseName - delete item.lowerCaseAlbumName + delete item.fSinger + delete item.fMusicName + delete item.fAlbumName + delete item.fInterval tempResult.push(item) arr.splice(i, 1) } @@ -94,55 +95,68 @@ export const findMusic = async(musicInfo) => { tempResult.reverse() return tempResult } - const trimStr = str => typeof str == 'string' ? str.trim() : str - const filterStr = str => typeof str == 'string' ? str.replace(/\s|'|\.|,|,|&|"|、|\(|\)|(|)|`|~|-|<|>|\||\/|\]|\[/g, '') : str - const musicName = trimStr(name) - const sortedSinger = filterStr(String(sortSingle(singer)).toLowerCase()) - const lowerCaseName = filterStr(String(musicName).toLowerCase()) - const lowerCaseAlbumName = filterStr(String(albumName).toLowerCase()) + const getIntv = (interval) => { + if (!interval) return 0 + // if (musicInfo._interval) return musicInfo._interval + let intvArr = interval.split(':') + let intv = 0 + let unit = 1 + while (intvArr.length) { + intv += parseInt(intvArr.pop()) * unit + unit *= 60 + } + return intv + } + const trimStr = str => typeof str == 'string' ? str.trim() : (str || '') + const filterStr = str => typeof str == 'string' ? str.replace(/\s|'|\.|,|,|&|"|、|\(|\)|(|)|`|~|-|<|>|\||\/|\]|\[|!|!/g, '') : String(str || '') + const fMusicName = filterStr(name).toLowerCase() + const fSinger = filterStr(sortSingle(singer)).toLowerCase() + const fAlbumName = filterStr(albumName).toLowerCase() + const fInterval = getIntv(interval) + const isEqualsInterval = (intv) => Math.abs((fInterval || intv) - (intv || fInterval)) < 5 + const isIncludesName = (name) => (fMusicName.includes(name) || name.includes(fMusicName)) + const isIncludesSinger = (singer) => fSinger ? (fSinger.includes(singer) || singer.includes(fSinger)) : true + const isEqualsAlbum = (album) => fAlbumName ? fAlbumName == album : true const result = lists.map(source => { for (const item of source.list) { item.name = trimStr(item.name) - item.sortedSinger = filterStr(String(sortSingle(item.singer)).toLowerCase()) - item.lowerCaseName = filterStr(String(item.name ?? '').toLowerCase()) - item.lowerCaseAlbumName = filterStr(String(item.albumName ?? '').toLowerCase()) - // console.log(lowerCaseName, item.lowerCaseName, item.source) - if ( - ( - item.sortedSinger == sortedSinger && item.lowerCaseName == lowerCaseName - ) || - ( - (interval ? item.interval == interval : true) && item.lowerCaseName == lowerCaseName && - (item.sortedSinger.includes(sortedSinger) || sortedSinger.includes(item.sortedSinger)) - ) || - ( - item.lowerCaseName == lowerCaseName && (lowerCaseAlbumName ? item.lowerCaseAlbumName == lowerCaseAlbumName : true) && - (interval ? item.interval == interval : true) - ) || - ( - item.lowerCaseName == lowerCaseName && (lowerCaseAlbumName ? item.lowerCaseAlbumName == lowerCaseAlbumName : true) && - (item.sortedSinger.includes(sortedSinger) || sortedSinger.includes(item.sortedSinger)) - ) - ) { - return item - } - if (!singer) { - if (item.lowerCaseName == lowerCaseName && (interval ? item.interval == interval : true)) return item + item.singer = trimStr(item.singer) + item.fSinger = filterStr(sortSingle(item.singer).toLowerCase()) + item.fMusicName = filterStr(String(item.name ?? '').toLowerCase()) + item.fAlbumName = filterStr(String(item.albumName ?? '').toLowerCase()) + item.fInterval = getIntv(item.interval) + // console.log(fMusicName, item.fMusicName, item.source) + if (!isEqualsInterval(item.fInterval)) { + item.name = null + continue } + if (item.fMusicName == fMusicName && isIncludesSinger(item.fSinger)) return item + } + for (const item of source.list) { + if (item.name == null) continue + if (item.fSinger == fSinger && isIncludesName(item.fMusicName)) return item + } + for (const item of source.list) { + if (item.name == null) continue + if (isEqualsAlbum(item.fAlbumName) && isIncludesSinger(item.fSinger) && isIncludesName(item.fMusicName)) return item } return null }).filter(s => s) const newResult = [] if (result.length) { - newResult.push(...sortMusic(result, item => item.sortedSinger == sortedSinger && item.lowerCaseName == lowerCaseName && item.interval == interval)) - newResult.push(...sortMusic(result, item => item.lowerCaseName == lowerCaseName && item.sortedSinger == sortedSinger && item.lowerCaseAlbumName == lowerCaseAlbumName)) - newResult.push(...sortMusic(result, item => item.sortedSinger == sortedSinger && item.lowerCaseName == lowerCaseName)) - newResult.push(...sortMusic(result, item => item.sortedSinger == sortedSinger && item.interval == interval)) + newResult.push(...sortMusic(result, item => item.fSinger == fSinger && item.fMusicName == fMusicName && item.interval == interval)) + newResult.push(...sortMusic(result, item => item.fMusicName == fMusicName && item.fSinger == fSinger && item.fAlbumName == fAlbumName)) + newResult.push(...sortMusic(result, item => item.fSinger == fSinger && item.fMusicName == fMusicName)) + newResult.push(...sortMusic(result, item => item.fMusicName == fMusicName)) + newResult.push(...sortMusic(result, item => item.fSinger == fSinger)) + newResult.push(...sortMusic(result, item => item.fAlbumName == fAlbumName)) + newResult.push(...sortMusic(result, item => item.interval == interval)) for (const item of result) { - delete item.sortedSinger - delete item.lowerCaseName - delete item.lowerCaseAlbumName + delete item.fSinger + delete item.fMusicName + delete item.fAlbumName + delete item.fInterval } newResult.push(...result) } From 84a7811c0954d4bc9044e8ff2910373140476341 Mon Sep 17 00:00:00 2001 From: lyswhut Date: Sat, 30 Nov 2024 11:54:00 +0800 Subject: [PATCH 10/11] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dkg=20id=E9=87=8D?= =?UTF-8?q?=E5=A4=8D=E5=AF=BC=E8=87=B4=E7=9A=84=E5=88=97=E8=A1=A8=E6=98=BE?= =?UTF-8?q?=E7=A4=BA=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/utils/index.ts | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/utils/index.ts b/src/utils/index.ts index a6d0a38..63fc3ed 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -30,6 +30,14 @@ export const toNewMusicInfo = (oldMusicInfo: any): LX.Music.MusicInfo => { albumName: oldMusicInfo.albumName, // 歌曲专辑名称 picUrl: oldMusicInfo.img, // 歌曲图片链接 } + const newInfo = { + id: `${oldMusicInfo.source as string}_${oldMusicInfo.songmid as string}`, + name: oldMusicInfo.name, + singer: oldMusicInfo.singer, + source: oldMusicInfo.source, + interval: oldMusicInfo.interval, + meta: meta as LX.Music.MusicInfoOnline['meta'], + } if (oldMusicInfo.source == 'local') { meta.filePath = oldMusicInfo.filePath ?? oldMusicInfo.songmid ?? '' @@ -51,6 +59,7 @@ export const toNewMusicInfo = (oldMusicInfo: any): LX.Music.MusicInfo => { switch (oldMusicInfo.source) { case 'kg': meta.hash = oldMusicInfo.hash + newInfo.id = oldMusicInfo.songmid + '_' + oldMusicInfo.hash break case 'tx': meta.strMediaMid = oldMusicInfo.strMediaMid @@ -66,14 +75,7 @@ export const toNewMusicInfo = (oldMusicInfo: any): LX.Music.MusicInfo => { } } - return { - id: `${oldMusicInfo.source as string}_${oldMusicInfo.songmid as string}`, - name: oldMusicInfo.name, - singer: oldMusicInfo.singer, - source: oldMusicInfo.source, - interval: oldMusicInfo.interval, - meta: meta as LX.Music.MusicInfoOnline['meta'], - } + return newInfo } export const toOldMusicInfo = (minfo: LX.Music.MusicInfo): any => { From 37666bf83ec0b8c9f077e44fefb91cd62f6c17d5 Mon Sep 17 00:00:00 2001 From: lyswhut Date: Sat, 30 Nov 2024 18:58:02 +0800 Subject: [PATCH 11/11] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E7=89=88=E6=9C=AC?= =?UTF-8?q?=E5=8F=B7=EF=BC=881.7.0-beta.4=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index fb66d66..8bcd450 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "lx-music-mobile", - "version": "1.7.0-beta.3", + "version": "1.7.0-beta.4", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "lx-music-mobile", - "version": "1.7.0-beta.3", + "version": "1.7.0-beta.4", "license": "Apache-2.0", "dependencies": { "@craftzdog/react-native-buffer": "^6.0.5", diff --git a/package.json b/package.json index 8dc74b8..b9a586d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "lx-music-mobile", - "version": "1.7.0-beta.3", + "version": "1.7.0-beta.4", "versionCode": 69, "private": true, "scripts": {