Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

下载大型音乐集中断时,用--no-overwrite会导致一些音乐文件不完整 #60

Open
ControlNet opened this issue May 31, 2024 · 0 comments

Comments

@ControlNet
Copy link

在下载一整个artist的音乐集的时候,通常音乐数量会有几百个到上千个,很容易受到环境问题中断。为了方便补完,经常就是直接重新运行命令并且带上--no-overwrite。但是似乎这个命令只会简单的检查文件是否存在,而没有检查文件的完整性。所以在重跑的时候可能会导致部分文件不完整。

复现步骤:

  1. 执行任意一个下载音乐的命令
  2. 在进度条没跑完的时候Ctrl+C
  3. 这时候查看文件的属性,会发现元数据没有放进去。
  4. 重新运行指令并且加上--no-overwrite,会发现文件并没有被覆盖更新。

这里就有两个担忧,第一个是音频本身不完整,但是似乎下载是通过非阻塞的方式进行的,在中断主进程的时候,似乎这个下载还能继续直到下载完成,应该问题不大。第二个是这个元数据并没有被放进去,并且在重新下载的时候也不会被更新。

建议考虑以下方法去解决这个问题:

  1. 在下载音频和元数据最终完成之前,只保存为临时文件,例如xxx.flac.tmp,只有当最终完成之后,再重命名为xxx.flac
  2. 执行--no-overwrite命令时,在检查是否覆盖之前,先通过某些方法检查文件和元数据的完整性,如果有问题就覆盖。

稍微检查了一下,可以发现缺失元数据的音乐主要是

print(mutagen.File(file_name).keys())  
# 如果是flac,那么一般是[], ["encoder"]; 如果是mp3, 那么可能是dict_keys([]), dict_keys(['TSSE'])

所以我现在先通过以下脚本删掉所有元数据缺失的,然后重下

from pathlib import Path

import mutagen
import argparse

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument("music_folder", type=str, default=".")
    parser.add_argument("--dry-run", action="store_true")
    args = parser.parse_args()

    for dir_path, dir_names, music_files in Path(args.music_folder).walk():
        import pdb; pdb.set_trace()
        for music_file in music_files:
            if music_file.endswith((".mp3", ".flac", ".m4a", ".wav")):
                audio = mutagen.File(dir_path / music_file)
                if len(audio.keys()) < 2:
                    # find all corresponding files including lyrics and cover
                    files_to_delete = dir_path.glob(f"{Path(music_file).stem}.*")
                    print("Deleting", music_file, "and its corresponding files")
                    for file_to_delete in files_to_delete:
                        if not args.dry_run:
                            file_to_delete.unlink()
                        print("Deleted", file_to_delete)

希望未来新版本能改进--no-overwrite的体验,比如说能自动检查文件完整性。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant