Чтение ID3-тегов удаленного MP3-файла с использованием Java - PullRequest
2 голосов
/ 29 октября 2010

Я ищу способ чтения тегов ID3 ​​из файла MP3 на удаленном сервере без фактической загрузки файла. Я видел такие библиотеки, как JAudioTagger и Entagged, но обе они, похоже, требуют объект файла, а не URL или InputStream, которые я знаю, как получить с удаленным файлом. Есть ли другая библиотека, которая может сделать это? Или есть способ заставить правильный объект взаимодействовать с этими классами, используя URL?

Ответы [ 3 ]

7 голосов
/ 29 октября 2010

ID3-теги расположены в последних 128 (355 при использовании расширенного тега) байтах файла, поэтому вам, по крайней мере, придется загрузить часть файла. Так как HTTP поддерживает доступ к файлам, зависящим от диапазона, это должно быть теоретически возможно (хотя я не знаю ни одной библиотеки, которая бы делала это для вас).

По сути, что должно произойти, это выполнить запрос HEAD, чтобы получить длину файла в байтах, а затем выполнить GET для файла с диапазоном length-355 до конца файла. Это вернет необходимые метаданные. Это дает хорошее представление о том, как выглядит ранжированный запрос.

Извините, что я не знаю ни одной библиотеки, которая бы делала это автоматически, но это не особенно сложная задача для установки геттера. Оттуда можно записать метаданные во временный файл и проанализировать его вашим анализатором ID3.

0 голосов
/ 28 февраля 2014
    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();
    }   
0 голосов
/ 30 октября 2010

На этой странице описано, как получить ID3 V.1 теги файла MP3.http://willcode4beer.com/parsing.jsp?set=mp3ID3

Он предлагает ..

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

.. метод, который вам нужен для удаленного URL.Основная идея состоит в том, чтобы получить URLConnection и запросить его для длины данных в MP3, затем вычесть 128 из этого числа и использовать его в качестве аргумента начала (иначе это будет очень медленно).

...