给大伙儿推荐一下这个视频播放框架,我也是在项目中用了一下,发现效果挺牛逼的,也支持自定义。基于原生VideoView有很多使用地方受限制,所以基本上项目中遇到视频播放的需求,都会采用视频框架,而不是采取原生VideoView来播放。传送门:https://github.com/CarGuo/GSYVideoPlayer。下面我就简单的抽取了其中的很常见的功能用法整理成了一个Demo,仅供参考,更多用法请移步大神的GitHub去看。
先完整引入:
compile 'com.shuyu:GSYVideoPlayer:4.1.0'
核心代码:
public class MainActivity extends Activity {
private MyStandardGSYVideoPlayer player;
private String url = "http://9890.vod.myqcloud.com/9890_4e292f9a3dd011e6b4078980237cc3d3.f30.mp4";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
player = findViewById(R.id.player);
player.loadCoverImage(url,R.mipmap.ic_launcher);//设置封面为视频第一帧(默认无封面,黑屏显示)
player.getBackButton().setVisibility(View.INVISIBLE);//非全屏时返回按钮隐藏(默认可见)
player.getTitleTextView().setVisibility(View.INVISIBLE);//非全屏时标题隐藏(默认可见)
player.setShowFullAnimation(true);//全屏过渡动画(默认开启)
player.setLockLand(true);//全屏后横屏显示(默认竖屏)
player.setThumbPlay(true);//是否点击封面也可以播放(默认false)
player.setHideKey(false);//全屏时是否隐藏屏幕虚拟按键(默认隐藏)
player.setIsTouchWiget(false);//非全屏时滑动界面是否可以改变进度,亮度、声音等(默认可以)
player.setIsTouchWigetFull(false);//全屏时滑动界面是否可以改变进度,亮度、声音等(默认可以)
player.setLooping(true);//是否循环播放视频(默认false)
player.setNeedLockFull(true);//全屏时是否显示小锁锁定屏幕功能(默认不显示)
player.setDismissControlTime(3000);//触摸屏幕时显示UI的时间(默认2500)
//上面的一切设置最好都放在setUp之前,放在之后可能不生效
player.setUp(url,true,"镜花水月");
//全屏按键监听
player.getFullscreenButton().setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
player.startWindowFullscreen(MainActivity.this, false, false);
}
});
//播放过程中状态监听回调
player.setVideoAllCallBack(new VideoAllCallBack() {
@Override
public void onStartPrepared(String url, Object... objects) {
}
@Override
public void onPrepared(String url, Object... objects) {
}
@Override
public void onClickStartIcon(String url, Object... objects) {
}
@Override
public void onClickStartError(String url, Object... objects) {
}
@Override
public void onClickStop(String url, Object... objects) {
}
@Override
public void onClickStopFullscreen(String url, Object... objects) {
}
@Override
public void onClickResume(String url, Object... objects) {
}
@Override
public void onClickResumeFullscreen(String url, Object... objects) {
}
@Override
public void onClickSeekbar(String url, Object... objects) {
}
@Override
public void onClickSeekbarFullscreen(String url, Object... objects) {
}
@Override
public void onAutoComplete(String url, Object... objects) {
}
@Override
public void onEnterFullscreen(String url, Object... objects) {
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
}
@Override
public void onQuitFullscreen(String url, Object... objects) {
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
}
@Override
public void onQuitSmallWidget(String url, Object... objects) {
}
@Override
public void onEnterSmallWidget(String url, Object... objects) {
}
@Override
public void onTouchScreenSeekVolume(String url, Object... objects) {
}
@Override
public void onTouchScreenSeekPosition(String url, Object... objects) {
}
@Override
public void onTouchScreenSeekLight(String url, Object... objects) {
}
@Override
public void onPlayError(String url, Object... objects) {
}
@Override
public void onClickStartThumb(String url, Object... objects) {
}
@Override
public void onClickBlank(String url, Object... objects) {
}
@Override
public void onClickBlankFullscreen(String url, Object... objects) {
}
});
//进度回调
player.setGSYVideoProgressListener(new GSYVideoProgressListener() {
@Override
public void onProgress(int progress, int secProgress, int currentPosition, int duration) {
}
});
}
@Override
protected void onResume() {
super.onResume();
player.onVideoResume();
}
@Override
protected void onPause() {
super.onPause();
player.onVideoPause();
}
@Override
public void onBackPressed() {
//物理返回按钮监听,如果当前处于全屏状态,先退出全屏
if (GSYVideoManager.backFromWindowFull(this)) {
return;
}
super.onBackPressed();
}
@Override
protected void onDestroy() {
super.onDestroy();
GSYVideoManager.releaseAllVideos();
}
}
布局文件:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:fitsSystemWindows="true">
<com.thtj.video.activity.MyStandardGSYVideoPlayer
android:id="@+id/player"
android:layout_width="match_parent"
android:layout_height="200dp"/>
</LinearLayout>
自定义部分:
/**
* 自定义StandardGSYVideoPlayer
*/
public class MyStandardGSYVideoPlayer extends StandardGSYVideoPlayer {
ImageView mCoverImage;
String mCoverOriginUrl;
int mDefaultRes;
public MyStandardGSYVideoPlayer(Context context, Boolean fullFlag) {
super(context, fullFlag);
}
public MyStandardGSYVideoPlayer(Context context) {
super(context);
}
public MyStandardGSYVideoPlayer(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void init(Context context) {
super.init(context);
mCoverImage = (ImageView) findViewById(R.id.thumbImage);
if (mThumbImageViewLayout != null && (mCurrentState == -1 || mCurrentState == CURRENT_STATE_NORMAL || mCurrentState == CURRENT_STATE_ERROR)) {
mThumbImageViewLayout.setVisibility(VISIBLE);
}
}
@Override
public int getLayoutId() {
return R.layout.video_layout_cover;
}
/**
* 通过Glide获取视频第一帧图片作为视频封面
*/
public void loadCoverImage(String url, int res) {
mCoverOriginUrl = url;
mDefaultRes = res;
Glide.with(getContext().getApplicationContext())
.setDefaultRequestOptions(
new RequestOptions()
.frame(1000)
.centerCrop()
.error(res)
.placeholder(res))
.load(url)
.into(mCoverImage);
}
@Override
public GSYBaseVideoPlayer startWindowFullscreen(Context context, boolean actionBar, boolean statusBar) {
GSYBaseVideoPlayer gsyBaseVideoPlayer = super.startWindowFullscreen(context, actionBar, statusBar);
MyStandardGSYVideoPlayer sampleCoverVideo = (MyStandardGSYVideoPlayer) gsyBaseVideoPlayer;
sampleCoverVideo.loadCoverImage(mCoverOriginUrl, mDefaultRes);
return gsyBaseVideoPlayer;
}
/**
* 重写此方法置空,取消双击屏幕暂停或者播放视频功能
*/
@Override
protected void touchDoubleUp() {
}
/**
* 重写此方法,修改自己的小锁开关图标
*/
protected void lockTouchLogic() {
if (mLockCurScreen) {
mLockScreen.setImageResource(R.drawable.open_suo);
mLockCurScreen = false;
} else {
mLockScreen.setImageResource(R.drawable.close_suo);
mLockCurScreen = true;
hideAllWidget();
}
}
/**
* 重写此方法,更改全屏图标
*/
@Override
public int getEnlargeImageRes() {
return R.drawable.quanping;
}
/**
* 重写此方法,更改缩屏图标
*/
@Override
public int getShrinkImageRes() {
return R.drawable.suoxiao;
}
/**
* 重写此方法,更改播放、暂停、错误的图标
*/
@Override
protected void updateStartImage() {
ImageView imageView = (ImageView) mStartButton;
if (mCurrentState == CURRENT_STATE_PLAYING) {
imageView.setImageResource(R.drawable.icon_pause);
} else if (mCurrentState == CURRENT_STATE_ERROR) {
imageView.setImageResource(R.drawable.icon_error);
} else {
imageView.setImageResource(R.drawable.icon_start);
}
}
}
自定义的布局:
<?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"
android:background="@android:color/black">
<RelativeLayout
android:id="@+id/surface_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center">
</RelativeLayout>
<RelativeLayout
android:id="@+id/thumb"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentBottom="true"
android:layout_alignParentEnd="true"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:background="#000000"
android:scaleType="fitCenter">
<ImageView
android:id="@+id/thumbImage"
android:scaleType="centerCrop"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
<LinearLayout
android:id="@+id/layout_bottom"
android:layout_width="match_parent"
android:layout_height="40dp"
android:layout_alignParentBottom="true"
android:background="#99000000"
android:gravity="center_vertical"
android:orientation="horizontal"
android:visibility="invisible">
<TextView
android:id="@+id/current"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="16dp"
android:text="00:00"
android:textSize="12sp"
android:textColor="#ffffff" />
<SeekBar
android:id="@+id/progress"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_weight="1.0"
android:background="@null"
android:max="100"
android:maxHeight="4dp"
android:minHeight="4dp"
android:paddingBottom="8dp"
android:paddingTop="8dp"
android:progressDrawable="@drawable/video_seek_progress"
android:thumb="@drawable/video_seek_thumb" />
<TextView
android:id="@+id/total"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="16dp"
android:text="00:00"
android:textSize="12sp"
android:textColor="#ffffff" />
<ImageView
android:id="@+id/fullscreen"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:paddingRight="16dp"
android:scaleType="center"
android:src="@drawable/video_enlarge" />
</LinearLayout>
<ProgressBar
android:id="@+id/bottom_progressbar"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_alignParentBottom="true"
android:max="100"
android:progressDrawable="@drawable/video_progress" />
<ImageView
android:id="@+id/back_tiny"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_marginLeft="6dp"
android:layout_marginTop="6dp"
android:visibility="gone" />
<LinearLayout
android:id="@+id/layout_top"
android:layout_width="match_parent"
android:layout_height="48dp"
android:background="@drawable/video_title_bg"
android:gravity="center_vertical">
<ImageView
android:id="@+id/back"
android:layout_width="48dp"
android:layout_height="48dp"
android:paddingLeft="10dp"
android:scaleType="centerInside"
android:src="@drawable/video_back" />
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="10dp"
android:textColor="@android:color/white"
android:textSize="16sp" />
</LinearLayout>
<ImageView
android:id="@+id/loading"
android:layout_width="28dp"
android:layout_height="28dp"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:visibility="invisible" />
<ImageView
android:id="@+id/start"
android:layout_width="40dp"
android:layout_height="50dp"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:layout_gravity="center_vertical" />
<ImageView
android:id="@+id/small_close"
android:layout_width="30dp"
android:layout_height="30dp"
android:paddingLeft="10dp"
android:paddingTop="10dp"
android:scaleType="centerInside"
android:src="@drawable/video_small_close"
android:visibility="gone" />
<ImageView
android:id="@+id/lock_screen"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginRight="50dp"
android:scaleType="centerInside"
android:src="@drawable/open_suo"
android:visibility="gone" />
</RelativeLayout>
如果需要修改小锁开关图标的,上边布局最后这个ImageView小锁图片换成自己的开锁图标即可。
Activity设置属性:
android:configChanges="orientation|keyboardHidden|screenSize"
android:screenOrientation="portrait"
最后就是权限,千万别忘了:
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
代码中的解释比较详细了,不说了。bye~