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