I'm trying to implement a feature in an app I'm making which enables the user to listen to an online stream. What I need to do is to download the file along with playing it.
I've figured out so much that I need a local HTTP server which I used NanoHTTPD. Now the tricky part is how to actually download and stream the audio at the same time.
This is the code I've came up with so far:
public class LocalHttpServer extends NanoHTTPD {
    public static final int SERVER_PORT = 5987;
    private String mUrl;
    private InputStream input;
    private FileOutputStream output;
    public LocalHttpServer(String url) {
        super(SERVER_PORT);
        mUrl = url;
    }
    private File createFile(String url) {
        File path = new File(MyApplication.getContext().getFilesDir(), "audio/");
        path.mkdirs();
        return new File(path, Util.md5(url));
    }
    @Override
    public Response serve(IHTTPSession session) {
        input = null;
        output = null;
        HttpURLConnection connection = null;
        try {
            URL url = new URL(mUrl);
            connection = (HttpURLConnection) url.openConnection();
            connection.connect();
            if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) {
                return new Response(Response.Status.BAD_REQUEST, "audio/mpeg3", null, 0);
            }
            int fileLength = connection.getContentLength();
            input = connection.getInputStream();
            output = new FileOutputStream(createFile(mUrl));
            new Thread(new Runnable() {
                @Override
                public void run() {
                    byte data[] = new byte[4096];
                    int count;
                    try {
                        while ((count = input.read(data)) != -1) {
                            output.write(data, 0, count);
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    } finally {
                        try {
                            if (output != null)
                                output.close();
                            if (input != null)
                                //input.close(); don't close it
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }).start();
            return new Response(Response.Status.OK, "audio/mpeg3", input, fileLength);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return new Response(Response.Status.BAD_REQUEST, "audio/mpeg3", null, 0);
    }
}
The problem with it is when fed to a MediaPlayer, the unexpected end of stream exception occurs.
                        
Since nobody posted an answer to my question I bring here another solution which I used to accomplish a somewhat similar task.
I figured I could use an AsyncTask to download file and when the download reached the 10% of total start the MediaPlayer using interface callbacks. And along the update the MediaPlayer whenever another 20% has been downloaded.
Here is the source for the said AsyncTask: https://gist.github.com/2hamed/63a31bd55fc6514d12b5
if you notice there is the
DownloadCallbackat the end of the code.