Android开发 MediaPlayer播放本地视频完善的demo(只是代码记录)
xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/root_layout"
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_sex_male"
android:layout_marginBottom="10dp"
android:layout_marginLeft="10dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="@id/vedio_current_time"
app:layout_constraintBottom_toBottomOf="parent" /> <TextView
android:id="@+id/vedio_current_time"
android:text="当前时间"
android:textColor="@color/fontWhite"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
app:layout_constraintTop_toTopOf="@id/start_and_stop"
app:layout_constraintBottom_toBottomOf="@id/start_and_stop"
app:layout_constraintLeft_toRightOf="@id/start_and_stop"
app:layout_constraintRight_toLeftOf="@id/vedio_seek"/> <SeekBar
android:id="@+id/vedio_seek"
android:layout_width="0dp"
android:layout_height="0dp"
android:maxHeight="3dp"
android:minHeight="3dp"
android:progressDrawable="@drawable/vedio_seekbar_bg"
app:layout_constraintTop_toTopOf="@id/start_and_stop"
app:layout_constraintBottom_toBottomOf="@id/start_and_stop"
app:layout_constraintLeft_toRightOf="@id/vedio_current_time"
app:layout_constraintRight_toRightOf="@id/vedio_total_time"/> <TextView
android:id="@+id/vedio_total_time"
android:textColor="@color/fontWhite"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="10dp"
app:layout_constraintTop_toTopOf="@id/start_and_stop"
app:layout_constraintBottom_toBottomOf="@id/start_and_stop"
app:layout_constraintLeft_toRightOf="@id/vedio_seek"
app:layout_constraintRight_toRightOf="parent"/> <ImageView
android:id="@+id/back"
android:layout_width="wrap_content"
android:layout_height="@dimen/title_height"
android:paddingLeft="20dp"
android:src="@mipmap/ic_back_white"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"/> <TextView
android:id="@+id/vedio_settings"
android:textColor="@color/fontWhite"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="10dp"
android:visibility="gone"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintRight_toRightOf="parent"/> </androidx.constraintlayout.widget.ConstraintLayout>
代码
/**
*@content:视频播放activity
*@time:2019-6-13 */ public class VideoPlayActivity extends BaseActivity implements View.OnClickListener {
private static final String TAG = VideoPlayActivity.class.getSimpleName();
private ConstraintLayout mRootLayout;
private SurfaceView mVideoPlaySurfaceview;
private ImageView mStartAndStop, mBack;
private MediaPlayer mMediaPlayer;
private SeekBar mVedioSeek;
private TextView mVedioCurrentTimeTextView, mVedioTotalTimeTextView, mVedioSettings;
private String mPath;
private boolean isInitFinish = false;
private SurfaceHolder mSurfaceHolder;
private Handler mHandler;
private final int GET_VIDEO_PLAY_TIME_KEY = 0x01;
private final int GONS_VIEW_KEY = 0x02;
private static int mCurrentPlayTime = 0; //因为切换横竖屏后,activity其实是重新创建的,所以需要用静态变量保存当前播放时间
private int mTotalPlayTime = 0;
SimpleDateFormat mTimeFormat = new SimpleDateFormat("mm:ss"); @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
initVedioSeekListener();
initHandler();
mHandler.sendEmptyMessageDelayed(GONS_VIEW_KEY,8*1000);
File file = new File(getExternalCacheDir(), "demo.mp4");
mPath = file.getAbsolutePath();
initMediaPalyer();
initSurfaceviewStateListener(); } @Override
protected void onPause() {
super.onPause();
pausePlay();
} @Override
protected void onResume() {
super.onResume();
startPlay();
} @Override
public int getLayout() {
return R.layout.activity_video_play;
} @Override
public void initView() {
mRootLayout = findViewById(R.id.root_layout);
mVideoPlaySurfaceview = findViewById(R.id.video_play_surfaceview);
mStartAndStop = findViewById(R.id.start_and_stop);
mVedioCurrentTimeTextView = findViewById(R.id.vedio_current_time);
mVedioTotalTimeTextView = findViewById(R.id.vedio_total_time);
mVedioSeek = findViewById(R.id.vedio_seek);
mVedioSettings = findViewById(R.id.vedio_settings);
mBack = findViewById(R.id.back);
mStartAndStop.setOnClickListener(this);
mBack.setOnClickListener(this);
mRootLayout.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_sex_male);
} else {
startPlay();
mStartAndStop.setImageResource(R.mipmap.ic_sex_female);
}
break;
case R.id.back:
finish();
break;
case R.id.root_layout:
mStartAndStop.setVisibility(View.VISIBLE);
mVedioSettings.setVisibility(View.VISIBLE);
mVedioTotalTimeTextView.setVisibility(View.VISIBLE);
mVedioCurrentTimeTextView.setVisibility(View.VISIBLE);
mBack.setVisibility(View.VISIBLE);
mVedioSeek.setVisibility(View.VISIBLE);
mHandler.sendEmptyMessageDelayed(GONS_VIEW_KEY,8*1000);
break;
default:
break;
} } private void initHandler(){
mHandler = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what){
case GET_VIDEO_PLAY_TIME_KEY:
if (mMediaPlayer != null){
mCurrentPlayTime = mMediaPlayer.getCurrentPosition();
L.e("每秒mCurrentPlayTime="+mCurrentPlayTime);
mVedioSeek.setProgress(mCurrentPlayTime/1000);
mVedioCurrentTimeTextView.setText(mTimeFormat.format(mCurrentPlayTime)); }
mHandler.sendEmptyMessageDelayed(GET_VIDEO_PLAY_TIME_KEY,1000);
break;
case GONS_VIEW_KEY:
mStartAndStop.setVisibility(View.GONE);
mVedioSettings.setVisibility(View.GONE);
mVedioTotalTimeTextView.setVisibility(View.GONE);
mVedioCurrentTimeTextView.setVisibility(View.GONE);
mBack.setVisibility(View.GONE);
mVedioSeek.setVisibility(View.GONE);
break;
default:
break; }
}
};
} private void initVedioSeekListener(){
mVedioSeek.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { } @Override
public void onStartTrackingTouch(SeekBar seekBar) { } @Override
public void onStopTrackingTouch(SeekBar seekBar) {
mMediaPlayer.seekTo(seekBar.getProgress()*1000);
mCurrentPlayTime = mMediaPlayer.getCurrentPosition();
mVedioCurrentTimeTextView.setText(mTimeFormat.format(mCurrentPlayTime)); }
});
} 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;
mMediaPlayer.start();
mHandler.sendEmptyMessage(GET_VIDEO_PLAY_TIME_KEY);
mTotalPlayTime = mMediaPlayer.getDuration();
if (mTotalPlayTime == -1){
Toast.makeText(VideoPlayActivity.this, "视频文件时间异常", Toast.LENGTH_SHORT).show();
finish();
}
mVedioSeek.setMax(mTotalPlayTime/1000);
mVedioTotalTimeTextView.setText(formatTime(mTotalPlayTime));
}
});
mMediaPlayer.setOnVideoSizeChangedListener(new MediaPlayer.OnVideoSizeChangedListener() { //尺寸变化回调
@Override
public void onVideoSizeChanged(MediaPlayer mp, int width, int height) {
changeVideoSize();
L.e("mCurrentPlayTime="+mCurrentPlayTime);
seekTo(mCurrentPlayTime); }
});
mMediaPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {
@Override
public boolean onError(MediaPlayer mp, int what, int extra) {
L.e("视频播放错误,错误原因what="+what+"extra="+extra);
return false;
}
});
mMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) { }
});
} catch (IOException e) {
e.printStackTrace();
}
} /**
* 修改视频的大小,以用来适配屏幕
*/
public void changeVideoSize() {
int videoWidth = mMediaPlayer.getVideoWidth();
int videoHeight = mMediaPlayer.getVideoHeight();
int deviceWidth = getResources().getDisplayMetrics().widthPixels;
int deviceHeight = getResources().getDisplayMetrics().heightPixels;
Log.e(TAG, "changeVideoSize: deviceHeight="+deviceHeight+"deviceWidth="+deviceWidth);
float devicePercent = 0;
//下面进行求屏幕比例,因为横竖屏会改变屏幕宽度值,所以为了保持更小的值除更大的值.
if (getResources().getConfiguration().orientation == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT) { //竖屏
devicePercent = (float) deviceWidth / (float) deviceHeight; //竖屏状态下宽度小与高度,求比
}else { //横屏
devicePercent = (float) deviceHeight / (float) deviceWidth; //横屏状态下高度小与宽度,求比 } if (videoWidth > videoHeight){
if (getResources().getConfiguration().orientation == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT){
videoWidth = deviceWidth;
videoHeight = (int)(videoHeight/devicePercent); }else {
videoWidth = deviceWidth;
videoHeight = (int)(deviceWidth*devicePercent);
} }else {
if (getResources().getConfiguration().orientation == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT) {//竖屏 videoHeight = deviceHeight;
float videoPercent = (float) videoWidth / (float) videoHeight;
float differenceValue = Math.abs(videoPercent - devicePercent);
if (differenceValue < 0.3){
videoWidth = deviceWidth;
}else {
videoWidth = (int)(videoWidth/devicePercent);
} }else { //横屏
videoHeight = deviceHeight;
videoWidth = (int)(deviceHeight*devicePercent); } } ConstraintLayout.LayoutParams layoutParams = (ConstraintLayout.LayoutParams) mVideoPlaySurfaceview.getLayoutParams();
layoutParams.width = videoWidth;
layoutParams.height = videoHeight;
layoutParams.verticalBias = 0.5f;
layoutParams.horizontalBias = 0.5f;
mVideoPlaySurfaceview.setLayoutParams(layoutParams); } 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);
} private String formatTime(long time){
return mTimeFormat.format(time);
} @Override
protected void onDestroy() {
super.onDestroy();
if (mMediaPlayer != null){
if (mMediaPlayer.isPlaying()){
mMediaPlayer.stop();
}
mMediaPlayer.release();
mMediaPlayer = null;
}
} }
Android开发 MediaPlayer播放本地视频完善的demo(只是代码记录)的更多相关文章
- Android使用VideoView播放本地视频及网络视频Demo
1.xm文件 <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:and ...
- Android 使用意图播放本地视频
Android播放视频的方式有三种: 一.使用意图播放,调用本地安装的播放器,选择一个进行播放. 二.使用VideoView播放(VideoView事实上是对MediaPlayer的封装,使用起来非常 ...
- Android开发之获取本地视频和获取自拍视频
1.获取本地所有视频 public void getLoadMedia() { Cursor cursor = UILApplication.instance.getApplicationContex ...
- Android开发 MediaPlayer播放raw资源MP3文件
代码 private MediaPlayer mRingPlayer; /** * 播放铃声 */ private void startRing(){ if (mRingPlayer != null) ...
- Android开发 MediaPlayer入门_播放本地视频
前言 MediaPlayer,可以播放视频/音频,并且它支持本地和网络文件的播放.本片博客作为入门教程,先以最通俗的方式解释播放文件本地视频.(如果你嫌MediaPlayer还是太麻烦可以试试选择Vi ...
- 照相、从相册上取照片、播放音频、播放本地视频、播放网络视频、MPMoviePlayerController
一.照相.从相册上去照片 1. 先判断是否支持照相功能 *判断当前设备是否支持照相功能,支持返回YES 否则返回NO 注意:模拟器不支持照相功能 把握一个原则只要是物理硬件相关的功能模拟器都不支持 例 ...
- Swift - 使用Media Player播放本地视频,在线视频
Media Player框架用于播放本地视频.音频,也可以在线播放视频和音频. 1,播放器MPMovieControlStyle样式有如下几种: (1)None: 没有播放控制控件 (2)Embedd ...
- potplayer 网页调用potplayer播放本地视频
网页调用potplayer播放本地视频 CreateTime--2018年1月3日10:36:24 Author:Marydon 源码展示: <!DOCTYPE html> <h ...
- Android 视频播放器 VideoView 的使用,播放本地视频 和 网络 视频
1.布局文件 <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:and ...
随机推荐
- 【记录】API Gateway作用? 与过滤器的区别?Nginx与Zuul区别?
网关(gateway)的作用: 网关可以拦截客户端所有请求,对该请求进行权限控制.负载均衡.日志管理.接口调用监控等 过滤器与网关的区别是什么? 过滤器是拦截单个tomcat服务器请求. 网关是拦截整 ...
- AMS5601的ardunio和STM32驱动开发
AMS5601的ardunio和STM32驱动开发 本文有麦粒电子撰写,并提供相应产品服务. 前言 目前ams关于磁编码芯片用的比较多的可能是ams5600,能够输出pwm信号,电压信号以及I2C通信 ...
- [转]【Git】rebase 用法小结
https://www.jianshu.com/p/4a8f4af4e803 本文主要参考 https://git-scm.com/docs/git-rebase rebase在git中是一个非常有魅 ...
- 在Mac OS终端的Terminal 中使用Sublime Text3
查看环境变量: $ echo $PATH $ /usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin 创建软链接: $ sudo ln -s /Application ...
- spring framework三个版本的下载包区别
docs:该文件夹下包含Spring的相关文档.开发指南及API参考文档:dist:该文件夹下包含Spring jar包.文档.项目等内容:schema:里面包含了Spring4所用到的xsd文件:
- Java高并发网络编程(二)BIO
一.阻塞 服务器端 public class BIOServer { public static void main(String[] args) throws Exception { ServerS ...
- 【TCP】TCP状态
下图所示,TCP通信过程包括三个步骤:建立TCP连接通道(三次握手).数据传输.断开TCP连接通道(四次挥手). 这里进一步探究TCP三路握手和四次挥手过程中的状态变迁以及数据传输过程.先看TCP状态 ...
- 「AHOI / HNOI2018」转盘 解题报告
「AHOI / HNOI2018」转盘 可能是我语文水平不太行... 首先可以猜到一些事实,这个策略一定可以被一个式子表示出来,不然带修修改个锤子. 然后我们发现,可以枚举起点,然后直接往前走,如果要 ...
- noip2007 tg day1t1 统计数字
题目描述 某次科研调查时得到了n个自然数,每个数均不超过1500000000(1.5*10^9).已知不相同的数不超过10000个,现在需要统计这些自然数各自出现的次数,并按照自然数从小到大的顺序输出 ...
- NX二次开发-Block UI C++界面Enumeration(枚举)控件的获取(持续补充)
NX9+VS2012 public: void SetBlockUIShow(); void EnumInt::SetBlockUIShow() { //获取枚举控件 PropertyList* En ...