使用Mutagen在Python中构建一个播放列表导出器
音乐是人类经历中最重要的部分之一。虽然现在大多数音乐都是在线流媒体,但有些人仍然喜欢把音乐下载成音频文件,以便离线收听。
音频文件是存储音乐以及关于音乐的其他信息的一种很好的方式。然而,将音频文件中的信息导出为播放列表格式并不总是那么容易。
这就是播放列表导出器的作用。它是一种软件,可以用来将音频文件的信息导出为可由音频播放器解释的格式。由此产生的播放列表也可以在Soundiiz等上传者的帮助下在流媒体服务中找到你的音乐。
在本教程中,我们将学习如何使用Mutagen音频库在Python中建立一个播放列表导出器。
前提条件
要继续学习本教程,你需要安装Python 3.6或更高版本。你还将有一堆音乐文件需要处理。MP3和FLAC格式都可以。
第1步:设置环境
为了开始工作,你将需要一个虚拟环境,将你的Python代码与你系统的其他部分分开。
要创建一个虚拟环境,在你的终端运行以下命令。
$ python3 -m venv venv
如果你使用的是 Windows 机器,Python 的可执行文件可能不叫
python3
。它可能是python
或py
。
要激活虚拟环境,在你的终端运行下面的命令。
$ source venv/bin/activate
随意使用其他的虚拟环境管理器,如Pipenv或Conda,如果你安装了它们。
第2步:将播放列表转存为M3U文件
M3U文件是一种简单的文本文件格式,可以用来存储音乐播放列表。它由每个音乐文件的路径列表组成。如果音乐文件在本地没有,就用直接链接到远程源来代替。
下面是一个M3U文件的样本内容。
01. Smells Like Teen Spirit.flac
02. In Bloom.flac
03. Come As You Are.flac
04. Breed.flac
05. Lithium.flac
06. Polly.flac
07. Territorial Pissings.flac
08. Drain You.flac
09. Lounge Act.flac
10. Stay Away.flac
11. On A Plain.flac
12. Something In The Way.flac
上面列出的项目的路径是相对于M3U文件所在的目录的。把文件移到另一个目录不会找到原来的音乐文件。
需要注意的是,如果使用音乐文件的完整路径,M3U文件可以随意移动而不被破坏。另外,如果你使用相对文件路径,仅移动M3U文件就会破坏播放列表。在这种情况下,你需要将播放列表文件存放在音乐文件夹内。
我们来生成一个M3U播放列表。我的音乐文件位于~/Music/Nirvana - Nevermind
目录中。
在你的虚拟环境中创建一个app.py
,并编写以下代码。
import os
music_path = "Music/Nirvana - Nevermind"
full_path = os.path.join(os.path.expanduser("~"), music_path)
ext = [".mp3", ".flac"]
files = os.scandir(full_path)
playlist = []
for entry in files:
if entry.is_file():
if os.path.splitext(entry.name)[1].lower() in ext:
playlist.append(entry.name + " \n")
file = open(os.path.join(full_path, "{}.m3u".format(
os.path.basename(full_path)
)), "w")
file.writelines(playlist)
file.close()
我们正在使用os.scandir
函数来扫描目录中的文件。该函数返回一个迭代器,产生os.DirEntry
对象。
我们通过调用is_file
方法来检查该条目是否是一个文件。如果该文件有我们要找的扩展名,我们就把它添加到播放列表中。然后我们打开一个与目录基名相同的M3U文件,将播放列表写入其中。
现在我的~/Music/Nirvana - Nevermind
目录中有一个Nirvana - Nevermind.M3U
。
第3步:用ID3标签倾倒播放列表
如果你的音乐文件命名不正确,或者你只是需要更多的数据来导出到流媒体服务或其他,一个简单的M3U文件可能不一定适合你。这就是Mutagen的用武之地。
Mutagen是一个Python库,允许你从音频文件中读取和写入元数据。它是对标准Python库mutagen
和mutagen.id3
的一个封装。
要在你的环境中安装Mutagen,在你激活的虚拟环境中运行以下命令。
$ pip install mutagen
然后使用os.scandir
和Mutagen一起将你的播放列表导出为带有ID3标签的JSON文件。
import os
from mutagen.mp3 import MP3
from mutagen.flac import FLAC
dir = "Music/Nirvana - Nevermind"
full_path = os.path.join(os.path.expanduser("~"), dir)
files = os.scandir(full_path)
for entry in files:
if entry.is_file():
if entry.name.endswith(".mp3"):
audio = MP3(entry.path)
elif entry.name.endswith(".flac"):
audio = FLAC(entry.path)
try:
artists = audio['artist'][0]
except KeyError:
try:
artists = audio['TPE1'][0]
except:
artists = 'Unknown'
except IndexError:
artists = 'Unknown'
print(artists)
我们使用mutagen.mp3
和mutagen.flac
模块中的MP3
和FLAC
类来读取ID3标签。MP3
类用于MP3文件,FLAC
类用于FLAC文件。
try
块用来捕捉KeyError
异常,如果没有找到标签,就会出现这种情况。如果该文件是一个MP3文件,并且没有找到标签artist
,我们尝试读取标签TPE1
。如果没有找到标签,我们就把艺术家设置为Unknown
。IndexError
异常是用来捕捉没有找到标签数据的情况。
FLAC文件有一个叫做artist
的标签,MP3文件有一个叫做TPE1
的标签。这就是为什么try
块是必要的。
下面是一些可以被读取的其他标签。
FLAC | MP3 | 标签 | 描述 |
---|---|---|---|
标题 | TIT2 | 标题 | 音频文件的标题 |
艺术家 | TPE1 | 艺术家 | 音频文件的艺术家 |
专辑 | TALB | 专辑 | 该音频文件的专辑 |
专辑艺术家 | TPE2 | 专辑艺术家 | 音频文件的专辑艺术家 |
体裁 | TCON | 体裁 | 音频文件的类型 |
请注意:这些标签不是所有的音频文件都能保存。
现在我们有了ID3标签,我们可以把播放列表转储到一个JSON文件。
import json
# ...
tags_list = []
for entry in files:
# your try catch blocks here
tags = {
"artists": artists,
# your other tags here
}
tags_list.append(tags)
tags_json = json.dumps(tags_list, indent=4)
file = open(os.path.join(full_path, "{}.json".format(
os.path.basename(full_path)
)), "w")
file.write(tags_json)
file.close()
我们把所有的标签合并成一个字典,然后转储到一个JSON文件。我们使用json.dumps
函数将字典转换为JSON字符串。我们使用indent=4
选项来使JSON文件更易读。
现在我的~/Music/Nirvana - Nevermind
目录中有一个Nirvana - Nevermind.json
。
结论
在Python中创建一个播放列表文件是相对容易的。使用os.scandir
,你可以创建一个简单的M3U播放列表文件(这在大多数情况下已经足够了)。使用Mutagen,你还可以将播放列表导出为一个带有ID3标签的JSON文件。