Android MediaPlayer and VideoView Tutorial

1- MediaPlayer

Android provides a component  to play music, it's MediaPlayer. MediaPlayer can run audio and video files, the source file is located on your device or from a URL.

Just like with other music player that you know, MediaPlayer provides methods to control playback of audio/video, including start, stop, rewind .....

You can also call MediaPlayer  from a service.

MediaPlayer is a component that don't have interface, it help you play a music file easily, but to play a video file you need to combine it with SuffaceView to display imagine. 

2- VideoView

VideoView is a custommized component which is available of Android, it is the combination of MediaPlayer and SuffaceView which  help you to play a video more easily.
When using VideoView, you can use MediaController, this is available in Android which used to control media (such as start, stop, rewind, pause...)
IF you locate  VideoView and  MediaController in a  FrameLayout, you can get interface as follow:

3- MediaPlayer example

The following simple example, use Media Player to play a music file and some controls of the play such as play, pause, rewind.
Create a project named MediaPlayerTutorial:
Create  raw  to contain the music file.
Prepare a music file, copy and paste to  raw folder.
This is the interface of the examples:
Design the interface:
Set up methods which will be called when clicking buttons:
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:tools="http://schemas.android.com/tools"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   android:paddingBottom="@dimen/activity_vertical_margin"
   android:paddingLeft="@dimen/activity_horizontal_margin"
   android:paddingRight="@dimen/activity_horizontal_margin"
   android:paddingTop="@dimen/activity_vertical_margin"
   tools:context="org.o7planning.mediaplayertutorial.MainActivity">

   <Button
       style="?android:attr/buttonStyleSmall"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:text="&lt;&lt;"
       android:id="@+id/button_rewind"
       android:layout_marginLeft="60dp"
       android:layout_marginStart="60dp"
       android:layout_marginTop="81dp"
       android:layout_below="@+id/textView_currentPosion"
       android:layout_alignParentLeft="true"
       android:layout_alignParentStart="true"
       android:onClick="doRewind" />

   <Button
       style="?android:attr/buttonStyleSmall"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:text="Start"
       android:id="@+id/button_start"
       android:layout_alignBottom="@+id/button_rewind"
       android:layout_toRightOf="@+id/button_rewind"
       android:layout_toEndOf="@+id/button_rewind"
       android:onClick="doStart" />

   <Button
       style="?android:attr/buttonStyleSmall"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:text="Pause"
       android:id="@+id/button_pause"
       android:layout_alignBottom="@+id/button_start"
       android:layout_toRightOf="@+id/button_start"
       android:layout_toEndOf="@+id/button_start"
       android:onClick="doPause" />

   <Button
       style="?android:attr/buttonStyleSmall"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:text=">>"
       android:id="@+id/button_fastForward"
       android:layout_alignBottom="@+id/button_pause"
       android:layout_toRightOf="@+id/button_pause"
       android:layout_toEndOf="@+id/button_pause"
       android:onClick="doFastForward" />

   <SeekBar
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:id="@+id/seekBar"
       android:layout_alignParentLeft="true"
       android:layout_alignParentStart="true"
       android:layout_alignParentTop="true"
       android:layout_alignParentRight="true"
       android:layout_alignParentEnd="true" />

   <TextView
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:textAppearance="?android:attr/textAppearanceLarge"
       android:text="&lt;Current Position>"
       android:id="@+id/textView_currentPosion"
       android:layout_marginTop="65dp"
       android:gravity="center"
       android:layout_below="@+id/textView_maxTime"
       android:layout_centerHorizontal="true" />

   <TextView
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:textAppearance="?android:attr/textAppearanceLarge"
       android:text="&lt;Max Time>"
       android:id="@+id/textView_maxTime"
       android:layout_below="@+id/seekBar"
       android:layout_alignParentRight="true"
       android:layout_alignParentEnd="true"
       android:layout_marginTop="38dp"
       android:layout_alignParentLeft="true"
       android:layout_alignParentStart="true"
       android:gravity="center" />
</RelativeLayout>
MainActivity.java
package org.o7planning.mediaplayertutorial;

import android.media.MediaPlayer;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.SeekBar;
import android.widget.TextView;

import java.util.concurrent.TimeUnit;

public class MainActivity extends AppCompatActivity {

   private TextView textMaxTime;
   private TextView textCurrentPosition;
   private Button buttonPause;
   private Button buttonStart;
   private SeekBar seekBar;
   private Handler threadHandler = new Handler();

   private MediaPlayer mediaPlayer;
   @Override
   protected void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       setContentView(R.layout.activity_main);

       this.textCurrentPosition = (TextView)this.findViewById(R.id.textView_currentPosion);
       this.textMaxTime=(TextView) this.findViewById(R.id.textView_maxTime);
       this.buttonStart= (Button) this.findViewById(R.id.button_start);
       this.buttonPause= (Button) this.findViewById(R.id.button_pause);

       this.buttonPause.setEnabled(false);

       this.seekBar= (SeekBar) this.findViewById(R.id.seekBar);
       this.seekBar.setClickable(false);

       // ID of 'mysong' in 'raw' folder.
       int songId = this.getRawResIdByName("mysong");

       // Create MediaPlayer.
       this.mediaPlayer=   MediaPlayer.create(this, songId);
   }

   // Find ID of resource in 'raw' folder.
   public int getRawResIdByName(String resName)  {
       String pkgName = this.getPackageName();
       // Return 0 if not found.
       int resID = this.getResources().getIdentifier(resName, "raw", pkgName);
       return resID;
   }

   // Convert millisecond to string.
   private String millisecondsToString(int milliseconds)  {
       long minutes = TimeUnit.MILLISECONDS.toMinutes((long) milliseconds);
       long seconds =  TimeUnit.MILLISECONDS.toSeconds((long) milliseconds) ;
       return minutes+":"+ seconds;
   }


   public void doStart(View view)  {
       // The duration in milliseconds
       int duration = this.mediaPlayer.getDuration();

       int currentPosition = this.mediaPlayer.getCurrentPosition();
       if(currentPosition== 0)  {
           this.seekBar.setMax(duration);
           String maxTimeString = this.millisecondsToString(duration);
           this.textMaxTime.setText(maxTimeString);
       } else if(currentPosition== duration)  {
           // Resets the MediaPlayer to its uninitialized state.
           this.mediaPlayer.reset();
       }
       this.mediaPlayer.start();
       // Create a thread to update position of SeekBar.
       UpdateSeekBarThread updateSeekBarThread= new UpdateSeekBarThread();
       threadHandler.postDelayed(updateSeekBarThread,50);

       this.buttonPause.setEnabled(true);
       this.buttonStart.setEnabled(false);
   }

   // Thread to Update position for SeekBar.
   class UpdateSeekBarThread implements Runnable {

       public void run()  {
           int currentPosition = mediaPlayer.getCurrentPosition();
           String currentPositionStr = millisecondsToString(currentPosition);
           textCurrentPosition.setText(currentPositionStr);

           seekBar.setProgress(currentPosition);
           // Delay thread 50 milisecond.
           threadHandler.postDelayed(this, 50);
       }
   }

   // When user click to "Pause".
   public void doPause(View view)  {
       this.mediaPlayer.pause();
       this.buttonPause.setEnabled(false);
       this.buttonStart.setEnabled(true);
   }

   // When user click to "Rewind".
   public void doRewind(View view)  {
       int currentPosition = this.mediaPlayer.getCurrentPosition();
       int duration = this.mediaPlayer.getDuration();
       // 5 seconds.
       int SUBTRACT_TIME = 5000;

       if(currentPosition - SUBTRACT_TIME > 0 )  {
           this.mediaPlayer.seekTo(currentPosition - SUBTRACT_TIME);
       }
   }

   // When user click to "Fast-Forward".
   public void doFastForward(View view)  {
       int currentPosition = this.mediaPlayer.getCurrentPosition();
       int duration = this.mediaPlayer.getDuration();
       // 5 seconds.
       int ADD_TIME = 5000;

       if(currentPosition + ADD_TIME < duration)  {
           this.mediaPlayer.seekTo(currentPosition + ADD_TIME);
       }
   }

}
Running apps:

4- Playing a video with VideoView example

Now, we can see an example with  VideoView and MediaController located on the surface of the video. You can preview images in following example:
Create a Project named AndroidVideoView:
Create raw folder to store video files.
Copy & Paste video files to raw folder:
Design the Interface:
Drag  VideoView to the Center of  FrameView
Note that  FrameLayout have only a cell to contain all subview, 9 subarea that you see ebove just are 9 gravity areas.
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="org.o7planning.androidvideoview.MainActivity">

    <VideoView
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:id="@+id/videoView"
        android:layout_gravity="center" />

</FrameLayout>
MainActivity.java
package org.o7planning.androidvideoview;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.res.Configuration;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnPreparedListener;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.widget.MediaController;
import android.widget.VideoView;

public class MainActivity extends AppCompatActivity {


    private VideoView videoView;
    private int position = 0;
    private MediaController mediaController;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);


        videoView = (VideoView) findViewById(R.id.videoView);

        // Set the media controller buttons
        if (mediaController == null) {
            mediaController = new MediaController(MainActivity.this);

            // Set the videoView that acts as the anchor for the MediaController.
            mediaController.setAnchorView(videoView);


            // Set MediaController for VideoView
            videoView.setMediaController(mediaController);
        }


        try {
            // ID of video file.
            int id = this.getRawResIdByName("myvideo");
            videoView.setVideoURI(Uri.parse("android.resource://" + getPackageName() + "/" + id));

        } catch (Exception e) {
            Log.e("Error", e.getMessage());
            e.printStackTrace();
        }

        videoView.requestFocus();


        // When the video file ready for playback.
        videoView.setOnPreparedListener(new OnPreparedListener() {

            public void onPrepared(MediaPlayer mediaPlayer) {


                videoView.seekTo(position);
                if (position == 0) {
                    videoView.start();
                }

                // When video Screen change size.
                mediaPlayer.setOnVideoSizeChangedListener(new MediaPlayer.OnVideoSizeChangedListener() {
                    @Override
                    public void onVideoSizeChanged(MediaPlayer mp, int width, int height) {

                        // Re-Set the videoView that acts as the anchor for the MediaController
                        mediaController.setAnchorView(videoView);
                    }
                });
            }
        });

    }

    // Find ID corresponding to the name of the resource (in the directory raw).
    public int getRawResIdByName(String resName) {
        String pkgName = this.getPackageName();
        // Return 0 if not found.
        int resID = this.getResources().getIdentifier(resName, "raw", pkgName);
        Log.i("AndroidVideoView", "Res Name: " + resName + "==> Res ID = " + resID);
        return resID;
    }


    // When you change direction of phone, this method will be called.
    // It store the state of video (Current position)
    @Override
    public void onSaveInstanceState(Bundle savedInstanceState) {
        super.onSaveInstanceState(savedInstanceState);

        // Store current position. 
        savedInstanceState.putInt("CurrentPosition", videoView.getCurrentPosition());
        videoView.pause();
    }


    // After rotating the phone. This method is called.
    @Override
    public void onRestoreInstanceState(Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);

        // Get saved position.
        position = savedInstanceState.getInt("CurrentPosition");
        videoView.seekTo(position);
    }

}
Running apps:
Some note to the code:
Imagine when you use  setAnchorView() to attach  MediaController to  VideoView:
Playing Video from URL:
First, you must declare permission to access Internet  ( android.permission.INTERNET) in  AndroidManifest.xml:
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
   package="org.o7planning.androidvideoview">

   <uses-permission android:name="android.permission.INTERNET"></uses-permission>

   <application
       android:allowBackup="true"
       android:icon="@mipmap/ic_launcher"
       android:label="@string/app_name"
       android:supportsRtl="true"
       android:theme="@style/AppTheme">



       <activity android:name=".MainActivity">
           <intent-filter>
               <action android:name="android.intent.action.MAIN" />

               <category android:name="android.intent.category.LAUNCHER" />
           </intent-filter>
       </activity>
   </application>

</manifest>
Java Code:
// Way 1:

String videoUrl="http://www.youtubemaza.com/files/data/366/Tom%20And%20Jerry%20055%20Casanova%20Cat%20(1951).mp4";        
Uri video = Uri.parse(videoUrl);
videoView.setVideoURI(video);


// Way 2:

String videoUrl="http://www.youtubemaza.com/files/data/366/Tom%20And%20Jerry%20055%20Casanova%20Cat%20(1951).mp4";    
videoView.setVideoPath(video);