Android Play Video File From Local SD Card / Web Example

This article shows you an example of how to use the android.widget.VideoView to play, pause, seek to, stop and replay video file. The video file can be browsed from a local SD card or a streaming video from a web URL.

1. VideoView Methods.

  1. android.widget.VideoView provides the below methods. Most of them can be understood by name.
  2. setVideoPath: Set video file local path or a URI instance.
  3. start: Play the video file.
  4. pause: Pause the playing video.
  5. resume: Replay the video from the beginning.
  6. seekTo: Seek to the specified video play position. Note this method is not always accurate, sometimes it will seek to the video beginning. We will write another article to tell you how to fix this issue.
  7. isPlaying: Return a boolean value to indicate whether the video is playing or not.
  8. getDuration: Get total video length.
  9. getCurrentPosition : Get current video playing position.

2. VideoView Example.

If you can not watch the above video, you can see it on the youtube URL https://youtu.be/lD_rJK7AzmU

  1. You can browse a local sd card stored video file or input a video file URL in the input text box. The web video URL should start with HTTP.
  2. Use the android device monitor to transfer the video files to the android sd card Movies directory as below.
  3. Run the command adb root in the shell ( dos window ) to make all android directories accessible.
  4. Open android device monitor in android studio. Push your video file to the sd card Movies folder.
    push-video-file-to-android-sd-card-movies-folder-use-android-device-monitor
  5. Click the browse button to select the video file to play, you can also input a web video file URL ( for example  http://dev2qa.com/demo/media/play_video_test.mp4 ) to play.

3. VideoView Example Source Code.

3.1 Main Activity.

  1. PlayVideoActivity.java
    package com.dev2qa.example.video.basic;
    
    import android.Manifest;
    import android.content.Intent;
    import android.content.pm.PackageManager;
    import android.media.MediaPlayer;
    import android.net.Uri;
    import android.os.Bundle;
    import android.os.Handler;
    import android.os.Message;
    import android.support.annotation.NonNull;
    import android.support.v4.app.ActivityCompat;
    import android.support.v4.content.ContextCompat;
    import android.support.v7.app.AppCompatActivity;
    import android.text.TextUtils;
    import android.view.KeyEvent;
    import android.view.View;
    import android.widget.Button;
    import android.widget.EditText;
    import android.widget.ProgressBar;
    import android.widget.Toast;
    import android.widget.VideoView;
    
    import com.dev2qa.example.R;
    
    public class PlayVideoActivity extends AppCompatActivity {
    
        private EditText videoPathEditor = null;
    
        private Button browseVideoFileButton = null;
    
        private Button playVideoButton = null;
    
        private Button stopVideoButton = null;
    
        private Button pauseVideoButton = null;
    
        private Button continueVideoButton = null;
    
        private Button replayVideoButton = null;
    
        private VideoView playVideoView = null;
    
        private ProgressBar videoProgressBar = null;
    
        // Request code for user select video file.
        private static final int REQUEST_CODE_SELECT_VIDEO_FILE = 1;
    
        // Request code for require android READ_EXTERNAL_PERMISSION.
        private static final int REQUEST_CODE_READ_EXTERNAL_PERMISSION = 2;
    
        // Used when update video progress thread send message to progress bar handler.
        private static final int UPDATE_VIDEO_PROGRESS_BAR = 3;
    
        // Save local video file uri.
        private Uri videoFileUri = null;
    
        // Wait update video progress thread sent message, then update video play progress.
        private Handler videoProgressHandler = null;
    
        // Save current video play position.
        private int currVideoPosition = 0;
    
        // Save whether the video is paused or not.
        private boolean isVideoPaused = false;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_play_video);
    
            setTitle("dev2qa.com - Android Play Video Example.");
    
            // Init this example used video components.
            initVideoControls();
    
            // When user input video file url in the video file path edittext input text box.
            videoPathEditor.setOnKeyListener(new View.OnKeyListener() {
                @Override
                public boolean onKey(View view, int i, KeyEvent keyEvent) {
                    int action = keyEvent.getAction();
                    if(action == KeyEvent.ACTION_UP) {
                        String text = videoPathEditor.getText().toString();
                        if (text.length() > 0) {
                            // If user input video file url, enable play button.
                            playVideoButton.setEnabled(true);
                            pauseVideoButton.setEnabled(false);
                            replayVideoButton.setEnabled(false);
                        } else {
                            // If user input nothing, disable all buttons.
                            playVideoButton.setEnabled(false);
                            pauseVideoButton.setEnabled(false);
                            replayVideoButton.setEnabled(false);
                        }
                    }
                    return false;
                }
            });
    
            // If user click browse video file button.
            browseVideoFileButton.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    // Check whether user has granted read external storage permission to this activity.
                    int readExternalStoragePermission = ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.READ_EXTERNAL_STORAGE);
    
                    // If not grant then require read external storage permission.
                    if(readExternalStoragePermission != PackageManager.PERMISSION_GRANTED)
                    {
                        String requirePermission[] = {Manifest.permission.READ_EXTERNAL_STORAGE};
                        ActivityCompat.requestPermissions(PlayVideoActivity.this, requirePermission, REQUEST_CODE_READ_EXTERNAL_PERMISSION);
                    }else {
                        selectVideoFile();
                    }
                }
            });
    
            // Click this button to play user browsed or input video file.
            playVideoButton.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    String videoFilePath = videoPathEditor.getText().toString();
    
                    if(!TextUtils.isEmpty(videoFilePath))
                    {
                        if(!videoFilePath.trim().toLowerCase().startsWith("http")) {
                            // Play local video file.
                            playVideoView.setVideoURI(videoFileUri);
                        }else
                        {
                            // Convert the web video url to a Uri object.
                            Uri webVideoFileUri = Uri.parse(videoFilePath.trim());
    
                            // Play web video file use the Uri object.
                            playVideoView.setVideoURI(webVideoFileUri);
                        }
    
                        playVideoView.setVisibility(View.VISIBLE);
    
                        videoProgressBar.setVisibility(ProgressBar.VISIBLE);
    
                        currVideoPosition = 0;
    
                        playVideoView.start();
    
                        playVideoButton.setEnabled(false);
    
                        stopVideoButton.setEnabled(true);
    
                        pauseVideoButton.setEnabled(true);
    
                        continueVideoButton.setEnabled(false);
    
                        replayVideoButton.setEnabled(true);
                    }
    
                }
            });
    
            // Click this button to stop playing video file.
            stopVideoButton.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
    
                    // Stop video playing.
                    playVideoView.stopPlayback();
    
                    // Seek to the beginning of the video file.
                    playVideoView.seekTo(0);
    
                    playVideoButton.setEnabled(true);
    
                    stopVideoButton.setEnabled(false);
    
                    pauseVideoButton.setEnabled(false);
    
                    continueVideoButton.setEnabled(false);
    
                    replayVideoButton.setEnabled(false);
                }
            });
    
            // Click this button to pause playing video file.
            pauseVideoButton.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
    
                    // Pause video play.
                    playVideoView.pause();
    
                    isVideoPaused = true;
    
                    // Record current video play position.
                    currVideoPosition = playVideoView.getCurrentPosition();
    
                    playVideoButton.setEnabled(false);
    
                    stopVideoButton.setEnabled(true);
    
                    pauseVideoButton.setEnabled(false);
    
                    continueVideoButton.setEnabled(true);
    
                    replayVideoButton.setEnabled(true);
                }
            });
    
            // Click this button to continue play paused video.
            continueVideoButton.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
    
                    playVideoView.seekTo(currVideoPosition);
    
                    playVideoButton.setEnabled(false);
    
                    pauseVideoButton.setEnabled(true);
    
                    stopVideoButton.setEnabled(true);
    
                    continueVideoButton.setEnabled(false);
    
                    replayVideoButton.setEnabled(true);
                }
            });
    
            // Click this button to replay video file.
            replayVideoButton.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
    
                    // Replay video.
                    playVideoView.resume();
    
                    // Set current video play position to 0.
                    currVideoPosition = 0;
    
                    playVideoButton.setEnabled(false);
    
                    pauseVideoButton.setEnabled(true);
    
                    stopVideoButton.setEnabled(true);
    
                    continueVideoButton.setEnabled(false);
    
                    replayVideoButton.setEnabled(true);
                }
            });
        }
    
        /*
          Initialize play video example controls.
        * */
        private void initVideoControls()
        {
            if(videoPathEditor==null)
            {
                videoPathEditor = (EditText) findViewById(R.id.play_video_file_path_editor);
            }
    
            if(browseVideoFileButton==null)
            {
                browseVideoFileButton = (Button)findViewById(R.id.browse_video_file_button);
            }
    
            if(playVideoButton==null)
            {
                playVideoButton = (Button)findViewById(R.id.play_video_start_button);
            }
    
            if(stopVideoButton==null)
            {
                stopVideoButton = (Button)findViewById(R.id.play_video_stop_button);
            }
    
            if(pauseVideoButton==null)
            {
                pauseVideoButton = (Button)findViewById(R.id.play_video_pause_button);
            }
    
            if(continueVideoButton==null)
            {
                continueVideoButton = (Button)findViewById(R.id.play_video_continue_button);
            }
    
            if(replayVideoButton==null)
            {
                replayVideoButton = (Button)findViewById(R.id.play_video_replay_button);
            }
    
            if(playVideoView==null)
            {
                playVideoView = (VideoView)findViewById(R.id.play_video_view);
            }
    
            if(videoProgressBar==null)
            {
                videoProgressBar = (ProgressBar) findViewById(R.id.play_video_progressbar);
            }
    
            if(videoProgressHandler==null)
            {
                // This handler wait and receive update progress bar message from child thread.
                videoProgressHandler = new Handler(){
                    @Override
                    public void handleMessage(Message msg) {
                        // When receive update progressbar message.
                        if(msg.what == UPDATE_VIDEO_PROGRESS_BAR)
                        {
                            // Get current video play position.
                            int currVideoPosition = playVideoView.getCurrentPosition();
    
                            // Get total video length.
                            int videoDuration = playVideoView.getDuration();
    
                            // Calculate the percentage.
                            int progressPercent = currVideoPosition * 100 / videoDuration;
    
                            // 10 times percentage value to make effect clear.
                            videoProgressBar.setProgress(progressPercent);
                        }
                    }
                };
    
                // This thread sends an update video progress message to the video progress Handler every 2 seconds.
                Thread updateProgressThread = new Thread()
                {
                    @Override
                    public void run() {
    
                        try {
                            while (true) {
                                // Create update video progressbar message.
                                Message msg = new Message();
                                msg.what = UPDATE_VIDEO_PROGRESS_BAR;
    
                                // Send the message to video progressbar update handler.
                                videoProgressHandler.sendMessage(msg);
    
                                // Sleep 2 seconds.
                                Thread.sleep(2000);
                            }
                        }catch (InterruptedException ex)
                        {
                            ex.printStackTrace();
                        }
                    }
                };
                // Start the thread.
                updateProgressThread.start();
            }
    
            setContinueVideoAfterSeekComplete();
        }
    
        /* This method start get content activity to let user select video file from local directory.*/
        private void selectVideoFile()
        {
            // Create an intent with action ACTION_GET_CONTENT.
            Intent selectVideoIntent = new Intent(Intent.ACTION_GET_CONTENT);
    
            // Show video in the content browser.
            // Set selectVideoIntent.setType("*/*") to select all data
            // Intent for this action must set content type, otherwise you will encounter below exception : android.content.ActivityNotFoundException: No Activity found to handle Intent { act=android.intent.action.GET_CONTENT }
            selectVideoIntent.setType("video/*");
    
            // Start android get content activity ( this is an android os built-in activity.).
            startActivityForResult(selectVideoIntent, REQUEST_CODE_SELECT_VIDEO_FILE);
        }
    
        /* This method will be invoked when startActivityForResult method complete in selectVideoFile() method.
        *  It is used to process activity result that is started by startActivityForResult method.
        * */
        @Override
        protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    
            // Identify activity by request code.
            if(requestCode == REQUEST_CODE_SELECT_VIDEO_FILE)
            {
                // If the request is success.
                if(resultCode==RESULT_OK)
                {
                    // To make example simple and clear, we only choose video file from local file,
                    // this is easy to get video file real local path.
                    // If you want to get video file real local path from a video content provider
                    // Please read another article.
                    videoFileUri = data.getData();
    
                    String videoFileName = videoFileUri.getLastPathSegment();
    
                    videoPathEditor.setText("You select video file is " + videoFileName);
    
                    playVideoButton.setEnabled(true);
    
                    pauseVideoButton.setEnabled(false);
    
                    replayVideoButton.setEnabled(false);
                }
            }
        }
    
        /* Run this method after user choose grant read external storage permission or not. */
        @Override
        public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
            if(requestCode==REQUEST_CODE_READ_EXTERNAL_PERMISSION)
            {
                if(grantResults.length > 0)
                {
                    int grantResult = grantResults[0];
                    if(grantResult == PackageManager.PERMISSION_GRANTED)
                    {
                        // If user grant the permission then open browser let user select audio file.
                        selectVideoFile();
                    }else
                    {
                        Toast.makeText(getApplicationContext(), "You denied read external storage permission.", Toast.LENGTH_LONG).show();
                    }
                }
            }
        }
    
        /* This method is used to play video after seek complete, otherwise video playing will not be accurate.*/
        private void setContinueVideoAfterSeekComplete()
        {
            playVideoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
                @Override
                public void onPrepared(MediaPlayer mediaPlayer) {
                    mediaPlayer.setOnSeekCompleteListener(new MediaPlayer.OnSeekCompleteListener() {
                        @Override
                        public void onSeekComplete(MediaPlayer mediaPlayer) {
                            if(isVideoPaused)
                            {
                                playVideoView.start();
                                isVideoPaused = false;
                            }
                        }
                    });
                }
            });
        }
    }

3.2 Main Layout Xml File.

  1. activity_play_video.xml
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">
    
        <EditText
            android:id="@+id/play_video_file_path_editor"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="Browse a video file path or input web video file url."/>
    
        <Button
            android:id="@+id/browse_video_file_button"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Browse Video File"/>
    
        <Button
            android:id="@+id/play_video_start_button"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Play Video"
            android:enabled="false"/>
    
        <Button
            android:id="@+id/play_video_stop_button"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Stop Play Video"
            android:enabled="false"/>
    
        <Button
            android:id="@+id/play_video_pause_button"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Pause Video"
            android:enabled="false"/>
    
        <Button
            android:id="@+id/play_video_continue_button"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Continue Video"
            android:enabled="false"/>
    
        <Button
            android:id="@+id/play_video_replay_button"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Replay Video"
            android:enabled="false"/>
    
        <ProgressBar
            android:id="@+id/play_video_progressbar"
            style="@android:style/Widget.ProgressBar.Horizontal"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:max="100"
            android:visibility="invisible"/>
    
        <VideoView
            android:id="@+id/play_video_view"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:visibility="invisible"/>
    
    
    </LinearLayout>

3.3 Android Manifest Xml File.

  1. Please note this example required permissions in this file.
  2. AndroidManifest.xml
    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.dev2qa.example">
    
        <!-- Play local video file required permission. -->
        <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    
        <!-- Play web url video file required permission. -->
        <uses-permission android:name="android.permission.INTERNET" />
    
        <application
            android:allowBackup="true"
            android:icon="@mipmap/ic_launcher"
            android:label="@string/app_name"
            android:roundIcon="@mipmap/ic_launcher_round"
            android:supportsRtl="true"
            android:theme="@style/AppTheme">
    
            <activity android:name=".video.basic.PlayVideoActivity">
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />
    
                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
            </activity>
        </application>
    
    </manifest>

Reference

  1. Android Play Local / URL Audio With ProgressBar Example
  2. Android Marshmallow Runtime Permission Example

2 thoughts on “Android Play Video File From Local SD Card / Web Example”

Leave a Comment

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

This site uses Akismet to reduce spam. Learn how your comment data is processed.