From 096c7c22274d56c3126a553317687087afaaae7f Mon Sep 17 00:00:00 2001 From: mebtte Date: Sun, 14 Apr 2024 17:53:41 +0800 Subject: [PATCH] detect usability of music file --- apps/pwa/src/components/file_select.tsx | 7 ++- apps/pwa/src/i18n/en_us.ts | 1 + apps/pwa/src/i18n/zh_hans.ts | 1 + .../my_music/create_music_dialog/index.tsx | 58 +++++++++++-------- .../my_music/create_music_dialog/utils.ts | 15 +++++ 5 files changed, 56 insertions(+), 26 deletions(-) diff --git a/apps/pwa/src/components/file_select.tsx b/apps/pwa/src/components/file_select.tsx index 31578d9a..bda7fad5 100644 --- a/apps/pwa/src/components/file_select.tsx +++ b/apps/pwa/src/components/file_select.tsx @@ -1,5 +1,4 @@ import styled, { css } from 'styled-components'; -import upperCaseFirstLetter from '@/style/upper_case_first_letter'; import { CSSVariable } from '../global_style'; import useEvent from '../utils/use_event'; import selectFile from '../utils/select_file'; @@ -16,6 +15,10 @@ const Style = styled.div<{ disabled: boolean }>` user-select: none; word-break: break-all; + > .placeholder { + color: ${CSSVariable.TEXT_COLOR_SECONDARY}; + } + &:active { border-color: ${CSSVariable.COLOR_PRIMARY}; border-style: solid; @@ -60,7 +63,7 @@ function FileSelect({ return ( ); } diff --git a/apps/pwa/src/i18n/en_us.ts b/apps/pwa/src/i18n/en_us.ts index 11315152..55bf9c86 100644 --- a/apps/pwa/src/i18n/en_us.ts +++ b/apps/pwa/src/i18n/en_us.ts @@ -223,4 +223,5 @@ export default { feedback: 'feedback', fork_from_these_musics: 'fork from these musics', forked_by_these_musics: 'forked by these musics', + can_not_play_audio_file: 'this file can not be played', }; diff --git a/apps/pwa/src/i18n/zh_hans.ts b/apps/pwa/src/i18n/zh_hans.ts index f69126e9..522261a1 100644 --- a/apps/pwa/src/i18n/zh_hans.ts +++ b/apps/pwa/src/i18n/zh_hans.ts @@ -211,6 +211,7 @@ const zhCN: { feedback: '反馈', fork_from_these_musics: '二次创作自以下音乐', forked_by_these_musics: '被以下音乐二次创作', + can_not_play_audio_file: '音乐文件无法被播放', }; export default zhCN; diff --git a/apps/pwa/src/pages/player/pages/my_music/create_music_dialog/index.tsx b/apps/pwa/src/pages/player/pages/my_music/create_music_dialog/index.tsx index 9bcb724f..f779ab76 100644 --- a/apps/pwa/src/pages/player/pages/my_music/create_music_dialog/index.tsx +++ b/apps/pwa/src/pages/player/pages/my_music/create_music_dialog/index.tsx @@ -40,7 +40,7 @@ import playerEventemitter, { } from '../../../eventemitter'; import { Singer } from './constants'; import upperCaseFirstLetter from '#/utils/upper_case_first_letter'; -import { base64ToCover } from './utils'; +import { base64ToCover, canAudioPlay } from './utils'; const maskProps: { style: CSSProperties } = { style: { zIndex: ZIndex.DIALOG }, @@ -90,33 +90,43 @@ function CreateMusicDialog() { setMusicType(option.actualValue); const [asset, setAsset] = useState(null); - const onAssetChange = (a) => { + const onAssetChange = (a: File | null) => { setAsset(a); - getMusicFileMetadata(a) - .then((metadata) => { - const { title, artist } = metadata; - if (!name && title) { - setName(title); + if (a) { + canAudioPlay(a).then((canPlay) => { + if (!canPlay) { + setAsset(null); + return notice.error(t('can_not_play_audio_file')); } - if (!singerList.length && artist) { - searchSingerRequest({ - keyword: artist, - page: 1, - pageSize: 10, - requestMinimalDuration: 0, - }) - .then((data) => { - if (!singerList.length) { - setSingerList(data.singerList); - } + }); + getMusicFileMetadata(a) + .then((metadata) => { + const { title, artist } = metadata; + if (!name && title) { + setName(title); + } + if (!singerList.length && artist) { + searchSingerRequest({ + keyword: artist, + page: 1, + pageSize: 10, + requestMinimalDuration: 0, }) - .catch((error) => logger.error(error, 'Failed to search singers')); - } - }) - .catch((error) => - logger.error(error, "Failed to parse music's metadata"), - ); + .then((data) => { + if (!singerList.length) { + setSingerList(data.singerList); + } + }) + .catch((error) => + logger.error(error, 'Failed to search singers'), + ); + } + }) + .catch((error) => + logger.error(error, "Failed to parse music's metadata"), + ); + } }; const [loading, setLoading] = useState(false); diff --git a/apps/pwa/src/pages/player/pages/my_music/create_music_dialog/utils.ts b/apps/pwa/src/pages/player/pages/my_music/create_music_dialog/utils.ts index 33a558a5..025e2d8a 100644 --- a/apps/pwa/src/pages/player/pages/my_music/create_music_dialog/utils.ts +++ b/apps/pwa/src/pages/player/pages/my_music/create_music_dialog/utils.ts @@ -25,3 +25,18 @@ export async function base64ToCover(base64: string) { canvas.toBlob((blob) => resolve(blob!), 'image/jpeg', 0.8), ); } + +export function canAudioPlay(file: File) { + const url = URL.createObjectURL(file); + const audio = new Audio(); + return new Promise((resolve) => { + audio.muted = true; + audio.autoplay = true; + audio.onplay = () => resolve(true); + audio.onerror = () => resolve(false); + audio.src = url; + }).finally(() => { + audio.pause(); + URL.revokeObjectURL(url); + }); +}