2014-11-12 11 views
7

Potrzebuję wyodrębnić tagi ID3 i metadane zdalnych plików mp3.Wyodrębnij znaczniki ID3 adresu URL MP3 z częściowym pobieraniem za pomocą pythona

napisałem kilka wierszy, które mogłyby dostać tagów ID3 lokalnego pliku:

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) 

muszę to osiągnąć za linki URL dla plików mp3. Próbowałem uzyskać częściowe pobieranie plików przy użyciu 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) 

Jak mogę wyodrębnić tagi ID3 z adresu URL MP3 bez pobierania pliku?

+0

Doszło aż do pobrania pierwszych 100 bajtów pliku MP3. Gdzie utknąłeś? – scav

+2

Ah, wygląda na to, że znaczniki id3 znajdują się w OSTATNIE 128 bajtów pliku. Więc jeśli nie znasz rozmiaru pliku, nie będziesz w stanie utworzyć nagłówka zakresu, aby je uzyskać. Może żądanie HEAD może najpierw uzyskać długość pliku ... – scav

Odpowiedz

0

W tym przykładzie znaczniki ID3 nie są pobierane, więc nie można ich wyodrębnić.

Grałem trochę po przeczytaniu specyfikacji dla ID3 i oto dobry sposób na rozpoczęcie pracy.

#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, znaczniki są zapisywane w metadanych ID3, zazwyczaj przed ramek MP3 (zawierające audio), ale standard MP3 pozwala im na "follow the mp3 frames".

Aby pobrać minimalną liczbę bajtów trzeba:

  1. pobrać pierwsze 10 bajtów mp3, wyodrębnić nagłówka ID3v2 i obliczyć wielkość nagłówka ID3v2
  2. aby pobrać pełną ID3v2 tagi pobrać size bajtów mp3
  3. użyć biblioteki Pythona do wyodrębnienia znaczników ID3

oto skrypt (python 2 lub 3), które wydobywa album sztuki wi th minimalną ilość wielkości POBIERZ

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) 

kilka uwag:

  • sprawdza czy ID3 jest w przedniej części pliku i że to ID3v2
  • wielkość tagów ID3 przechowywany w bajcie od 6 do 9, jako documented on id3.org
  • Niestety, mutagen potrzebuje jednej pełnej ramki audio mp3 do przeanalizowania tagów id3. Dlatego trzeba także pobrać jedną mp3 ramki (która jest na max 2881 bajtów według this comment)
  • zamiast ślepo przy założeniu, że sztuka album jpg należy sprawdzić dla formatu obrazu najpierw jako ID3 allows many different image types
  • testowane około 10 losowych plików mp3 z internetu, np ten: python url.py http://www.fuelfriendsblog.com/listenup/01%20America.mp3
Powiązane problemy