2010-10-29 104 views
2

我正在尋找一種方法來讀取遠程服務器上的MP3文件中的ID3標籤,而無需實際下載文件。我已經見過像JAudioTagger和Entagged這樣的庫,但都似乎需要一個文件對象,而不是URL或InputStream,我知道如何使用遠程文件。有另一個圖書館可以做到這一點嗎?或者有沒有辦法讓正確的對象與使用URL的這些類進行交互?使用Java讀取遠程MP3文件的ID3標籤

回答

-1

此頁面描述如何獲取ID3 V. 1 MP3文件的標籤。 http://willcode4beer.com/parsing.jsp?set=mp3ID3

它提供了一個..

public Tag readTag(InputStream in, long start) throws .. 

..method那就是你會想什麼遠程URL。基本思路是獲取一個URLConnection &查詢MP3中數據的長度,然後從該數字中減去128作爲起始參數(否則將會是非常慢)。

+0

我最終使用這段代碼的適應來實現我想要的。我首先打開了一個URLConnection來獲取文件的長度。然後我打開另一個URLConnection,並將setRequestProperty的範圍設置爲128。這最終比從URLConnection打開一個InputStream然後跳過128的大小要快得多。 – Zach 2010-12-26 00:27:17

7

ID3標籤位於文件的最後128個字符(如果使用擴展標籤的話),因此您至少不得不下載部分文件。由於HTTP支持範圍特定的文件訪問,所以理論上可以這樣做(儘管我不知道任何可以爲你做的庫)。

本質上,需要發生的是執行HEAD請求以字節爲單位獲取文件的長度,然後在範圍length-355的文件上對文件執行GET操作。這將返回必要的元數據。 This給出了一個遠程請求的樣子。

對不起,雖然我不知道任何會自動執行此操作的庫,但設置getter並不是一件特別困難的任務。從那裏可以將元數據寫入臨時文件,並由ID3解析器進行解析。

0
String tmp=""; 
    int bytes_read; 

    try{ 
     //RandomAccessFile file = new RandomAccessFile("/mnt/sdcard/Music/6 am (reggaeton).mp3", "r"); 
     RandomAccessFile file = new RandomAccessFile("/mnt/sdcard/Music/Jorge Vercilo - Final feliz.mp3", "r"); 

     long fsize=file.length(); 
     System.out.println("Abriu arquivo"); 
     byte[] buf = new byte[1024]; 
     bytes_read = file.read(buf, 0, 10); 
     System.out.println("Leu "+String.valueOf(bytes_read)); 
     if(bytes_read==10){ 
      if(buf[0] == 'I' &&buf[1] == 'D' && buf[2] == '3') { 
       System.out.println("É ID3"); 
       int version = (buf[4]<<8) + (buf[3] & 0xff); 
       System.out.println("Versão: "+String.valueOf(version)); 
       if(buf[5] == 0x00) System.out.println("Clear flags"); 
       long size = ((buf[9] & 0xFF) << 0) | 
          ((buf[8] & 0xFF) << 8) | 
          ((buf[7] & 0xFF) << 16) | 
          ((buf[6] & 0xFF) << 24); 
       System.out.println("Size: "+String.valueOf(size)); 

       long p = 10; 
       long frame_size; 
       String encoding=""; 
       while(p<fsize){ 
        file.seek(p); 
        bytes_read = file.read(buf, 0, 10); 
        if(bytes_read==10){ 
         frame_size = ((buf[7] & 0xFF) << 0) | 
          ((buf[6] & 0xFF) << 8) | 
          ((buf[5] & 0xFF) << 16) | 
          ((buf[4] & 0xFF) << 24); 
         System.out.println("Frame size: "+String.valueOf(frame_size)); 
         tmp = new String(buf,0,4); 
         System.out.println("Frame type: "+tmp); 

         if(buf[0] == 'T' && buf[1] == 'P' && buf[2] == 'E' && buf[3] == '1') {// artist 
          p+=10; 
          file.seek(p); 
          if(file.read(buf, 0, (int)frame_size)==frame_size){ 
           if(buf[0]==0x01) encoding="UTF-16"; 
           else if(buf[0]==0x02) encoding="UTF-16BE"; 
           else if(buf[0]==0x03) encoding="UTF-8"; 
           if(buf[0]==0x00) tmp = new String(buf,1,(int)frame_size-1); 
           else tmp = new String(buf,1,(int)frame_size-1,encoding); 
           System.out.println("Artist: "+tmp); 
          } 
          p+=frame_size; 
         } 
         else if(buf[0] == 'T' && buf[1] == 'I' && buf[2] == 'T' && buf[3] == '2') {// title 
          p+=10; 
          file.seek(p); 
          if(file.read(buf, 0, (int)frame_size)==frame_size){ 
           if(buf[0]==0x01) encoding="UTF-16"; 
           else if(buf[0]==0x02) encoding="UTF-16BE"; 
           else if(buf[0]==0x03) encoding="UTF-8"; 
           if(buf[0]==0x00) tmp = new String(buf,1,(int)frame_size-1); 
           else tmp = new String(buf,1,(int)frame_size-1,encoding); 
           System.out.println("title: "+tmp); 
          } 
          p+=frame_size; 
         } 
         else if(buf[0] == 0x00 && buf[1] == 0x00 && buf[2] == 0x00 && buf[3] == 0x00) {// END OF HEADER 
          break; 
         } 
         else p+= frame_size+10; 
        } 
        //checar se ja pegou o title e o artist 
       } 
      } 
     } 

     if(file!=null) file.close(); 
    }catch(Exception e){ 
     System.out.println("ERROOOOOOOOO!"); 
     e.printStackTrace(); 
    }