Android中Vitamio全屏播放

版权声明:本文为博主原创文章,未经博主允许不得转载。 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;
    }
}


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



猜你喜欢

转载自blog.csdn.net/qq_29078329/article/details/77720531