MediaPlayer,能夠播放視頻/音頻,而且它支持本地和網絡文件的播放.本片博客做爲入門教程,先以最通俗的方式解釋播放文件本地視頻.(若是你嫌MediaPlayer仍是太麻煩能夠試試選擇VideoView)java
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
播放本地視頻,那就須要讀寫存儲權限,注意別忘記了動態受權android
音視頻開發的基本操做,在xml的根佈局上添加下面這個屬性,也能夠在SurfaceView上添加數組
android:keepScreenOn="true"
做爲顯示播放視頻的曲面View,若是你還不瞭解它.那麼建議你先學習一些SurfaceView的知識.網絡
咱們須要監聽SurfaceView狀態,肯定它啓動完畢以後咱們在開始加載播放視頻.在onCreate執行下面的初始化initSurfaceviewStateListenersession
private void initSurfaceviewStateListener() { mSurfaceHolder = mVideoPlaySurfaceview.getHolder(); mSurfaceHolder.addCallback(new SurfaceHolder.Callback() { @Override public void surfaceCreated(SurfaceHolder holder) { mMediaPlayer.setDisplay(holder);//給mMediaPlayer添加預覽的SurfaceHolder setPlayVideo(mPath);//添加播放視頻的路徑 } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { Log.e(TAG, "surfaceChanged觸發: width=" + width + "height" + height); } @Override public void surfaceDestroyed(SurfaceHolder holder) { } }); }
在surfaceCreated方法裏執行了2個方法:(固然能夠先不關注,下面依然會從新提到它們)app
private void initMediaPalyer() { mMediaPlayer = new MediaPlayer(); }
直接new,沒說明好說的,也是能夠先在onCreate執行initMediaPalyer異步
SurfaceView初始化完成後直接給MediaPlayer設置SurfaceHolder >>>>> mMediaPlayer.setDisplay(holder);ide
mSurfaceHolder.addCallback(new SurfaceHolder.Callback() { @Override public void surfaceCreated(SurfaceHolder holder) { mMediaPlayer.setDisplay(holder);//給mMediaPlayer添加預覽的SurfaceHolder setPlayVideo(mPath);//添加播放視頻的路徑 }
private void setPlayVideo(String path) { try { mMediaPlayer.setDataSource(path);//設置播放視頻文件 mMediaPlayer.setVideoScalingMode(MediaPlayer.VIDEO_SCALING_MODE_SCALE_TO_FIT);//縮放模式 mMediaPlayer.setLooping(true);//設置循環播放 mMediaPlayer.prepareAsync();//異步準備 // mMediaPlayer.prepare();//同步準備,由於是同步在一些性能較差的設備上會致使UI卡頓 mMediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() { //準備完成回調 @Override public void onPrepared(MediaPlayer mp) { mp.start();//啓動播放視頻 } }); } catch (IOException e) { e.printStackTrace(); } }
setPlayVideo方法,在surfaceCreated接口回調方法裏執行便可.上面已經有寫就不在重複交代了
private void startPlay(){ if (!mMediaPlayer.isPlaying()){ //判斷視頻是否在播放 mMediaPlayer.start(); } }
private void pausePlay(){ if (mMediaPlayer.isPlaying()){ mMediaPlayer.pause(); } }
private void stopPlay(){ if (mMediaPlayer.isPlaying()){ mMediaPlayer.stop(); } }
這是必要的,由於MediaPlayer底層是運行C++的函數方法.不要使用後,必需釋放內存函數
@Override protected void onDestroy() { super.onDestroy(); if (mMediaPlayer != null){ if (mMediaPlayer.isPlaying()){ mMediaPlayer.stop(); } mMediaPlayer.release(); mMediaPlayer = null; } }
xml文件oop
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:fitsSystemWindows="true" android:keepScreenOn="true" android:background="@color/colorBlack1" tools:context=".work.share.VideoPlayActivity"> <SurfaceView android:id="@+id/video_play_surfaceview" android:layout_width="wrap_content" android:layout_height="wrap_content" app:layout_constraintHorizontal_bias="0.5" app:layout_constraintVertical_bias="0.5" app:layout_constraintTop_toTopOf="parent" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent"/> <ImageView android:id="@+id/start_and_stop" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@mipmap/ic_start" android:layout_marginBottom="50dp" android:layout_marginLeft="20dp" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintBottom_toBottomOf="parent" /> </androidx.constraintlayout.widget.ConstraintLayout>
activity
import androidx.constraintlayout.widget.ConstraintLayout; import android.content.pm.ActivityInfo; import android.media.MediaPlayer; import android.os.Bundle; import android.util.Log; import android.view.SurfaceHolder; import android.view.SurfaceView; import android.view.View; import android.widget.ImageView; import com.yt.kangaroo.R; import com.yt.kangaroo.app.BaseActivity; import java.io.File; import java.io.IOException; /** *@content:視頻播放activity *@time:2019-6-13 *@build: */ public class VideoPlayActivity extends BaseActivity implements View.OnClickListener { private static final String TAG = VideoPlayActivity.class.getSimpleName(); private SurfaceView mVideoPlaySurfaceview; private ImageView mStartAndStop; private MediaPlayer mMediaPlayer; private String mPath; private boolean isInitFinish = false; private SurfaceHolder mSurfaceHolder; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED); File file = new File(getExternalCacheDir(), "demo.mp4"); mPath = file.getAbsolutePath(); initMediaPalyer(); initSurfaceviewStateListener(); } @Override protected void onPause() { super.onPause(); pausePlay(); } @Override public int getLayout() { return R.layout.activity_video_play; } @Override public void initView() { mVideoPlaySurfaceview = findViewById(R.id.video_play_surfaceview); mStartAndStop = findViewById(R.id.start_and_stop); mStartAndStop.setOnClickListener(this); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.start_and_stop: if (mMediaPlayer.isPlaying()) { pausePlay(); mStartAndStop.setImageResource(R.mipmap.ic_start); } else { startPlay(); mStartAndStop.setImageResource(R.mipmap.ic_stop); } break; default: break; } } private void initSurfaceviewStateListener() { mSurfaceHolder = mVideoPlaySurfaceview.getHolder(); mSurfaceHolder.addCallback(new SurfaceHolder.Callback() { @Override public void surfaceCreated(SurfaceHolder holder) { mMediaPlayer.setDisplay(holder);//給mMediaPlayer添加預覽的SurfaceHolder setPlayVideo(mPath);//添加播放視頻的路徑 } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { Log.e(TAG, "surfaceChanged觸發: width=" + width + "height" + height); } @Override public void surfaceDestroyed(SurfaceHolder holder) { } }); } private void initMediaPalyer() { mMediaPlayer = new MediaPlayer(); } private void setPlayVideo(String path) { try { mMediaPlayer.setDataSource(path);// mMediaPlayer.setVideoScalingMode(MediaPlayer.VIDEO_SCALING_MODE_SCALE_TO_FIT);//縮放模式 mMediaPlayer.setLooping(true);//設置循環播放 mMediaPlayer.prepareAsync();//異步準備 // mMediaPlayer.prepare();//同步準備,由於是同步在一些性能較差的設備上會致使UI卡頓 mMediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() { //準備完成回調 @Override public void onPrepared(MediaPlayer mp) { isInitFinish = true; mp.start(); } }); } catch (IOException e) { e.printStackTrace(); } } private void startPlay(){ if (!mMediaPlayer.isPlaying()){ mMediaPlayer.start(); } } private void stopPlay(){ if (mMediaPlayer.isPlaying()){ mMediaPlayer.stop(); } } private void pausePlay(){ if (mMediaPlayer.isPlaying()){ mMediaPlayer.pause(); } } private void seekTo(int time){ mMediaPlayer.seekTo(time); } @Override protected void onDestroy() { super.onDestroy(); if (mMediaPlayer != null){ if (mMediaPlayer.isPlaying()){ mMediaPlayer.stop(); } mMediaPlayer.release(); mMediaPlayer = null; } } }
end