一个可以代替VideoView简单好用的Android视频播放器

如果项目中需要用到视频播放功能,android原生的视频播放器坑实在太多了。所以介绍一个好用的第三方播放器,可自定义多种效果(如播放回调、缓冲动画等)。简单靠谱,不多废话,直接看代码。

1、首先添加依赖

implementation 'com.linsea:universalvideoview:1.1.0@aar'

2、然后就是layout布局文件,我这里首先是定义了一个半屏的效果

<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@android:color/black"
    android:orientation="vertical">

    <ImageView
        android:id="@+id/iv_back"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="10dp"
        android:layout_marginTop="10dp"
        android:padding="5dp"
        android:src="@mipmap/icon_back"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"/>

    <FrameLayout
        android:id="@+id/video_layout"
        android:layout_width="fill_parent"
        android:layout_height="200dp"
        android:background="@android:color/black"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <com.universalvideoview.UniversalVideoView
            android:id="@+id/videoView"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:layout_gravity="center"
            app:uvv_autoRotation="true"
            app:uvv_fitXY="false"/>

        <com.universalvideoview.UniversalMediaController
            android:id="@+id/media_controller"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            app:uvv_scalable="true"/>
    </FrameLayout>

3、接下来就是Activity中的应用了

public class VideoPlayActivity extends BaseActivity implements UniversalVideoView.VideoViewCallback {

    private static final String KEY_VIDEO_URL = "video_url";
    private static final String KEY_VIDEO_TITLE = "video_title";
     private static final String SEEK_POSITION_KEY = "SEEK_POSITION_KEY";
    //播放器
    UniversalVideoView mVideoView;
    //进度条等
    UniversalMediaController mMediaController;
    //返回按钮
    private ImageView ivBack;

    View mVideoLayout;
    
    private int mSeekPosition;//进度
    private int cachedHeight;
    private boolean isFullscreen;

    private String TAG = "VideoPlayActivity";
    private String url = "";//视频url
    private String title = "";//视频title

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_video_play);

        url = getIntent().getStringExtra(KEY_VIDEO_URL);
        title = getIntent().getStringExtra(KEY_VIDEO_TITLE);

        mVideoLayout = findViewById(R.id.video_layout);
        mVideoView = findViewById(R.id.videoView);
        mMediaController = findViewById(R.id.media_controller);
        ivBack = findViewById(R.id.iv_back);

        mVideoView.setMediaController(mMediaController);
        setVideoAreaSize();
        mVideoView.setVideoURI(Uri.parse(url));
        mVideoView.setVideoViewCallback(this);
        mVideoView.start();
        mMediaController.setTitle(title);
		//返回按钮,结束Activity
        ivBack.setOnClickListener(v -> VideoPlayActivity.this.finish());
  		
  		mVideoView.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
            @Override
            public void onCompletion(MediaPlayer mp) {
                Log.d(TAG, "onCompletion ");
            }
        });
    }

    /**
     * 置视频区域大小
     */
    private void setVideoAreaSize() {
        mVideoLayout.post(() -> {
            int width = mVideoLayout.getWidth();
            cachedHeight = (int) (width * 405f / 720f);
            ViewGroup.LayoutParams videoLayoutParams = mVideoLayout.getLayoutParams();
            videoLayoutParams.width = ViewGroup.LayoutParams.MATCH_PARENT;
            videoLayoutParams.height = cachedHeight;
            mVideoLayout.setLayoutParams(videoLayoutParams);
            mVideoView.setVideoPath(url);
            mVideoView.requestFocus();
        });
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        Log.d(TAG, "onSaveInstanceState Position=" + mVideoView.getCurrentPosition());
        outState.putInt(SEEK_POSITION_KEY, mSeekPosition);
    }

    @Override
    protected void onRestoreInstanceState(Bundle outState) {
        super.onRestoreInstanceState(outState);
        mSeekPosition = outState.getInt(SEEK_POSITION_KEY);
        Log.d(TAG, "onRestoreInstanceState Position=" + mSeekPosition);
    }

    @Override
    public void onScaleChange(boolean isFullscreen) {
        this.isFullscreen = isFullscreen;
        if (isFullscreen) {
        //横屏
            ViewGroup.LayoutParams layoutParams = mVideoLayout.getLayoutParams();
            layoutParams.width = ViewGroup.LayoutParams.MATCH_PARENT;
            layoutParams.height = ViewGroup.LayoutParams.MATCH_PARENT;
            mVideoLayout.setLayoutParams(layoutParams);
            ivBack.setVisibility(View.GONE);

        } else {
        //竖屏
            ViewGroup.LayoutParams layoutParams = mVideoLayout.getLayoutParams();
            layoutParams.width = ViewGroup.LayoutParams.MATCH_PARENT;
            layoutParams.height = this.cachedHeight;
            mVideoLayout.setLayoutParams(layoutParams);
            ivBack.setVisibility(View.VISIBLE);
        }
        switchTitleBar(!isFullscreen);
    }

    @Override
    public void onPause(MediaPlayer mediaPlayer) {
    }

    private void switchTitleBar(boolean show) {
        ActionBar supportActionBar = getSupportActionBar();
        if (supportActionBar != null) {
            if (show) {
                supportActionBar.show();
            } else {
                supportActionBar.hide();
            }
        }
    }

    @Override
    protected void onPause() {
        super.onPause();
        Log.d(TAG, "onPause ");
        if (mVideoView != null && mVideoView.isPlaying()) {
            mSeekPosition = mVideoView.getCurrentPosition();
            Log.d(TAG, "onPause mSeekPosition=" + mSeekPosition);
            mVideoView.pause();
        }
    }

    public static Intent newIntent(Context context, String url, String title) {
        Intent intent = new Intent(context, VideoPlayActivity.class);
        intent.putExtra(KEY_VIDEO_URL, url);
        intent.putExtra(KEY_VIDEO_TITLE, title);
        return intent;
    }

    @Override
    public void onStart(MediaPlayer mediaPlayer) {
        Log.d(TAG, "onStart UniversalVideoView callback");
    }

    @Override
    public void onBufferingStart(MediaPlayer mediaPlayer) {
        Log.d(TAG, "onBufferingStart UniversalVideoView callback");
    }

    @Override
    public void onBufferingEnd(MediaPlayer mediaPlayer) {
        Log.d(TAG, "onBufferingEnd UniversalVideoView callback");
    }

    @Override
    public void onBackPressed() {
        if (this.isFullscreen) {
            mVideoView.setFullscreen(false);
        } else {
            super.onBackPressed();
        }
    }

    @Override
    public void onPointerCaptureChanged(boolean hasCapture) {
    }
}

另外,此View并不会保存播放状态,至于播放状态和时间的保存。需要自己做相应的操作。

还有,如果横竖屏切换(半屏/全屏),Activity生命周期会重新执行,如果不需要重新执行生命周期的话,可在 AndroidManifest 对应的Activity中添加如下属性即可:

android:configChanges="orientation|keyboardHidden|screenSize"

到此,基本的播放就可以实现了。至于相关的业务订制。可在Activity中的相关回调里完成。最后再来看几个UI相关的属性

属性说明
uvv_fitXYUniversalVideoView的属性,布尔值,true时设置视频缩放时在X,Y方向上铺满View设置的宽度和高度,这样可能使视频变形.false时则缩放时保持视频的长宽比例,与SDK中的VideoView类似.
uvv_autoRotationUniversalVideoView的属性,布尔值,true时视频会根据重力响应通知客户进行全屏与非全屏之间的切换.
uvv_scalableUniversalMediaController属性,布尔值,是否显示控制条右下方的缩放按钮,如果不想全屏播放时,可以设置为false不显示.

END

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值