Android中Vitamio全屏播放

来源:互联网 发布:java基础代码 编辑:程序博客网 时间:2024/05/16 19:50

最近项目中视频播放需要实现全屏,小窗、全屏切换功能,下面整理一下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;    }}


项目源码地址:https://github.com/xiyy/TopNews ,希望大家多多关注,谢谢!