I want to move a progressively streamed mp3 file to sd card once it is completely loaded. Is there any way of achieving that.
I've seen that the MediaPlayer
completely downloads the whole file while progressive streaming and then we can seek to any part of file. I want to move a fully streamed file to external storage so that future playback do not waste data and battery.
The comment on the original post points you in the right direction, but I thought it may be helpful to expound a bit...
What I've done is build a lightweight proxy server using the Apache HTTP libraries. There should be plenty of examples out there to get the basics of this part. Provide the MediaPlayer an appropriate localhost URL so that it opens a socket to your proxy. When the MediaPlayer makes a request, use the proxy to send an equivalent request to the actual media host. You will receive byte[] data in the proxy's packetReceived method, which I use to build an HttpGet and send it on its way with AndroidHttpClient.
You will get back an HttpResponse and you can use the HttpEntity inside to access the streaming byte data. I'm using a ReadableByteChannel, like so:
HttpEntityWrapper entity = (HttpEntityWrapper)response.getEntity();
ReadableByteChannel src = Channels.newChannel(entity.getContent());
Do whatever you'd like with the data as you read it back (like cache it in a file on the SD card). To pass the correct stuff on to the MediaPlayer, get the SocketChannel from the client Socket, first write the response headers directly to that channel, and then proceed to write the entity's byte data. I'm using an NIO ByteBuffer in a while loop (client is a Socket and buffer is a ByteBuffer).
int read, written;
SocketChannel dst = client.getChannel();
while (dst.isConnected() &&
dst.isOpen() &&
src.isOpen() &&
(read = src.read(buffer)) >= 0) {
try {
buffer.flip();
// This is one point where you can access the stream data.
// Just remember to reset the buffer position before trying
// to write to the destination.
if (buffer.hasRemaining()) {
written = dst.write(buffer);
// If the player isn't reading, wait a bit.
if (written == 0) Thread.sleep(15);
buffer.compact();
}
}
catch (IOException ex) {
// handle error
}
}
You may need to alter the host header in the response before passing it along to the player so that it looks like your proxy is the sender, but I'm dealing with a proprietary implementation of the MediaPlayer so behaviour could be a bit different. Hope that helps.