Записать mp3-файл на диск во время игры на Java

У меня есть приложение, воспроизводящее удаленные файлы MP3 через HTTP с использованием библиотек JLayer/BasicPlayer. Я хочу сохранить проигранные файлы mp3 на диск без их повторной загрузки.

Это код, использующий BasicPlayer на основе JLayer для воспроизведения файла MP3.

String mp3Url = "http://ia600402.us.archive.org/6/items/Stockfinster.-DeadLinesutemos025/01_Push_Push.mp3";
URL url = new URL(mp3Url);
URLConnection conn = url.openConnection();
InputStream is = conn.getInputStream();
BufferedInputStream bis = new BufferedInputStream(is);

BasicPlayer player = new BasicPlayer();
player.open(bis);
player.play();

Как мне сохранить mp3 файл на диск?


person nanoman    schedule 15.02.2012    source источник


Ответы (3)


Чтобы не проходить байты дважды, нужно обернуть входной поток из соединения в фильтр, который записывает любые прочитанные данные в выходной поток, т.е. своего рода «входной поток тройника». Такой класс не так сложно написать самостоятельно, но вы можете сохранить работу, используя TeeInputStream из библиотеки Apache Commons IO.

Apache Commons IO: http://commons.apache.org/io/
TeeInputStream javadoc: http://commons.apache.org/io/apidocs/org/apache/commons/io/input/TeeInputStream.html

Изменить: проверка концепции:

import java.io.*;

public class TeeInputStream extends InputStream {
    private InputStream in;
    private OutputStream out;

    public TeeInputStream(InputStream in, OutputStream branch) {
        this.in=in;
        this.out=branch;
    }
    public int read() throws IOException {
        int read = in.read();
        if (read != -1) out.write(read);
        return read;
    }
    public void close() throws IOException {
        in.close();
        out.close();
    }
}

Как это использовать:

...
BufferedInputStream bis = new BufferedInputStream(is);
TeeInputStream tis = new TeeInputStream(bis,new FileOutputStream("test.mp3"));

BasicPlayer player = new BasicPlayer();
player.open(tis);
player.play();
person Joni    schedule 15.02.2012

Вы можете сначала записать поток на диск с помощью FileInputStream. Затем перезагрузите поток из файла.

person Summer_More_More_Tea    schedule 15.02.2012

Оберните свой собственный InputStream

class myInputStream extends InputStream {

    private InputStream is;
    private FileOutputStream resFile;
    public myInputStream(InputStream is) throws FileNotFoundException {
        this.is = is;
        resFile = new FileOutputStream("path_to_result_file");
    }

    @Override
    public int read() throws IOException {
        int b = is.read();
        if (b != -1)
            resFile.write(b);
        return b;
    }

    @Override
    public void close() {
        try {
            resFile.close();
        } catch (IOException ex) {
        }
        try {
            is.close();
        } catch (IOException ex) {
        }
    }
}

и использовать

InputStream is = conn.getInputStream();
myInputStream myIs = new myInputStream(is);
BufferedInputStream bis = new BufferedInputStream(myIs);
person turbanoff    schedule 15.02.2012