How to stream and download a video using VideoView in Android

Hi there,

It’s been a while I haven’t written anything here, well was busy with my new company and consulting others!

A customer of mine wants to download and play video simultaneously at first I was confidence that  requirement is easy! But it was only a dream because android’s SDK support no such functionality for whatever reason.

But hopefully VideoView supports http streaming and it leads me to implement a HTTP internal server as a fake http streaming server and ask VideoView to get data from it!

it sound quite easy but there are loads of things that you need to take care.

1-creating a HTTP server, thanks Lord there is one for free NanoHTTPD

2-read data in chunks and send it back to VideoView

3-respond to VideoView so it could request for other chunks.

for this part you have to check if VideoView is sending request with “Range” header if not it means it is the first time so you have to response with “Content-Range: bytes 0-YOUR_CHUNK” also you have to send the “Content-Length : full length of file” so that VideoView could request back for other chunks and at the end don’t forget to send your response with “206” not with “200”.

“HTTP 206” means partial data!

4-your video files must be encoded correctly otherwise it doesn’t work at all, you can read full article here or just simply download ffmpeg and encode your video with that!

the rest is code : I just copied the useful part here, you can find the full solution in my github

 

    public class VideoStreamServer extends NanoHTTPD
    {
 
        public VideoStreamServer(int port) {
            super(port);
        }
 
        @Override
        public Response serve(String uri, Method method, Map<String, String> headers, Map<String, String> parms, Map<String, String> files) {
 
            //range=bytes=619814-
            long range;
 
            if (headers.containsKey("range"))
            {
                String contentRange = headers.get("range");
                range = Integer.parseInt(contentRange.substring(contentRange.indexOf("=") + 1, contentRange.indexOf("-")));
            }
            else
                range = 0;
 
            byte[] buffer;
            int constantLength = 256000;
            long bufLength=0;
            boolean isLastPart=false;
            try {
 
                RandomAccessFile ff =new RandomAccessFile(new File("/mnt/sdcard","1.mp4"),"rw" );
                long remainingChunk = ff.length() - range; //remaining
                if (remainingChunk < constantLength){
                    bufLength= remainingChunk; //means last part
                    isLastPart = true;
                }
 
                else
                    bufLength = constantLength;
                if (range !=0)
                    ff.seek(range);
                buffer= new byte[(int)bufLength];
 
                ff.read(buffer);
 
            } catch (FileNotFoundException e) {
                e.printStackTrace();
                buffer = new byte[0];
            } catch (IOException e) {
                e.printStackTrace();
                buffer = new byte[0];
            }
            Response response;
 
                response = new Response(Response.Status.PARTIAL_CONTENT,"video/mp4",new ByteArrayInputStream(buffer));
 
            response.addHeader("Content-Length","891064");
            response.addHeader("Content-Range",String.format("bytes %s-%s/%s", range,(range+bufLength),"891064"));
            Log.e("SERVER","Inside server sent " + String.format("bytes %s-%s/%s", range,(range+bufLength),"891064"));
            return response;
 
        }
    }

2 thoughts on “How to stream and download a video using VideoView in Android

  1. Hi,

    I have the same problem and your idea sounds really smart. But how do you actually download the movie? With AsyncTask? How do I make sure it downloads the right parts and am I able to read while the system still writes?

    If I understand your example code correctly you just read from the external sd card File file = new File("/mnt/sdcard","1-ffmpeg.mp4"); (MyActivity.java ln 77)

Leave a Reply

Your email address will not be published. Required fields are marked *

*