Android Play Video File From Local SD Card / Web Example

This article show you example about how to use android.widget.VideoView to play, pause, seek to, stop and replay video file. The video file can be browsed from local SD card or a stream video from a web url.

1. VideoView Methods.

android.widget.VideoView provide below methods. Most of them can be understood by name.

  1. setVideoPath : Set video file local path or a URI instance.
  2. start : Play the video file.
  3. pause : Pause the playing video.
  4. resume : Replay the video from beginning.
  5. seekTo : Seek to the specified video play position. Note this method is not always accurate, some time it will seek to the video beginning. We will write another article to tell you how to fix this issue.
  6. isPlaying : Return a boolean value to indicate whether the video is playing or not.
  7. getDuration : Get total video length.
  8. getCurrentPosition : Get current video playing position.

2. VideoView Example.

android play video file from local sd card or web example new

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.

Use android device monitor to transfer video file to android sd card Movies directory as below.

  1. Run adb root command in shell ( dos window ) to make all android directory accessible.
    adb root command to pull file in android device monitor
  2. Open android device monitor in android studio. Push your video file to sd card Movies folder.
    push video file to android sd card movies folder use android device monitor
  3. Click browse button to select the video file to play, you can also input a web video file url ( http://dev2qa.com/demo/media/play_video_test.mp4 ) to play.

3. VideoView Example Source Code.

3.1 Main Activity.

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);
            }
        });
    }

    /*
      Initialise 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 send update video progress message to 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 a 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.

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.

Please note this example required permissions in this file.

READ :   Android Display Data In Table Layout Statically And Programmatically Example

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 Comments


  1. good tutorial it’s work me thanks

    Reply

  2. Any place to download a complete source code package? I am using the Android Studio 3.3.

    Reply

Leave a Reply

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.