从远程mp3中提取封面艺术



我需要从远程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封面艺术的最后一个字节并提取图像。

谢谢你帮我解决

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

这里有一个棘手的解决方案:读取直到整个文件被读取,或者诱变剂不会出错。这将读取整个文件,以防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())

ID3标签通常在mp3文件的前面,而不是后面。我从互联网上随机查看了一些mp3,它们前面有所有的ID3标签,尽管mp3格式允许它们在最后有标签。

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

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

之后,您将下载完整的ID3标签并可以提取它们。现在,诱变剂有一个限制,你也需要下载第一个mp3音频帧,否则它会抛出一个异常:mutagen.mp3.HeaderNotFoundError: can't sync to an MPEG frame。如果这个限制对你来说是可以的,我发布了一个类似问题的python解决方案(事实上,这可能是重复的,我看到你也将问题中的源代码复制到了你的问题中)。

如果你绝对想最大限度地减少下载量,那么你可能想尝试其他一些模块,希望它们不需要下载第一个音频帧。

最新更新