Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

java mp3 inputstream to byte array?

before you say "Google it", I tried, found a few interesting articles, but nothing worked.

I need to convert a mp3 file from a website to a byte stream, that I can later save into a file locally.

Here is my code (most important parts):

Url url = new Url("someUrl");
URLConnection conn = url.openConnection();
byte[] result = inputStreamToByteArray(conn.getInputStream());
// .... some code here
byteArrayToFile(result, "tmp.mp3");

public byte[] inputStreamToByteArray(InputStream inStream){
    InputStreamReader in = new InputStreamReader(inStream):
    ByteArrayOutputStream baos = new ByteArrayOutputStream();

    int next = inStream.read();
    while (next > -1){
        baos.write(next);
        next = in.read();
    }

    byte[] result = baos.toByteArray();
    baos.flush();
    in.close();
    return result;
} 

public void byteArrayToFile(byte[] byteArray, String outFilePath){
    FileOutputStream fos = new FileOutputStream(outFilePath);
    fos.write(byteArray);
    fos.close()
}

The code compiles without errors. Connection to the url is valid. It sends the right response.

The problem is somewhere in the conversion. I also get the new file on disk, after byteArrayToFile(), with appropriate lenght, but I can't play it in any player. It says length 00:00 and will not play.

Btw. I'd like to avoid any 3rd party libs. But if nothing else works...

like image 593
ZolaKt Avatar asked Dec 13 '22 18:12

ZolaKt


1 Answers

(The code you've presented wouldn't compile without errors, by the way. You haven't got required exception handling, and inputStream should be InputStream, just for starters.)

This is the problem:

InputStreamReader in = new InputStreamReader(inStream):

You're trying to read from a binary stream, and convert it into text. It isn't text. You shouldn't be using anything to do with "Reader" or "Writer" for binary data like an MP3 file.

Here's what your inputStreamToByteArray method should look like (or use Guava and its ByteStreams.toByteArray method):

public byte[] inputStreamToByteArray(InputStream inStream) throws IOException {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    byte[] buffer = new byte[8192];
    int bytesRead;
    while ((bytesRead = inStream.read(buffer)) > 0) {
        baos.write(buffer, 0, bytesRead);
    }
    return baos.toByteArray();
}

Note that I've left it for the caller to clean up the input stream. Typically whoever fetches the stream also closes it - it would be slightly odd for a method like this to close it itself, IMO. You could do so if you wanted to, but probably in a finally block so you'd know that it would always be closed even if an exception was thrown.

Note that your "writing" code later on won't close the file if there's an exception, either. You should get in the habit of always closing streams in finally blocks.

like image 180
Jon Skeet Avatar answered Dec 23 '22 23:12

Jon Skeet