Skip to content

Commit

Permalink
detect usability of music file
Browse files Browse the repository at this point in the history
  • Loading branch information
mebtte committed Apr 14, 2024
1 parent 68cacf6 commit 096c7c2
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 26 deletions.
7 changes: 5 additions & 2 deletions apps/pwa/src/components/file_select.tsx
Original file line number Diff line number Diff line change
@@ -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';
Expand All @@ -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;
Expand Down Expand Up @@ -60,7 +63,7 @@ function FileSelect({

return (
<Style onClick={onSelectFile} disabled={disabled}>
{value ? value.name : placeholder}
{value ? value.name : <span className="placeholder">{placeholder}</span>}
</Style>
);
}
Expand Down
1 change: 1 addition & 0 deletions apps/pwa/src/i18n/en_us.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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',
};
1 change: 1 addition & 0 deletions apps/pwa/src/i18n/zh_hans.ts
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,7 @@ const zhCN: {
feedback: '反馈',
fork_from_these_musics: '二次创作自以下音乐',
forked_by_these_musics: '被以下音乐二次创作',
can_not_play_audio_file: '音乐文件无法被播放',
};

export default zhCN;
Original file line number Diff line number Diff line change
Expand Up @@ -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 },
Expand Down Expand Up @@ -90,33 +90,43 @@ function CreateMusicDialog() {
setMusicType(option.actualValue);

const [asset, setAsset] = useState<File | null>(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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<boolean>((resolve) => {
audio.muted = true;
audio.autoplay = true;
audio.onplay = () => resolve(true);
audio.onerror = () => resolve(false);
audio.src = url;
}).finally(() => {
audio.pause();
URL.revokeObjectURL(url);
});
}

0 comments on commit 096c7c2

Please sign in to comment.