【问题标题】:extract cover art from remote mp3从远程 mp3 中提取封面艺术
【发布时间】:2017-06-04 09:37:59
【问题描述】:

我需要从远程 mp3 文件中提取封面并将其保存到文件中,而无需下载整个 mp3。但我没有成功。我尝试下载文件的前 100 个字节,例如:

import urllib2
from mutagen.mp3 import MP3

req = urllib2.Request('http://www.stephaniequinn.com/Music/Commercial%20DEMO%20-%2001.mp3')
req.headers['Range'] = 'bytes=%s-%s' % (0, 100)
response = urllib2.urlopen(req)
headers = response.info()
print headers.type
print headers.maintype

data = response.read()
print len(data)

我已经了解到 id 3 标签位于 mp3 的最后 128 个字节。现在我需要一些帮助来仅下载包含 apic 封面艺术的最后一个字节并提取图像。

谢谢你帮助我

【问题讨论】:

  • 您在示例中链接到的 mp3 没有附加任何艺术品。你能提供一件艺术品吗?
  • 如果我下载这个 mp3 VLC 显示一些封面艺术...我正在搜索另一个请稍候
  • 你使用的是linux还是windows?您需要一些命令行工具来查找 mp3 文件中封面的位置
  • Linux 但脚本最终应该在 Python for Android 上运行
  • 我也尝试使用 ffmpeg 处理它,但我没有通过命令行在 Android 上运行它

标签: python id3 mutagen


【解决方案1】:

隐蔽艺术位于文件开头的 id3v2 标记中。

这是一个 hacky 解决方案:读取直到整个文件被读取或诱变剂不会出错。如果 mp3 不是 mp3,这将读取整个文件。理想情况下,你会传递给它一个可搜索的文件,它会缓冲,也许有一个库。

# Python 2 or 3
try:
    import urllib2 as request
except ImportError:
    from urllib import request
from io import BytesIO
from mutagen import MutagenError
from mutagen.mp3 import MP3


def get_mp3(url):
    """
    Args:
        url (str)
    Returns:
        mutagen.mp3.MP3
    Raises:
        mutagen.MutagenError
        EnvironmentError
    """

    r = request.urlopen(url)
    try:
        size = 128
        filelike = BytesIO()
        while 1:
            data = r.read(size)
            size *= 2
            filelike.seek(0, 2)
            filelike.write(data)
            filelike.seek(0)
            try:
                return MP3(filelike)
            except MutagenError:
                if not data:
                    raise
                pass
    finally:
        r.close()

try:
    f = get_mp3("http://web.ist.utl.pt/antonio.afonso/www.aadsm.net/libraries/id3/music/Bruno_Walter_-_01_-_Beethoven_Symphony_No_1_Menuetto.mp3")
except (MutagenError, EnvironmentError):
    pass
else:
    if f.tags:
        for frame in f.tags.getall("APIC"):
            print(frame.pprint())

【讨论】:

  • 您是否检查过这是否没有下载整个文件?我假设当不在标头中提供Range 时,它会下载整个文件,尽管告诉read 只加载几个字节?
  • @hansaplast 我不知道。使用“strace -y -e recvfrom python foo.py”查看它表明它至少没有加载整个文件。
【解决方案2】:

ID3 标签通常在 mp3 文件的前面,而不是后面。我从网上查了一些随机的 mp3,它们的所有 ID3 标签都在前面,尽管mp3 format 允许他们在末尾有它。

如果您只想下载绝对最小的字节数(因为您不想浪费手机用户的带宽),您需要:

  1. 进行 10 字节的部分下载并检查 ID3 标记是否在文件前面。如果没有:下载整个文件
  2. 从字节 6-9 中提取大小(请注意,字节的最左边位始终设置为零,如 described on id3.org
  3. 重新下载刚刚计算的部分大小

之后,您将下载完整的 ID3 标签并可以提取它们。现在,mutagen 有个限制,你需要下载第一个 mp3 音频帧,否则会抛出异常:mutagen.mp3.HeaderNotFoundError: can't sync to an MPEG frame。如果这个限制对你来说没问题,我posted a python solution at a similar question(实际上这可能是重复的,我看到你也已经将问题中的源代码复制到你的问题中)。

如果您绝对想最小化下载大小,那么您可能想尝试few other modules,希望它不需要同时下载第一个音频帧。

【讨论】:

    猜你喜欢
    • 2010-09-25
    • 1970-01-01
    • 2012-07-15
    • 2014-06-18
    • 2022-01-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多