版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_29078329/article/details/77720531
最近项目中视频播放需要实现全屏,小窗、全屏切换功能,下面整理一下Vitamio全屏播放实现的过程,如下图,以CCTV1播放为例说明。
全屏播放依靠动态改变布局宽高实现,小窗播放时布局:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:id="@+id/top_part_live_activity"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:background="@color/darker_gray"
android:orientation="vertical"></LinearLayout>
<FrameLayout
android:id="@+id/fl_video_view_live_activity"
android:layout_width="match_parent"
android:layout_height="203dp"
android:layout_gravity="center">
<io.vov.vitamio.widget.VideoView
android:id="@+id/video_view_live_activity"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true" />
<ImageView
android:id="@+id/exit_btn_video_live_activity"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_marginLeft="10dp"
android:layout_marginTop="10dp"
android:background="@drawable/live_activity_exit"
android:visibility="gone" />
<ImageView
android:id="@+id/loading_btn_live_activity"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:background="@drawable/loading_spinner" />
<ImageView
android:id="@+id/full_screen_live_activity"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right|bottom"
android:layout_marginBottom="10dp"
android:layout_marginRight="10dp"
android:background="@drawable/live_full_screen"
android:visibility="gone" />
<ImageView
android:id="@+id/switch_video_live_activity"
android:layout_width="35dp"
android:layout_height="35dp"
android:layout_gravity="center" />
</FrameLayout>
<LinearLayout
android:id="@+id/bottom_part_live_activity"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:background="@color/darker_gray"
android:orientation="vertical">
</LinearLayout>
</LinearLayout>
VideoView在FrameLayout布局中,并填充父布局,FrameLayout宽高即为VideoView宽高。点击全屏按钮时,需要将top_part_live_activity、bottom_part_live_activity隐藏,并
设置FrameLayout的宽为设备的高度、FrameLayout的高为设备的宽度,然后通知Activity改为横向布局,此时VideoView就是全屏播放。
private void setFullScreen() {
LinearLayout.LayoutParams fullScreenLLP = new LinearLayout.LayoutParams(
DeviceUtil.getHeightPixel(this), DeviceUtil.getWidthPixel(this) - DeviceUtil.getStatusBarHeight(this));
mTopPart.setVisibility(View.GONE);
mBottomPart.setVisibility(View.GONE);
mFlVideoView.setLayoutParams(fullScreenLLP);//mFlVideoView的宽是屏幕高度,高是屏幕宽度-状态栏高度
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);//Activity横屏
mVideoView.setVideoLayout(VideoView.VIDEO_LAYOUT_SCALE, 0);
isFullScreen = true;
}
当切回小窗播放时,将top_part_live_activity、bottom_part_live_activity显示出来,恢复FrameLayout的宽高,并通知Activity改为纵向布局,即可小窗播放。
public void setVideoPreview() {
LinearLayout.LayoutParams previewLLP = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, DeviceUtil.dip2px(203, this));
mTopPart.setVisibility(View.VISIBLE);
mBottomPart.setVisibility(View.VISIBLE);
mFlVideoView.setLayoutParams(previewLLP);//mFlVideoView的宽是屏幕的宽度,高是203dp
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);//Activity竖屏
mVideoView.setVideoLayout(VideoView.VIDEO_LAYOUT_SCALE, 0);
isFullScreen = false;
}
LiveActivity需要动态改变布局方向,因此AndroidManifest.xml中要设置成:
android:configChanges="orientation|screenSize|smallestScreenSize|keyboard|keyboardHidden|navigation"
才能动态改变LiveActivity的布局方向。LiveActivity代码如下,其中还包括暂停、播放、缓冲、退出逻辑。
public class LiveActivity extends AppCompatActivity implements View.OnClickListener {
private static final String TAG = "LiveActivity";
private VideoView mVideoView;
private ImageView mSwitchBtn;
private ImageView mExitBtn;
private ImageView mFullScreenBtn;
private FrameLayout mFlVideoView;
private ImageView mLoadingView;
private LinearLayout mTopPart;
private LinearLayout mBottomPart;
private AnimationDrawable mLoadingAnim;
private boolean isFullScreen;
private boolean isScreenClear = true;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (!Vitamio.isInitialized(getApplicationContext())) {
return;
}
setContentView(R.layout.activity_live);
String liveUrl = getIntent().getStringExtra("live_url");
mFlVideoView = (FrameLayout) findViewById(R.id.fl_video_view_live_activity);
mSwitchBtn = (ImageView) findViewById(R.id.switch_video_live_activity);
mExitBtn = (ImageView) findViewById(R.id.exit_btn_video_live_activity);
mSwitchBtn.setOnClickListener(this);
mExitBtn.setOnClickListener(this);
mFullScreenBtn = (ImageView) findViewById(R.id.full_screen_live_activity);
mFullScreenBtn.setOnClickListener(this);
mTopPart = (LinearLayout) findViewById(R.id.top_part_live_activity);
mBottomPart = (LinearLayout) findViewById(R.id.bottom_part_live_activity);
mLoadingView = (ImageView) findViewById(R.id.loading_btn_live_activity);
mLoadingAnim = (AnimationDrawable) mLoadingView.getBackground();
mLoadingView.setVisibility(View.VISIBLE);
mLoadingAnim.start();
mVideoView = (VideoView) findViewById(R.id.video_view_live_activity);
mVideoView.setVideoPath(liveUrl);
mVideoView.requestFocus();
mVideoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
mp.setPlaybackSpeed(1.0f);
}
});
mVideoView.setOnInfoListener(new MediaPlayer.OnInfoListener() {
@Override
public boolean onInfo(MediaPlayer mp, int what, int extra) {
switch (what) {
case MediaPlayer.MEDIA_INFO_BUFFERING_START:
if (!mLoadingAnim.isRunning()) {
//缓冲时,如果mSwitchBtn可见,要使其隐藏;mSwitchBtn和mLoadingView不允许同时显示
if (mSwitchBtn.getVisibility() == View.VISIBLE) {
mSwitchBtn.setVisibility(View.GONE);
}
mLoadingView.setVisibility(View.VISIBLE);
mLoadingAnim.start();
}
mp.pause();
break;
case MediaPlayer.MEDIA_INFO_BUFFERING_END:
mLoadingView.setVisibility(View.GONE);
mLoadingAnim.stop();
mp.start();
break;
case MediaPlayer.MEDIA_INFO_DOWNLOAD_RATE_CHANGED:
Log.i(TAG, "当前网速:" + extra + "kb/s");
break;
}
return true;
}
});
mVideoView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (event.ACTION_DOWN == event.getAction()) {
if (isScreenClear) {
isScreenClear = false;
mExitBtn.setVisibility(View.VISIBLE);
mFullScreenBtn.setVisibility(View.VISIBLE);
//缓冲时隐藏mSwitchBtn,缓冲完成后才能显示mSwitchBtn;缓冲对话框与mSwitchBtn不能同时显示
if (!mLoadingAnim.isRunning()) {
mSwitchBtn.setVisibility(View.VISIBLE);
if (mVideoView.isPlaying()) {
mSwitchBtn.setImageResource(R.drawable.layer_list_live_activity_switch_pause);
}
if (mVideoView.hasFocus() && !mVideoView.isPlaying()) {
//暂停状态
mSwitchBtn.setImageResource(R.drawable.layer_list_live_activity_switch_play);
}
} else {
mSwitchBtn.setVisibility(View.GONE);
}
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
if (!isScreenClear) {
isScreenClear = true;
mFullScreenBtn.setVisibility(View.GONE);
mExitBtn.setVisibility(View.GONE);
mSwitchBtn.setVisibility(View.GONE);
}
}
}, 3000);
} else {
isScreenClear = true;
mFullScreenBtn.setVisibility(View.GONE);
mExitBtn.setVisibility(View.GONE);
mSwitchBtn.setVisibility(View.GONE);
}
}
return true;
}
});
}
@Override
protected void onDestroy() {
super.onDestroy();
if (mVideoView != null && mVideoView.isPlaying()) {
mVideoView.stopPlayback();//停止播放,并释放资源
}
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.switch_video_live_activity:
if (mVideoView.isPlaying()) {
mVideoView.pause();
mSwitchBtn.setImageResource(R.drawable.layer_list_live_activity_switch_play);
} else {
mVideoView.start();
mSwitchBtn.setImageResource(R.drawable.layer_list_live_activity_switch_pause);
}
break;
case R.id.exit_btn_video_live_activity:
if (mLoadingAnim != null && mLoadingAnim.isRunning()) {
mLoadingAnim.stop();
}
if (isFullScreen) {
setVideoPreview();
} else {
finish();
}
break;
case R.id.full_screen_live_activity:
if (!isFullScreen) {
setFullScreen();
} else {
setVideoPreview();
}
break;
}
}
private void setFullScreen() {
LinearLayout.LayoutParams fullScreenLLP = new LinearLayout.LayoutParams(
DeviceUtil.getHeightPixel(this), DeviceUtil.getWidthPixel(this) - DeviceUtil.getStatusBarHeight(this));
mTopPart.setVisibility(View.GONE);
mBottomPart.setVisibility(View.GONE);
mFlVideoView.setLayoutParams(fullScreenLLP);//mFlVideoView的宽是屏幕高度,高是屏幕宽度-状态栏高度
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);//Activity横屏
mVideoView.setVideoLayout(VideoView.VIDEO_LAYOUT_SCALE, 0);
isFullScreen = true;
}
public void setVideoPreview() {
LinearLayout.LayoutParams previewLLP = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, DeviceUtil.dip2px(203, this));
mTopPart.setVisibility(View.VISIBLE);
mBottomPart.setVisibility(View.VISIBLE);
mFlVideoView.setLayoutParams(previewLLP);//mFlVideoView的宽是屏幕的宽度,高是203dp
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);//Activity竖屏
mVideoView.setVideoLayout(VideoView.VIDEO_LAYOUT_SCALE, 0);
isFullScreen = false;
}
}