How to play video in video view from url based on buffer %age in android?

1.6k views Asked by At

I have a link of video from s3 server and i am playing this video on VideoView. Video is playing properly but the problem is that first it downloads the entire video then plays it.

I want it play like buffer. I mean if 20 % video downloaded it should play those and then again download (Like in youtube). Here is my code what i have done is..

 FFmpegMediaMetadataRetriever mediaMetadataRetriever = new FFmpegMediaMetadataRetriever();
      AWSCredentials myCredentials = new BasicAWSCredentials(
        "AKIAIGOIY4LLB7EMACGQ",
        "7wNQeY1JC0uyMaGYhKBKc9V7QC7X4ecBtyLimt2l");
      AmazonS3 s3client = new AmazonS3Client(myCredentials);
      GeneratePresignedUrlRequest request = new GeneratePresignedUrlRequest(
        "mgvtest", videoUrl);
      URL objectURL = s3client.generatePresignedUrl(request);

      try {
       mediaMetadataRetriever.setDataSource(videoUrl);
      } catch (Exception e) {
       utilDialog.showDialog("Unable to load this video",
         utilDialog.ALERT_DIALOG);
       pb.setVisibility(View.INVISIBLE);
      }

      videoView.setVideoURI(Uri.parse(videoUrl));
     MediaController myMediaController = new MediaController(this);
      // myMediaController.setMediaPlayer(videoView);
      videoView.setMediaController(myMediaController);

      videoView.setOnCompletionListener(myVideoViewCompletionListener);
      videoView.setOnPreparedListener(MyVideoViewPreparedListener);
      videoView.setOnErrorListener(myVideoViewErrorListener);

      videoView.requestFocus();
      videoView.start();

Listeners

MediaPlayer.OnCompletionListener myVideoViewCompletionListener = new MediaPlayer.OnCompletionListener() {

  @Override
  public void onCompletion(MediaPlayer arg0) {
   // Toast.makeText(PlayRecordedVideoActivity.this, "End of Video",
   // Toast.LENGTH_LONG).show();
  }
 };

 MediaPlayer.OnPreparedListener MyVideoViewPreparedListener = new MediaPlayer.OnPreparedListener() {

  @Override
  public void onPrepared(MediaPlayer mp) {
   pb.setVisibility(View.INVISIBLE);
   imgScreenshot.setVisibility(View.VISIBLE);
   tvScreenshot.setVisibility(View.VISIBLE);

   // final Animation in = new AlphaAnimation(0.0f, 1.0f);
   // in.setDuration(3000);
   // tvScreenshot.startAnimation(in);

   Animation animation = AnimationUtils.loadAnimation(
     getApplicationContext(), R.anim.zoom_in);
   tvScreenshot.startAnimation(animation);

   new Handler().postDelayed(new Runnable() {

    @Override
    public void run() {
     tvScreenshot.setVisibility(View.INVISIBLE);
    }
   }, 3000);
  }
 };

 MediaPlayer.OnErrorListener myVideoViewErrorListener = new MediaPlayer.OnErrorListener() {

  @Override
  public boolean onError(MediaPlayer mp, int what, int extra) {

   // Toast.makeText(PlayRecordedVideoActivity.this, "Error!!!",
   // Toast.LENGTH_LONG).show();
   return true;
  }
 };
2

There are 2 answers

0
Mick On BEST ANSWER

To be able to start playing an mp4 video before it has fully downloaded the video has to have the metadata at the start of the video rather than the end - unfortunately, with standard mp4 the default it usually to have it at the end.

The metadata is in an 'atom' or 'box' (basically a data structure within the mp4 file) and can be moved to the start. This is usually referred to as faststart and tools such as ffmpeg will allow you do this. The following is an extract from the ffmpeg documentation:

The mov/mp4/ismv muxer supports fragmentation. Normally, a MOV/MP4 file has all the metadata about all packets stored in one location (written at the end of the file, it can be moved to the start for better playback by adding faststart to the movflags, or using the qt-faststart tool).

There are other tools and software which will allow you do this also - e.g. the one mentioned in the ffmpeg extract above:

If you actually want full streaming where the server breaks the file into chunks and these are downloaded one by one by the client, then you probably want to use one of the adaptive bit rate protocols (Apple's HLS, MS's Smoothstreaming, Adobe Adaptive Streaming or the new open standard DASH). This also allows you have different bit rates to allow for different network conditions. You will need a server that can support this functionality to use these techniques. This may be overkill if you just want a simple site with a single video and will not have too much traffic.

3
NullByte On

Actually you have to start cloudfront with s3, so can stream s3 videos, checkout this link for more information: http://www.miracletutorials.com/s3-streaming-video-with-cloudfront/