mirror of
https://github.com/ikun0014/lx-music-mobile.git
synced 2025-05-23 22:37:41 +08:00
优化本地文件封面读取,标签编辑添加从文件名解析歌曲、艺术家的功能
This commit is contained in:
parent
4410e0e0b2
commit
9ff9368b74
@ -64,9 +64,9 @@ public class Utils {
|
||||
private static void writeToFile(String filePath, String dataString) throws IOException {
|
||||
File file = new File(filePath);
|
||||
deletePath(file);
|
||||
FileOutputStream fileOutputStream = new FileOutputStream(file);
|
||||
fileOutputStream.write(dataString.getBytes());
|
||||
fileOutputStream.close();
|
||||
try (FileOutputStream fileOutputStream = new FileOutputStream(file)){
|
||||
fileOutputStream.write(dataString.getBytes());
|
||||
}
|
||||
}
|
||||
|
||||
static class WriteStringToFile implements Callable<Object> {
|
||||
|
12
package-lock.json
generated
12
package-lock.json
generated
@ -24,7 +24,7 @@
|
||||
"react-native-exception-handler": "^2.10.10",
|
||||
"react-native-fast-image": "^8.6.3",
|
||||
"react-native-fs": "^2.20.0",
|
||||
"react-native-local-media-metadata": "github:lyswhut/react-native-local-media-metadata#c2b993093ddd141b4b88673baba7cb4d7b565d04",
|
||||
"react-native-local-media-metadata": "github:lyswhut/react-native-local-media-metadata#ac715cd5bd3e338d313f585bb9cb3075607a4378",
|
||||
"react-native-navigation": "^7.37.2",
|
||||
"react-native-pager-view": "^6.2.3",
|
||||
"react-native-quick-base64": "^2.0.8",
|
||||
@ -8997,8 +8997,8 @@
|
||||
},
|
||||
"node_modules/react-native-local-media-metadata": {
|
||||
"version": "0.1.0",
|
||||
"resolved": "git+ssh://git@github.com/lyswhut/react-native-local-media-metadata.git#c2b993093ddd141b4b88673baba7cb4d7b565d04",
|
||||
"integrity": "sha512-4DjQA97Ec9BPa+KPx6NBMgSQsZERTM+nkCQbLfKq+G/udZAM5+AhjVukZPey14Lp8yUyytSdBt/75jpWJomIpQ==",
|
||||
"resolved": "git+ssh://git@github.com/lyswhut/react-native-local-media-metadata.git#ac715cd5bd3e338d313f585bb9cb3075607a4378",
|
||||
"integrity": "sha512-/ElZWRuXfxL/soMVx+yemaeizy3Ec7zSq+T47HKfmXSQWAc7CLQqk/icn5lH4ELapCEBhoTsOsDVIbsZQLTrKg==",
|
||||
"license": "MIT",
|
||||
"workspaces": [
|
||||
"example"
|
||||
@ -17194,9 +17194,9 @@
|
||||
}
|
||||
},
|
||||
"react-native-local-media-metadata": {
|
||||
"version": "git+ssh://git@github.com/lyswhut/react-native-local-media-metadata.git#c2b993093ddd141b4b88673baba7cb4d7b565d04",
|
||||
"integrity": "sha512-4DjQA97Ec9BPa+KPx6NBMgSQsZERTM+nkCQbLfKq+G/udZAM5+AhjVukZPey14Lp8yUyytSdBt/75jpWJomIpQ==",
|
||||
"from": "react-native-local-media-metadata@github:lyswhut/react-native-local-media-metadata#c2b993093ddd141b4b88673baba7cb4d7b565d04",
|
||||
"version": "git+ssh://git@github.com/lyswhut/react-native-local-media-metadata.git#ac715cd5bd3e338d313f585bb9cb3075607a4378",
|
||||
"integrity": "sha512-/ElZWRuXfxL/soMVx+yemaeizy3Ec7zSq+T47HKfmXSQWAc7CLQqk/icn5lH4ELapCEBhoTsOsDVIbsZQLTrKg==",
|
||||
"from": "react-native-local-media-metadata@github:lyswhut/react-native-local-media-metadata#ac715cd5bd3e338d313f585bb9cb3075607a4378",
|
||||
"requires": {}
|
||||
},
|
||||
"react-native-navigation": {
|
||||
|
@ -58,7 +58,7 @@
|
||||
"react-native-exception-handler": "^2.10.10",
|
||||
"react-native-fast-image": "^8.6.3",
|
||||
"react-native-fs": "^2.20.0",
|
||||
"react-native-local-media-metadata": "github:lyswhut/react-native-local-media-metadata#c2b993093ddd141b4b88673baba7cb4d7b565d04",
|
||||
"react-native-local-media-metadata": "github:lyswhut/react-native-local-media-metadata#ac715cd5bd3e338d313f585bb9cb3075607a4378",
|
||||
"react-native-navigation": "^7.37.2",
|
||||
"react-native-pager-view": "^6.2.3",
|
||||
"react-native-quick-base64": "^2.0.8",
|
||||
|
@ -13,7 +13,7 @@
|
||||
- 优化播放详情页歌曲封面、控制按钮对各尺寸屏幕的适配,修改横屏下的控制栏按钮布局
|
||||
- 优化横竖屏界面的暂时判断,现在趋于方屏的屏幕按竖屏的方式显示,横屏下的播放栏添加上一曲切歌按钮
|
||||
- 添加对wy源某些歌曲有问题的歌词进行修复(#370)
|
||||
- 文件选择器允许选择外置存储设备上的路径(/storage)
|
||||
- 文件选择器允许(在旧系统)选择外置存储设备上的路径(`/storage`)
|
||||
- 图片显示改用第三方的图片组件,支持gif类型的图片显示,尝试解决某些设备上图片过多导致的应用崩溃问题
|
||||
- 歌曲评论内容过长时自动折叠,需手动展开
|
||||
- 改进本地音乐在线信息的匹配机制
|
||||
@ -26,7 +26,7 @@
|
||||
### 变更
|
||||
|
||||
- 在更低版本的安卓上启用跟随系统亮暗主题功能(#317)
|
||||
- 由于歌曲评论的图片太大占用较多资源,评论图片不再直接加载,需要点击后点击图片后再加载
|
||||
- 由于歌曲评论的图片太大占用较多资源,评论图片不再直接加载,需要点击图片区域后再加载
|
||||
|
||||
### 其他
|
||||
|
||||
|
@ -16,7 +16,7 @@ export interface InputItemProps extends InputProps {
|
||||
export default memo(({ value, label, onChanged, ...props }: InputItemProps) => {
|
||||
const theme = useTheme()
|
||||
return (
|
||||
<View style={styles.container} onStartShouldSetResponder={() => true}>
|
||||
<View style={styles.container}>
|
||||
<Text style={styles.label} size={14}>{label}</Text>
|
||||
<Input
|
||||
value={value}
|
||||
|
@ -5,8 +5,8 @@ import InputItem from './InputItem'
|
||||
import { useI18n } from '@/lang'
|
||||
import TextAreaItem from './TextAreaItem'
|
||||
import PicItem from './PicItem'
|
||||
import Text from '@/components/common/Text'
|
||||
import { useTheme } from '@/store/theme/hook'
|
||||
import ParseName from './ParseName'
|
||||
|
||||
export interface Metadata {
|
||||
name: string // 歌曲名
|
||||
@ -79,10 +79,13 @@ export default forwardRef<MetadataFormType, {}>((props, ref) => {
|
||||
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<View>
|
||||
<Text size={14}>{global.i18n.t('metadata_edit_modal_file_path')}</Text>
|
||||
<Text size={14} selectable color={theme['c-primary-font']} style={styles.pathText}>{path}</Text>
|
||||
</View>
|
||||
<TextAreaItem
|
||||
value={path}
|
||||
label={global.i18n.t('metadata_edit_modal_file_path')}
|
||||
numberOfLines={3}
|
||||
scrollEnabled
|
||||
style={{ ...styles.pathText, color: theme['c-primary-font'] }}
|
||||
/>
|
||||
|
||||
<InputItem
|
||||
value={data.name}
|
||||
@ -94,11 +97,17 @@ export default forwardRef<MetadataFormType, {}>((props, ref) => {
|
||||
label={t('metadata_edit_modal_form_singer')}
|
||||
onChanged={handleUpdateSinger}
|
||||
keyboardType="name-phone-pad" />
|
||||
<ParseName
|
||||
path={path}
|
||||
onNameChanged={handleUpdateName}
|
||||
onSingerChanged={handleUpdateSinger}
|
||||
/>
|
||||
<InputItem
|
||||
value={data.albumName}
|
||||
label={t('metadata_edit_modal_form_album_name')}
|
||||
onChanged={handleUpdateAlbumName}
|
||||
keyboardType="name-phone-pad" />
|
||||
|
||||
<PicItem
|
||||
value={data.pic}
|
||||
label={t('metadata_edit_modal_form_pic')}
|
||||
@ -107,6 +116,7 @@ export default forwardRef<MetadataFormType, {}>((props, ref) => {
|
||||
value={data.lyric}
|
||||
label={t('metadata_edit_modal_form_lyric')}
|
||||
onChanged={handleUpdateLyric}
|
||||
numberOfLines={6}
|
||||
keyboardType="default" />
|
||||
</View>
|
||||
)
|
||||
@ -121,7 +131,7 @@ const styles = createStyle({
|
||||
maxWidth: '100%',
|
||||
},
|
||||
pathText: {
|
||||
marginBottom: 10,
|
||||
height: 60,
|
||||
},
|
||||
})
|
||||
|
||||
|
60
src/components/MetadataEditModal/ParseName.tsx
Normal file
60
src/components/MetadataEditModal/ParseName.tsx
Normal file
@ -0,0 +1,60 @@
|
||||
import { memo } from 'react'
|
||||
|
||||
import { StyleSheet, View } from 'react-native'
|
||||
import { useTheme } from '@/store/theme/hook'
|
||||
import Text from '@/components/common/Text'
|
||||
import ButtonPrimary from '@/components/common/ButtonPrimary'
|
||||
import { useI18n } from '@/lang'
|
||||
|
||||
|
||||
export interface ParseNameProps {
|
||||
path: string
|
||||
onNameChanged: (text: string) => void
|
||||
onSingerChanged: (text: string) => void
|
||||
}
|
||||
|
||||
const parsePath = (path: string) => {
|
||||
return path.substring(path.lastIndexOf('/') + 1, path.lastIndexOf('.')).split('-').map(name => name.trim())
|
||||
}
|
||||
|
||||
export default memo(({ path, onNameChanged, onSingerChanged }: ParseNameProps) => {
|
||||
const theme = useTheme()
|
||||
const t = useI18n()
|
||||
const handleParseNameSinger = () => {
|
||||
const [name, singer] = parsePath(path)
|
||||
onNameChanged(name)
|
||||
if (singer) onSingerChanged(singer)
|
||||
}
|
||||
const handleParseSingerName = () => {
|
||||
const [singer, name] = parsePath(path)
|
||||
onSingerChanged(singer)
|
||||
if (name) onNameChanged(name)
|
||||
}
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<Text style={styles.label} size={14}>{t('metadata_edit_modal_form_parse_name')}</Text>
|
||||
<View style={styles.btns}>
|
||||
<ButtonPrimary style={{ backgroundColor: theme['c-button-background'] }} onPress={handleParseNameSinger}>
|
||||
<Text color={theme['c-button-font']} size={13}>{t('metadata_edit_modal_form_parse_name_singer')}</Text>
|
||||
</ButtonPrimary>
|
||||
<ButtonPrimary style={{ backgroundColor: theme['c-button-background'] }} onPress={handleParseSingerName}>
|
||||
<Text color={theme['c-button-font']} size={13}>{t('metadata_edit_modal_form_parse_singer_name')}</Text>
|
||||
</ButtonPrimary>
|
||||
</View>
|
||||
</View>
|
||||
)
|
||||
})
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
// paddingLeft: 25,
|
||||
marginBottom: 15,
|
||||
},
|
||||
label: {
|
||||
marginBottom: 2,
|
||||
},
|
||||
btns: {
|
||||
marginTop: 5,
|
||||
flexDirection: 'row',
|
||||
},
|
||||
})
|
@ -31,7 +31,7 @@ export default memo(({ value, label, onChanged }: PicItemProps) => {
|
||||
})
|
||||
}, [onChanged])
|
||||
return (
|
||||
<View style={styles.container} onStartShouldSetResponder={() => true}>
|
||||
<View style={styles.container}>
|
||||
<View style={styles.header}>
|
||||
<Text style={styles.label} size={14}>{label}</Text>
|
||||
<View style={styles.btns}>
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { memo } from 'react'
|
||||
|
||||
import { View } from 'react-native'
|
||||
import { StyleSheet, View } from 'react-native'
|
||||
import type { InputProps } from '@/components/common/Input'
|
||||
import Input from '@/components/common/Input'
|
||||
import { useTheme } from '@/store/theme/hook'
|
||||
@ -11,22 +11,21 @@ import { createStyle } from '@/utils/tools'
|
||||
export interface TextAreaItemProps extends InputProps {
|
||||
value: string
|
||||
label: string
|
||||
onChanged: (text: string) => void
|
||||
onChanged?: (text: string) => void
|
||||
}
|
||||
|
||||
export default memo(({ value, label, onChanged, ...props }: TextAreaItemProps) => {
|
||||
export default memo(({ value, label, onChanged, style, ...props }: TextAreaItemProps) => {
|
||||
const theme = useTheme()
|
||||
return (
|
||||
<View style={styles.container} onStartShouldSetResponder={() => true}>
|
||||
<View style={styles.container}>
|
||||
<Text style={styles.label} size={14}>{label}</Text>
|
||||
<Input
|
||||
value={value}
|
||||
onChangeText={onChanged}
|
||||
numberOfLines={6}
|
||||
scrollEnabled={false}
|
||||
textAlignVertical='top'
|
||||
multiline
|
||||
style={{ ...styles.textarea, backgroundColor: theme['c-primary-input-background'] }}
|
||||
style={StyleSheet.compose({ ...styles.textarea, backgroundColor: theme['c-primary-input-background'] }, style)}
|
||||
{...props}
|
||||
/>
|
||||
</View>
|
||||
|
@ -5,7 +5,7 @@ import Text from '@/components/common/Text'
|
||||
import { useTheme } from '@/store/theme/hook'
|
||||
import { createStyle } from '@/utils/tools'
|
||||
|
||||
type ButtonProps = BtnProps
|
||||
export type ButtonProps = BtnProps
|
||||
|
||||
export default memo(({ disabled, onPress, children }: ButtonProps) => {
|
||||
const theme = useTheme()
|
||||
|
@ -113,6 +113,9 @@
|
||||
"metadata_edit_modal_form_album_name": "Album name",
|
||||
"metadata_edit_modal_form_lyric": "LRC Lyrics",
|
||||
"metadata_edit_modal_form_name": "Song name",
|
||||
"metadata_edit_modal_form_parse_name": "Parse song name and artist from file name",
|
||||
"metadata_edit_modal_form_parse_name_singer": "Name - Artist",
|
||||
"metadata_edit_modal_form_parse_singer_name": "Artist - Name",
|
||||
"metadata_edit_modal_form_pic": "Song cover",
|
||||
"metadata_edit_modal_form_remove_pic": "Remove image",
|
||||
"metadata_edit_modal_form_select_pic": "Select Image",
|
||||
|
@ -113,6 +113,9 @@
|
||||
"metadata_edit_modal_form_album_name": "专辑名",
|
||||
"metadata_edit_modal_form_lyric": "LRC 歌词",
|
||||
"metadata_edit_modal_form_name": "歌曲名",
|
||||
"metadata_edit_modal_form_parse_name": "从文件名解析歌曲名、艺术家",
|
||||
"metadata_edit_modal_form_parse_name_singer": "歌曲名 - 艺术家",
|
||||
"metadata_edit_modal_form_parse_singer_name": "艺术家 - 歌曲名",
|
||||
"metadata_edit_modal_form_pic": "歌曲封面",
|
||||
"metadata_edit_modal_form_remove_pic": "移除图片",
|
||||
"metadata_edit_modal_form_select_pic": "选择图片",
|
||||
|
@ -1,10 +1,10 @@
|
||||
import { scanFiles } from 'react-native-local-media-metadata'
|
||||
import { temporaryDirectoryPath } from '@/utils/fs'
|
||||
import { scanFiles, readPic as _readPic } from 'react-native-local-media-metadata'
|
||||
export {
|
||||
type MusicMetadata,
|
||||
type MusicMetadataFull,
|
||||
readMetadata,
|
||||
writeMetadata,
|
||||
readPic,
|
||||
writePic,
|
||||
readLyric,
|
||||
writeLyric,
|
||||
@ -14,6 +14,10 @@ export const scanAudioFiles = async(dirPath: string): Promise<string[]> => {
|
||||
return scanFiles(dirPath, ['mp3', 'flac', 'ogg', 'wav'])
|
||||
}
|
||||
|
||||
export const readPic = async(dirPath: string): Promise<string> => {
|
||||
return _readPic(dirPath, temporaryDirectoryPath + '/local-media-metadata')
|
||||
}
|
||||
|
||||
// export interface MusicMetadata {
|
||||
// type: 'mp3' | 'flac' | 'ogg' | 'wav'
|
||||
// bitrate: string
|
||||
|
Loading…
x
Reference in New Issue
Block a user