从远程 mp3 中提取封面艺术
extract cover art from remote 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 标记中。
这是一个 hacky 解决方案:读取直到读取整个文件或诱变剂不会出错。如果 mp3 不是 mp3,这将读取整个文件。理想情况下,你会传递给它一个可搜索的 file-like 来缓冲,也许有一个库。
# 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 format 允许它们放在最后。
如果您只想下载绝对最小字节数(因为您不想浪费您的移动用户带宽),您需要:
- 进行 10 字节的部分下载并检查 ID3 标签是否在文件前面。如果没有:下载整个文件
- 从字节 6-9 中提取大小(注意字节最左边的位总是设置为零,如 described on id3.org)
- 根据您刚刚计算的大小重新进行部分下载
之后您将下载完整的 ID3 标签并可以提取它们。现在,mutagen 有一个限制,你需要下载第一个 mp3 音频帧,否则会抛出异常:mutagen.mp3.HeaderNotFoundError: can't sync to an MPEG frame
。如果这个限制对你来说没问题,我 posted a python solution at a similar question(事实上这可能是重复的,我看到你也已经将问题中的源代码复制到你的问题中)。
如果您绝对想尽量减少下载大小,那么您可能想尝试 few other modules,希望它不需要同时下载第一个音频帧。
我需要从远程 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 标记中。
这是一个 hacky 解决方案:读取直到读取整个文件或诱变剂不会出错。如果 mp3 不是 mp3,这将读取整个文件。理想情况下,你会传递给它一个可搜索的 file-like 来缓冲,也许有一个库。
# 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 format 允许它们放在最后。
如果您只想下载绝对最小字节数(因为您不想浪费您的移动用户带宽),您需要:
- 进行 10 字节的部分下载并检查 ID3 标签是否在文件前面。如果没有:下载整个文件
- 从字节 6-9 中提取大小(注意字节最左边的位总是设置为零,如 described on id3.org)
- 根据您刚刚计算的大小重新进行部分下载
之后您将下载完整的 ID3 标签并可以提取它们。现在,mutagen 有一个限制,你需要下载第一个 mp3 音频帧,否则会抛出异常:mutagen.mp3.HeaderNotFoundError: can't sync to an MPEG frame
。如果这个限制对你来说没问题,我 posted a python solution at a similar question(事实上这可能是重复的,我看到你也已经将问题中的源代码复制到你的问题中)。
如果您绝对想尽量减少下载大小,那么您可能想尝试 few other modules,希望它不需要同时下载第一个音频帧。