请先了解上一章节
上一章节:GSYVideoPlayer视频播放
在播放的时候发现,直播视频时GSY是有画面的
但在直播音频的时候GSY会黑屏,这样用户体验感就不会很好
怎么办?我一开始想到了三个办法
1.放一第一帧图片
2.放置一张背景图
3.修改GSYVideo Player本身的背景
经过测试我发现,方法1在播放时就不可行在加载时可展示,方法2展示了一张封面无法显示Video控制布局
那就只能读源码执行方法3了
public class LiveVideo extends StandardGSYVideoPlayer {
public LiveDataFullscreenButtonClick liveDataClick;//点击全屏按钮回调
private GSYSeekBar progress;
private RelativeLayout video_parent;
/**
* 恢复暂停状态
*/
public void onResume() {
onVideoResume();
}
/**
* 暂停状态
*/
public void onPause() {
onVideoPause();
}
public void setBackground1(){
// this.setBackground();
}
/**
* 接口回调
* @param liveDataClick
*/
public void setOnFullscreenButtonClick(LiveDataFullscreenButtonClick liveDataClick) {
this.liveDataClick = liveDataClick;
}
/* 重写方法自定义layout id与video_layout_standard.xml一致 不重新使用系统默认布局*/
@Override
public int getLayoutId() {
return R.layout.livevideo_layout;
}
public LiveVideo(Context context, Boolean fullFlag) {
super(context, fullFlag);
init();
}
public LiveVideo(Context context) {
super(context);
init();
}
public LiveVideo(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public void setmThumbImageView(@DrawableRes int id){
video_parent.setBackgroundResource(id);
}
/* 初始化操作 */
private void init() {
progress = findViewById(R.id.progress);
video_parent = findViewById(R.id.video_parent);
video_parent.setBackgroundResource(R.color.black);
//EXOPlayer内核,支持格式更多
// PlayerFactory.setPlayManager(Exo2PlayerManager.class);
//代理缓存模式,支持所有模式,不支持m3u8等,默认
// CacheFactory.setCacheManager(ProxyCacheManager.class);
//系统内核模式
// PlayerFactory.setPlayManager(SystemPlayerManager.class);
//ijk内核,默认模式
PlayerFactory.setPlayManager(IjkPlayerManager.class);
settingsVideo();
}
/* 一些播放器的设置 做一些UI的隐藏 可根据自己需求*/
public void settingsVideo() {
GSYVideoType.enableMediaCodec();//使能硬解码,播放前设置
Debuger.enable();//打开GSY的Log
//隐藏一些UI
setViewShowState(mBottomContainer, VISIBLE);
setViewShowState(mTopContainer, VISIBLE);
setViewShowState(mLockScreen, GONE);
setViewShowState(mLoadingProgressBar, GONE);
setViewShowState(mTopContainer, GONE);
setViewShowState(mThumbImageView, GONE);
setViewShowState(mBottomProgressBar, GONE);
//显示一些UI 进度 时间 当前时间 全屏 返回 加载Loading 暂停开始
setViewShowState(mStartButton, VISIBLE);
setViewShowState(mLoadingProgressBar, VISIBLE);
setViewShowState(mFullscreenButton, VISIBLE);
setViewShowState(mBackButton, GONE);
setViewShowState(mProgressBar, VISIBLE);
setViewShowState(mCurrentTimeTextView, VISIBLE);
setViewShowState(mTotalTimeTextView, VISIBLE);
setEnlargeImageRes(R.drawable.full);
setShrinkImageRes(R.drawable.full);
}
public void setTotalTime(String totalTime){
mTotalTimeTextView.setText(totalTime+"");
}
//拦截事件
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
mFullscreenButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
liveDataClick.onClick();
}
});
return super.dispatchTouchEvent(ev);
}
/* 取消 双击暂停 */
@Override
protected void touchDoubleUp() {
// super.touchDoubleUp();
}
public void setProgressTouch(boolean isTouch) {
progress.setTouch(isTouch);
}
public interface LiveDataFullscreenButtonClick {
void onClick();
}
}
这是我自定义的播放器继承了StandardGSYVideoPlayer 所以需要看StandardGSYVideoPlayer的源码
在StandardGSYVideoPlayer类中有一个方法changeUiToPlayingShow() 就是在播放器播放时也就是
已经prepare过后会调用这个方法 也就是说播放时的ui都是在这里设置的
@Override
protected void changeUiToPlayingShow() {
Debuger.printfLog("changeUiToPlayingShow");
setViewShowState(mTopContainer, VISIBLE);
setViewShowState(mBottomContainer, VISIBLE);
setViewShowState(mStartButton, VISIBLE);
setViewShowState(mLoadingProgressBar, INVISIBLE);
//可以看到隐藏了这个Layout,这个就是封面的Layout 所以修改这个就可以了
/*
在自定义的播放器中重写这个方法 然后对这个进行设置
*/
setViewShowState(mThumbImageViewLayout, INVISIBLE);
setViewShowState(mBottomProgressBar, INVISIBLE);
setViewShowState(mLockScreen, (mIfCurrentIsFullscreen && mNeedLockFull) ? VISIBLE : GONE);
if (mLoadingProgressBar instanceof ENDownloadView) {
((ENDownloadView) mLoadingProgressBar).reset();
}
updateStartImage();
}
测试一下发现图片时有展示的,但是有个BUG我们的封面展示后,无法点击展示我们的全屏按钮播放按钮布局了
这时我们需要对封面这个Layout进行动态的Ontouch监听
mThumbImageView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
/*
* 当触碰时 就根据需求显示对应的View
* 比如全屏按钮 进度条 开始暂停按钮等
* */
}
});
还有一些其他状态的方法 根据需求进行自定义修改
@Override
protected void changeUiToNormal() {
Debuger.printfLog("changeUiToNormal");
setViewShowState(mTopContainer, VISIBLE);
setViewShowState(mBottomContainer, INVISIBLE);
setViewShowState(mStartButton, VISIBLE);
setViewShowState(mLoadingProgressBar, INVISIBLE);
setViewShowState(mThumbImageViewLayout, VISIBLE);
setViewShowState(mBottomProgressBar, INVISIBLE);
setViewShowState(mLockScreen, (mIfCurrentIsFullscreen && mNeedLockFull) ? VISIBLE : GONE);
updateStartImage();
if (mLoadingProgressBar instanceof ENDownloadView) {
((ENDownloadView) mLoadingProgressBar).reset();
}
}
@Override
protected void changeUiToPreparingShow() {
Debuger.printfLog("changeUiToPreparingShow");
setViewShowState(mTopContainer, VISIBLE);
setViewShowState(mBottomContainer, VISIBLE);
setViewShowState(mStartButton, INVISIBLE);
setViewShowState(mLoadingProgressBar, VISIBLE);
setViewShowState(mThumbImageViewLayout, INVISIBLE);
setViewShowState(mBottomProgressBar, INVISIBLE);
setViewShowState(mLockScreen, GONE);
if (mLoadingProgressBar instanceof ENDownloadView) {
ENDownloadView enDownloadView = (ENDownloadView) mLoadingProgressBar;
if (enDownloadView.getCurrentState() == ENDownloadView.STATE_PRE) {
((ENDownloadView) mLoadingProgressBar).start();
}
}
}
@Override
protected void changeUiToPlayingShow() {
Debuger.printfLog("changeUiToPlayingShow");
setViewShowState(mTopContainer, VISIBLE);
setViewShowState(mBottomContainer, VISIBLE);
setViewShowState(mStartButton, VISIBLE);
setViewShowState(mLoadingProgressBar, INVISIBLE);
setViewShowState(mThumbImageViewLayout, INVISIBLE);
setViewShowState(mBottomProgressBar, INVISIBLE);
setViewShowState(mLockScreen, (mIfCurrentIsFullscreen && mNeedLockFull) ? VISIBLE : GONE);
if (mLoadingProgressBar instanceof ENDownloadView) {
((ENDownloadView) mLoadingProgressBar).reset();
}
updateStartImage();
}
@Override
protected void changeUiToPauseShow() {
Debuger.printfLog("changeUiToPauseShow");
setViewShowState(mTopContainer, VISIBLE);
setViewShowState(mBottomContainer, VISIBLE);
setViewShowState(mStartButton, VISIBLE);
setViewShowState(mLoadingProgressBar, INVISIBLE);
setViewShowState(mThumbImageViewLayout, INVISIBLE);
setViewShowState(mBottomProgressBar, INVISIBLE);
setViewShowState(mLockScreen, (mIfCurrentIsFullscreen && mNeedLockFull) ? VISIBLE : GONE);
if (mLoadingProgressBar instanceof ENDownloadView) {
((ENDownloadView) mLoadingProgressBar).reset();
}
updateStartImage();
updatePauseCover();
}
@Override
protected void changeUiToPlayingBufferingShow() {
Debuger.printfLog("changeUiToPlayingBufferingShow");
setViewShowState(mTopContainer, VISIBLE);
setViewShowState(mBottomContainer, VISIBLE);
setViewShowState(mStartButton, INVISIBLE);
setViewShowState(mLoadingProgressBar, VISIBLE);
setViewShowState(mThumbImageViewLayout, INVISIBLE);
setViewShowState(mBottomProgressBar, INVISIBLE);
setViewShowState(mLockScreen, GONE);
if (mLoadingProgressBar instanceof ENDownloadView) {
ENDownloadView enDownloadView = (ENDownloadView) mLoadingProgressBar;
if (enDownloadView.getCurrentState() == ENDownloadView.STATE_PRE) {
((ENDownloadView) mLoadingProgressBar).start();
}
}
}
@Override
protected void changeUiToCompleteShow() {
Debuger.printfLog("changeUiToCompleteShow");
setViewShowState(mTopContainer, VISIBLE);
setViewShowState(mBottomContainer, VISIBLE);
setViewShowState(mStartButton, VISIBLE);
setViewShowState(mLoadingProgressBar, INVISIBLE);
setViewShowState(mThumbImageViewLayout, VISIBLE);
setViewShowState(mBottomProgressBar, INVISIBLE);
setViewShowState(mLockScreen, (mIfCurrentIsFullscreen && mNeedLockFull) ? VISIBLE : GONE);
if (mLoadingProgressBar instanceof ENDownloadView) {
((ENDownloadView) mLoadingProgressBar).reset();
}
updateStartImage();
}
@Override
protected void changeUiToError() {
Debuger.printfLog("changeUiToError");
setViewShowState(mTopContainer, INVISIBLE);
setViewShowState(mBottomContainer, INVISIBLE);
setViewShowState(mStartButton, VISIBLE);
setViewShowState(mLoadingProgressBar, INVISIBLE);
setViewShowState(mThumbImageViewLayout, INVISIBLE);
setViewShowState(mBottomProgressBar, INVISIBLE);
setViewShowState(mLockScreen, (mIfCurrentIsFullscreen && mNeedLockFull) ? VISIBLE : GONE);
if (mLoadingProgressBar instanceof ENDownloadView) {
((ENDownloadView) mLoadingProgressBar).reset();
}
updateStartImage();
}
我们在布局中有创建一些id和原GSYVideo一致的Layout
在源码中看到对最外层的RelativeLayout没有操作
也就是说我们可以动态修改最外层的background进行展示同时不会影响播放的操作
这是一种比较稳妥的方法不会修改源码
<?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:id="@+id/video_parent"
android:background="@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" />
<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:textColor="@color/white"
style="@style/news_des_style"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="16dp"
android:text="00:00"
/>
<com.blue.bCheng.views.GSYSeekBar
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:padding="10dp"
android:max="100"
android:maxHeight="4dp"
android:minHeight="4dp"
android:paddingBottom="8dp"
android:paddingTop="8dp"
android:progressDrawable="@drawable/video_progress_bg"
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:textColor="@color/white"
style="@style/news_des_style"/>
</LinearLayout>
<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" />
<View
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="match_parent"/>
<ImageView
android:id="@+id/fullscreen"
style="@style/left_icon_style"
android:src="@drawable/full" />
</LinearLayout>
<ProgressBar
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/loading"
android:layout_centerInParent="true"
/>
<ImageView
android:visibility="gone"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_centerInParent="true"
android:padding="5dp"
android:id="@+id/start"
/>
</RelativeLayout>