2014-11-12 11 views
7

Ho bisogno di estrarre tag ID3 e meta-dati di file mp3 remoti.Estrai tag ID3 di un URL MP3 con download parziale usando python

ho scritto poche righe che potrebbero ottenere tag ID3 dei file locale:

from mutagen.mp3 import MP3 
import urllib2 

audio = MP3("Whistle.mp3") 

songtitle = audio["TIT2"] 
artist = audio["TPE1"] 

print "Title: " + str(songtitle) 
print "Artist: "+str(artist) 

ho bisogno per raggiungere questo obiettivo per collegamenti URL per i file mp3. Ho provato ad ottenere il download parziale dei file usando urllib2.

import urllib2 
from mutagen.mp3 import MP3 

req = urllib2.Request('http://www.1songday.com/wp-content/uploads/2013/08/Lorde-Royals.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) 

Come posso estrarre i tag ID3 dell'URL MP3 senza scaricare completamente il file?

+0

Hai ottenuto fino al recupero dei primi 100 byte del file MP3. Dove sei bloccato? – scav

+2

Ah, sembra che i tag ID3 siano negli ULTIMI 128 byte del file. Quindi, a meno che non si conosca la dimensione del file, non sarà possibile creare un'intestazione Range per ottenerli. Forse una richiesta HEAD può ottenere prima la lunghezza del file ... – scav

risposta

0

Nel tuo esempio, i tag ID3 non vengono recuperati, quindi non puoi estrarli.

Ho giocato un po 'dopo aver letto le specifiche per ID3 ed ecco un buon modo per iniziare.

#Search for ID3v1 tags 
import string 
tagIndex = string.find(data,'TAG') 
if (tagIndex>0): 
    if data[tagIndex+3]=='+': 
    print "Found extended ID3v1 tag!" 
    title = data[tagIndex+3:tagIndex+63] 
    print title 
    else: 
    print "Found ID3v1 tags" 
    title = data[tagIndex+3:tagIndex+33] 
    print title 
    #So on. 
else: 
    #Look for ID3v2 tags 
    if 'TCOM' in data: 
    composerIndex = string.find(data,'TCOM') 
    #and so on. See wikipedia for a full list of frame specifications 
0

ID3 tag vengono memorizzati nei metadati ID3 che di solito è davanti dei telai mp3 (contenenti l'audio), ma lo standard mp3 li permette anche di "follow the mp3 frames".

Per scaricare il numero minimo di byte è necessario:

  1. scaricare i primi 10 byte del mp3, estrarre l'intestazione ID3v2 e calcolare le dimensioni dell'intestazione ID3v2
  2. per recuperare la piena ID3v2 tags scaricare size byte del mp3
  3. utilizzare una libreria python per estrarre i tag ID3

Ecco uno script (python 2 o 3) che estrae le copertine degli album wi th una quantità minima di dimensione del download:

try: 
    import urllib2 as request # python 2 
except ImportError: 
    from urllib import request # python 3 
    from functools import reduce 
import sys 
from io import BytesIO 
from mutagen.mp3 import MP3 

url = sys.argv[1] 

def get_n_bytes(url, size): 
    req = request.Request(url) 
    req.headers['Range'] = 'bytes=%s-%s' % (0, size-1) 
    response = request.urlopen(req) 
    return response.read() 

data = get_n_bytes(url, 10) 
if data[0:3] != 'ID3': 
    raise Exception('ID3 not in front of mp3 file') 

size_encoded = bytearray(data[-4:]) 
size = reduce(lambda a,b: a*128+b, size_encoded, 0) 

header = BytesIO() 
# mutagen needs one full frame in order to function. Add max frame size 
data = get_n_bytes(url, size+2881) 
header.write(data) 
header.seek(0) 
f = MP3(header) 

if f.tags and 'APIC:' in f.tags.keys(): 
    artwork = f.tags['APIC:'].data 
    with open('image.jpg', 'wb') as img: 
     img.write(artwork) 

Qualche osservazione:

  • controlla che l'ID3 è di fronte a file e che è ID3v2
  • la dimensione dei tag ID3 è memorizzato nel byte 6 a 9, come documented on id3.org
  • sfortunatamente il mutageno ha bisogno di un fotogramma audio mp3 completo per analizzare i tag id3. È quindi necessario scaricare anche un fotogramma mp3 (che è al massimo 2881 byte lungo secondo this comment)
  • invece di ciecamente assumendo che l'album è JPG si dovrebbe verificare per il formato dell'immagine in primo luogo come ID3 allows many different image types
  • testato con circa 10 mp3 casuali da internet, ad es questo: python url.py http://www.fuelfriendsblog.com/listenup/01%20America.mp3