2

我正在寻找一种从远程服务器上的 MP3 文件中读取 ID3 标签而不实际下载文件的方法。我见过像 JAudioTagger 和 Entagged 这样的库,但它们似乎都需要一个文件对象而不是 URL 或 InputStream,我知道如何获取远程文件。是否有另一个图书馆可以做到这一点?或者有没有办法让正确的对象使用 URL 与这些类进行交互?

4

3 回答 3

7

ID3 Tags are located in the last 128 ( 355 if using extended tag ) bytes of the file, so you are going to at least have to download part of the file. As HTTP supports range specific file access, it should be theoretically possible to do this (though I do not know of any libraries that would do it for you).

Essentially what would need to happen is to do a HEAD request to get the length of the file in bytes, then perform a GET on the file with the Range length-355 to the end of the file. This would return the necessary metadata. This gives a good idea of what a ranged request looks like.

Sorry though that I do not know of any libraries that would do this automatically, but it isn't a particularly difficult task to set up the getter. From there it is possible to write the metadata to a temp file and have it parsed by your ID3 parser.

于 2010-10-29T19:56:56.393 回答
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();
    }   
于 2014-02-28T12:40:26.693 回答
-1

本页介绍如何获取 MP3 文件的 ID3 V.1标签。http://willcode4beer.com/parsing.jsp?set=mp3ID3

它提供了一个..

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

..method 这就是您想要的远程 URL。基本思想是获取一个 URLConnection 并查询它以获取 MP3 中数据的长度,然后从该数字中减去 128 并将其用作开始参数(否则它会慢)。

于 2010-10-30T01:41:05.917 回答