Android uses MediaPlayer to play local videos

MediaPlayer can play video and audio, and it supports playback of local and network files.This article is about using MediaPlayer to play local videos. If you find it difficult to use MediaPlayer, you can also choose VideoView to play videos.

The MainActivity.java code is as follows:

package per.juan.playvideodome;

import androidx.appcompat.app.AppCompatActivity;

import android.content.Context;
import android.content.res.AssetFileDescriptor;
import android.media.MediaPlayer;
import android.os.Build;
import android.os.Bundle;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.WindowManager;

public class MainActivity extends AppCompatActivity {
    SurfaceView mSvVideoPlayer;

    private MediaPlayer mMediaPlayer;
    private int mPosition = 0;
    private boolean hasActiveHolder = false;

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

        mSvVideoPlayer = findViewById(R.id.sv_video_player);
        playVideo();
    }

    /**
     * Play Video
     */
    public void playVideo() {
        if (mMediaPlayer == null) {
            //Instantiate MediaPlayer object
            mMediaPlayer = new MediaPlayer();
            mSvVideoPlayer.setVisibility(View.VISIBLE);
            boolean mHardwareDecoder = false;
            // Show directly without maintaining its own buffer
            if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB && mHardwareDecoder) {
                mSvVideoPlayer.getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
            }
            mSvVideoPlayer.getHolder().setFixedSize(getScreenWidth(), getScreenHeight());
            mSvVideoPlayer.getHolder().setKeepScreenOn(true);//Keep the screen always on
            mSvVideoPlayer.getHolder().addCallback(new SurFaceCallback());
        }
    }

    /**
     * Set the dispay, SurfaceHolder, to the player.However, at this point it is possible that SurfaceView has not been created successfully, so you need to listen for SurfaceView creation events
     */
    private final class SurFaceCallback implements SurfaceHolder.Callback {

        @Override
        public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

        }

        @Override
        public void surfaceCreated(SurfaceHolder holder) {
            if (mMediaPlayer == null) {
                return;
            }
            if (!hasActiveHolder) {
                play(mPosition);
                hasActiveHolder = true;
            }
            if (mPosition > 0) {
                play(mPosition);
                mPosition = 0;
            }
        }

        @Override
        public void surfaceDestroyed(SurfaceHolder holder) {
            if (mMediaPlayer == null) {
                return;
            }
            if (mMediaPlayer.isPlaying()) {
                mMediaPlayer.stop();
                mPosition = mMediaPlayer.getCurrentPosition();
            }
        }

        private void play(int position) {
            try {
                //Add path to play video and configure MediaPlayer
                AssetFileDescriptor fileDescriptor = getResources().openRawResourceFd(R.raw.info);
                mMediaPlayer.reset();
                //Add a preview of SurfaceHolder to mMediaPlayer to associate the player with SurfaceView
                mMediaPlayer.setDisplay(mSvVideoPlayer.getHolder());

                mMediaPlayer.setDataSource(fileDescriptor.getFileDescriptor(),
                        fileDescriptor.getStartOffset(),
                        fileDescriptor.getLength());
                // buffer
                mMediaPlayer.prepare();
                mMediaPlayer.setOnBufferingUpdateListener(new BufferingUpdateListener());
                mMediaPlayer.setOnPreparedListener(new PreparedListener(position));
                mMediaPlayer.setOnCompletionListener(new CompletionListener());
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * Callback when buffer changes
     */
    private final class BufferingUpdateListener implements MediaPlayer.OnBufferingUpdateListener {

        @Override
        public void onBufferingUpdate(MediaPlayer mp, int percent) {
        }
    }

    /**
     * Ready to complete callback
     * Playback is only possible when the player is ready, so the play can only be sent after triggering the prepare
     */
    private final class PreparedListener implements MediaPlayer.OnPreparedListener {
        private int position;

        public PreparedListener(int position) {
            this.position = position;
        }

        @Override
        public void onPrepared(MediaPlayer mp) {
            mMediaPlayer.start();
            if (position > 0) {
                mMediaPlayer.seekTo(position);
            }
        }
    }

    /**
     * Callback at end of playback
     */
    private final class CompletionListener implements MediaPlayer.OnCompletionListener {

        @Override
        public void onCompletion(MediaPlayer mp) {
            mMediaPlayer.start();
        }
    }

    @Override
    public void onDestroy() {
        //Release memory, the bottom level of MediaPlayer is a function method to run C++, memory must be released after not being used
        if (mMediaPlayer != null) {
            if (mMediaPlayer.isPlaying()) {
                mMediaPlayer.pause();
                mPosition = mMediaPlayer.getCurrentPosition();
            }
            mMediaPlayer.release();
            mMediaPlayer = null;
        }
        super.onDestroy();
    }

    private int getScreenWidth() {
        return ((WindowManager) getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getWidth();
    }

    private int getScreenHeight() {
        return ((WindowManager) getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay()
                .getHeight();
    }
}

activity_main.xml file

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <SurfaceView
        android:id="@+id/sv_video_player"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:visibility="gone" />

</RelativeLayout>

The main API s are:

  • void setDataSource(String path) sets the MediaPlayer's data source through a specific path, which can be either a local path or a network path
  • The void setDataSource(Context context, Uri uri) sets the MediaPlayer's data source by a given Uri, where the Uri can be a network path or a Uri of a ContentProvider.
  • void setDataSource(MediaDataSource dataSource) sets the data source by providing a MediaDataSource
  • void setDataSource(FileDescriptor fd) Sets the data source through FileDescriptor
  • int getCurrentPosition() Gets the current playing position
  • int getAudioSessionId() returns the session ID of the audio
  • Time when int getDuration() got the file
  • TrackInfo[] getTrackInfo() returns an array of trace information
  • Whether boolean isLooping () plays in a loop
  • Is boolean isPlaying() playing
  • void pause () paused
  • void start () start
  • void stop () stop
  • void prepare() loads streaming media files synchronously.
  • void prepareAsync() loads streaming media files asynchronously.
  • void reset() resets the MediaPlayer to an uninitialized state.
  • void release () recycles streaming media resources.
  • void seekTo(int msec) specifies where to play (time in milliseconds)
  • void setAudioStreamType(int streamtype) Specifies the streaming media type
  • void setLooping(boolean looping) Sets whether or not a single loop
  • void setNextMediaPlayer(MediaPlayer next) When the current MediaPlayer has finished playing, MediaPlayer next starts playing
  • void setWakeMode(Context context, int mode): Sets the state of CPU wake-up.
  • setOnBufferingUpdateListener(MediaPlayer.OnBufferingUpdateListener listener) Callback when buffer of network streaming media changes
  • setOnCompletionListener(MediaPlayer.OnCompletionListener listener) Callback at end of network streaming media playback
  • Callback on setOnErrorListener(MediaPlayer.OnErrorListener listener) error
  • setOnPreparedListener(MediaPlayer.OnPreparedListener listener): Callback when the loading of streaming media is complete.
  • setOnInfoListener(OnInfoListener l) Information Listening

Okay, that's it for this article. There are some inadequate summaries to guide you. Thank you _

Tags: MediaPlayer Android SurfaceView network

Posted on Wed, 04 Sep 2019 21:06:08 -0700 by ashmo