Spaces:
Running
Running
import os | |
import gradio as gr | |
from mutagen.mp3 import MP3 | |
from mutagen.flac import FLAC | |
from mutagen.id3 import USLT, PictureType | |
from utils import insert_meta, clean_dir, TMP_DIR, EN_US | |
CACHE_DIR = f"{TMP_DIR}/meta" | |
ZH2EN = { | |
"# 音频 Meta 信息编辑器": "# Music Metadata Editor", | |
"上传待编辑音乐 (mp3/flac)": "Upload music (mp3/flac)", | |
"编辑文件名 (不含后缀)": "Edit filename (excluding suffix)", | |
"请确保文件名有效": "Ensure the filename is valid", | |
"编辑歌名": "Edit title", | |
"编辑作者": "Edit artist", | |
"编辑专辑": "Edit album", | |
"编辑歌词": "Edit lyrics", | |
"编辑封面 (留空意味着清空)": "Edit cover (leaving blank means deletion)", | |
"提交": "Submit", | |
"下载输出音频": "Download output audio", | |
"状态栏": "Status", | |
} | |
def _L(zh_txt: str): | |
return ZH2EN[zh_txt] if EN_US else zh_txt | |
# outer func requires try except | |
def extract_metadata(file_path: str): | |
status = "Success" | |
title = fname = artist = album = lyrics = cover = None | |
try: | |
if not file_path: | |
raise ValueError("文件路径为空!") | |
fname = os.path.splitext(os.path.basename(file_path))[0] | |
file_ext = os.path.splitext(file_path)[1].lower() | |
if file_ext == ".mp3": | |
title, artist, album, lyrics, cover = extract_mp3_meta(file_path) | |
elif file_ext == ".flac": | |
title, artist, album, lyrics, cover = extract_flac_meta(file_path) | |
except Exception as e: | |
status = f"{e}" | |
return status, title, fname, artist, album, lyrics, cover | |
def extract_mp3_meta(file_path): | |
title = artist = album = lyrics = cover = None | |
audio = MP3(file_path) | |
title = audio.get("TIT2") | |
artist = audio.get("TPE1") | |
album = audio.get("TALB") | |
for tag in audio.tags.values(): | |
if isinstance(tag, USLT): | |
lyrics = tag.text | |
if tag.FrameID == "APIC": | |
cover = f"{CACHE_DIR}/cover.jpg" | |
with open(cover, "wb") as img_file: | |
img_file.write(tag.data) | |
return title, artist, album, lyrics, cover | |
def extract_flac_meta(file_path): | |
title = artist = album = lyrics = cover = None | |
audio = FLAC(file_path) | |
title = audio.get("TITLE")[0] | |
artist = audio.get("ARTIST")[0] | |
album = audio.get("ALBUM")[0] | |
lyrics = audio.get("LYRICS")[0] | |
for picture in audio.pictures: | |
if picture.type == PictureType.COVER_FRONT: | |
cover = f"{CACHE_DIR}/cover.jpg" | |
with open(cover, "wb") as img_file: | |
img_file.write(picture.data) | |
break | |
return title, artist, album, lyrics, cover | |
# outer func requires try except | |
def upd_meta(audio_in: str, fname, title, artist, album, lyric, cover): | |
status = "Success" | |
audio_out = None | |
try: | |
file_ext = os.path.splitext(audio_in)[1].lower() | |
audio_out = insert_meta( | |
audio_in, | |
title, | |
artist, | |
album, | |
lyric, | |
cover, | |
f"{CACHE_DIR}/{fname}{file_ext}", | |
) | |
except Exception as e: | |
status = f"{e}" | |
return status, audio_out | |
def clear_inputs(): | |
status = None | |
try: | |
clean_dir(CACHE_DIR) | |
except Exception as e: | |
status = f"{e}" | |
return status, None, None, None, None, None, None | |
def music_meta_editor(): | |
clean_dir(CACHE_DIR) | |
with gr.Blocks() as meta: | |
gr.Markdown(_L("# 音频 Meta 信息编辑器")) | |
with gr.Row(): | |
with gr.Column(): | |
input_audio = gr.Audio( | |
label=_L("上传待编辑音乐 (mp3/flac)"), | |
type="filepath", | |
) | |
fname = gr.Textbox( | |
label=_L("编辑文件名 (不含后缀)"), | |
placeholder=_L("请确保文件名有效"), | |
interactive=True, | |
show_copy_button=True, | |
) | |
title = gr.Textbox( | |
label=_L("编辑歌名"), | |
interactive=True, | |
show_copy_button=True, | |
) | |
artist = gr.Textbox( | |
label=_L("编辑作者"), | |
interactive=True, | |
show_copy_button=True, | |
) | |
album = gr.Textbox( | |
label=_L("编辑专辑"), | |
interactive=True, | |
show_copy_button=True, | |
) | |
lyrics = gr.TextArea( | |
label=_L("编辑歌词"), | |
interactive=True, | |
show_copy_button=True, | |
) | |
cover = gr.Image( | |
label=_L("编辑封面 (留空意味着清空)"), | |
interactive=True, | |
type="filepath", | |
) | |
submit = gr.Button(_L("提交")) | |
with gr.Column(): | |
status_bar = gr.Textbox(label=_L("状态栏"), show_copy_button=True) | |
output_audio = gr.Audio( | |
label=_L("下载输出音频"), | |
show_share_button=False, | |
) | |
input_audio.upload( | |
fn=extract_metadata, | |
inputs=input_audio, | |
outputs=[status_bar, title, fname, artist, album, lyrics, cover], | |
) | |
input_audio.clear( | |
fn=clear_inputs, | |
inputs=None, | |
outputs=[status_bar, title, fname, artist, album, lyrics, cover], | |
) | |
submit.click( | |
fn=upd_meta, | |
inputs=[input_audio, fname, title, artist, album, lyrics, cover], | |
outputs=[status_bar, output_audio], | |
) | |
return meta | |