2012-03-25 13 views
5

Grazie a questo sito e ad alcuni altri, ho creato un codice semplice per leggere i tag ID3v2.3 dai file MP3. Fare ciò è stata una grande esperienza di apprendimento in quanto non conoscevo hex/byte/binary ecc.Codifica del testo nei tag ID3v2.3

Posso leggere correttamente i dati, ma ho trovato un problema che credo abbia a che fare con la codifica utilizzata. Mi sono reso conto che i frame di testo hanno un byte all'inizio del "testo" che descrive la codifica utilizzata e potenzialmente più informazioni nei prossimi 2 byte ...

Esempio: I dati dal frame TIT2 iniziano con il byte $ 03 (esadecimale) prima del testo attuale. Questo testo viene visualizzato correttamente, anche se con un carattere aggiuntivo all'inizio, utilizzando Encoding.ASCII.GetString

In un altro MP3, i dati di TIT2 inizia $ 01 e è seguita da $ FF $ FE, che credo sia a che fare con Unicode ? Il testo stesso è suddiviso, ci sono $ 00 tra ogni carattere di testo, e questo impedisce la visualizzazione dei dati nei moduli di Windows (non appena si incontra un 00, il testo si ferma, così ottengo il primo carattere e basta). Ho provato a utilizzare Encoding.UNICODE.GetString, ma sembra che restituisca un messaggio senza senso.

La stampa di questi dati su una console sembra funzionare, con spazi tra ogni carattere, pertanto la lettura dei dati funziona correttamente.

Ho letto la documentazione ufficiale per ID3v2.3 ma suppongo di non averlo capito abbastanza per comprendere la sezione di codifica del testo.

Qualsiasi risposta o collegamento ad articoli che potrebbero essere d'aiuto sarebbe molto apprezzato!

saluti Ross

risposta

3

dati da cornice TIT2 inizia con il byte $ 03 (hex) prima del testo vero e proprio. Questo testo viene visualizzato correttamente, anche se con un carattere aggiuntivo all'inizio, utilizzando Encoding.ASCII.GetString

codifica 0x03 è UTF-8, così si dovrebbe usare Encoding.UTF8.GetString. Il carattere all'inizio potrebbe essere U + FEFF Byte Order Mark, che viene utilizzato per distinguere tra UTF-16LE e UTF-16BE ... non è utile per UTF-8, ma gli strumenti di Windows amano metterlo lì comunque.

UTF-8 è una funzione ID3v2.4 non presente in 2.3, che potrebbe essere il motivo per cui non è possibile trovarla nelle specifiche. Nel mondo reale troverai tutti i tipi di assurdità nei tag ID3 indipendentemente dalla versione.

dati da TIT2 inizia $ 01 e $ è seguito da FF $ FE, che credo sia a che fare con Unicode? Il testo stesso è suddiviso, però, ci sono $ 00, ogni carattere di testo,

Questo è UTF-16, la codifica del testo-to-byte Windows chiama erroneamente “Unicode”. È composto da unità di codice a due byte, quindi i caratteri nell'intervallo U + 0000-U + 00FF escono come il byte basso dello stesso numero, seguito da un byte alto zero. Il prefisso 0xFF-0xFE è un contrassegno dell'ordine byte correttamente utilizzato. Encoding.Unicode.GetString dovrebbe restituire una stringa corretta da questo-post un po 'di codice?

stampa di questi dati ad una console sembra funzionare

Ottenere caratteri non ASCII per stampare sulla console di Windows può essere una prova, quindi se si ha colpito problemi tenere a mente che possono essere causati da l'operazione di stampa stessa.

Per completezza, la codifica 0x02 è UTF-16BE senza BOM (non vi è motivo di esistere e non l'ho mai incontrato in natura) e la codifica 0x00 deve essere ISO-8859-1 , ma in realtà potrebbe essere praticamente qualsiasi codifica ASCII-superset, più probabilmente una codepage ANSI di Windows come Encoding.GetEncoding(1252) di uno standard come 8859-1.

+0

Grazie bobince - mi ha dato un sacco di lavorare su! – phanteh

0

Ottimo, ho ottenuto qualche codice per leggere correttamente l'Unicode & ASCII (sotto)!

Una domanda però - mi aspettavo che Encoding.UNICODE.GetString() gestisca il BOM, ma non sembra. Prendo che devi leggere questi byte & trattare con i dati di conseguenza te stesso? Ho appena spogliato i 2 byte se è UNICODE qui sotto.

public class Frame 
{ 
    FrameHeader _header; 
    public string data; 
    public string name; 


    public Frame(FrameHeader frm, byte[] bytes) 
    { 
     _header = frm; 
     name = _header._name; 
     if (!name.Equals("APIC")) 
     { 
      byte[] actualdata; 
      int y; 
      int x; 
      int encoding = bytes[0]; 

      if (encoding.Equals(1)) 
      { 
       y = 3; 
       actualdata = new byte[bytes.Length - 3]; 
       for (x = 0; x < (bytes.Length - 3); x++, y++) 
        actualdata[x] = bytes[y]; 
       data = Encoding.Unicode.GetString(actualdata); 
      } 
      else 
      { 
       y = 1; 
       actualdata = new byte[bytes.Length - 1]; 
       for (x = 0; x < (bytes.Length - 1); x++, y++) 
        actualdata[x] = bytes[y]; 
       data = Encoding.ASCII.GetString(actualdata); 
      } 
     } 
    } 
} 
5

Basta aggiungere un altro commento, per il codice di codifica del testo:

00 - ISO-8859-1 (ASCII).

01 - UCS-2 (Unicode codificato UTF-16 con distinta base), in ID3v2.2 e ID3v2.3.

02 - Unicode codificato in UTF-16BE senza distinta base, in ID3v2.4.

03 - codifica UTF-8 Unicode, in ID3v2.4.

da: http://en.wikipedia.org/wiki/ID3

+0

Solo per completezza, ISO-8859-1 è latino-1 (ASCII da 0..127 + dell'Europa occidentale accentuato i caratteri da 128..255) https://en.wikipedia.org/wiki/ISO/IEC_8859-1 –

+0

Sebbene non sia specifico, ho visto i tag UTF ID3v2.3 (01) senza il BOM. È stato codificato come UTF-16BE. Non sono sicuro se ci sia una sorta di default non ufficiale, ma Windows e uno strumento di terze parti sembravano decodificarlo correttamente. – Dustin