项目实训—基于AI的智能视频剪辑器(五)视频播放的实现

本文详细介绍了如何在安卓端使用开源项目Dkplayer实现视频播放功能,包括自定义PrepareView、TitleView、VodControlView、GestureView和CompleteView等控制组件,以及如何使用StandardVideoController和VideoView进行视频播放和控制。通过这些组件,可以实现视频播放的初始化、进度控制、手势操作、全屏切换等功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


前言

在与后端初步联调,测试完毕视频的上传功能后,由于算法部分尚未完成,因此先暂缓了需要进行联调的部分功能。这段时间内,我将精力主要放在了视频播放功能的实现上。

安卓端有一些开源的视频播放器项目,由于当前尚未对视频播放功能有特殊的需求,这里直接使用了开源项目 dkplayer 的视频播放器组件,而自己编写控制视频播放的相关代码。


一、Dkplayer 自定义控制组件

首先引用开源项目

implementation 'com.github.dueeeke.dkplayer:dkplayer-java:3.2.6'

网上有关 Dkplayer 的使用说明的资料比较少,在初步阅读开源项目源码后,这里进行一下总结:
Dkplayer 真正的视频播放器类是 VideoView,同时 VideoViewManager 作为视频播放器管理类,可以管理并配置视频播放器。但是仅仅使用 VideoView,只能实现简单的视频播放,而不能进行一些调节进度条、调整亮度等更自由的操作。而 Dkplayer 提供了一个类 ControlWrapper,可以通过自定义控制组件,来调用封装好的视频播放控制类的 api ,根据需求完善视频播放功能。

这里我主要定义了5个控制组件:

控制组件类 作用
PrepareView 播放器的初始状态,准备播放界面
TitleView 视频播放器的顶部控制栏,主要包括标题、时间、电量以及返回操作
VodControlView 视频播放器的底部控制栏,包括进度条、播放时间、全屏控制
GestureView 视频播放器的手势控制,包括拖动快进快退、亮度、音量等控制
CompleteView 视频播放完毕后的界面

PrepareView

PrepareView 对应的页面显示了视频的封面图片,以及播放图标,点击图标后,便调用接口,播放视频
在这里插入图片描述

public class PrepareView extends FrameLayout implements IControlComponent {
   

    private ControlWrapper mControlWrapper;
    
    private ImageView mThumb;
    private ImageView mStartPlay;
    private ProgressBar mLoading;

    public PrepareView(@NonNull Context context) {
   
        super(context);
    }

    public PrepareView(@NonNull Context context, @Nullable AttributeSet attrs) {
   
        super(context, attrs);
    }

    public PrepareView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
   
        super(context, attrs, defStyleAttr);
    }
    
    {
   
        LayoutInflater.from(getContext()).inflate(R.layout.player_layout_prepare_view, this, true);
        mThumb = findViewById(R.id.thumb);
        mStartPlay = findViewById(R.id.start_play);
        mLoading = findViewById(R.id.loading);
        findViewById(R.id.status_btn).setOnClickListener(new OnClickListener() {
   
            @Override
            public void onClick(View v) {
   
                // 设置是否在移动网络下直接播放视频
                VideoViewManager.instance().setPlayOnMobileNetwork(true);
                mControlWrapper.start();
            }
        });
    }

    /**
     * 设置点击此界面开始播放
     */
    public void setClickStart() {
   
        setOnClickListener(new OnClickListener() {
   
            @Override
            public void onClick(View v) {
   
                mControlWrapper.start();
            }
        });
    }

    @Override
    public void attach(@NonNull ControlWrapper controlWrapper) {
   
        mControlWrapper = controlWrapper;
    }

    @Override
    public View getView() {
   
        return this;
    }

    @Override
    public void onVisibilityChanged(boolean isVisible, Animation anim) {
   

    }

    @Override
    public void onPlayStateChanged(int playState) {
   
        switch (playState) {
   
            case VideoView.STATE_PREPARING:
                bringToFront();
                setVisibility(VISIBLE);
                mStartPlay.setVisibility(View.GONE);
                mLoading.setVisibility(View.VISIBLE);
                break;
            case VideoView.STATE_PLAYING:
            case VideoView.STATE_PAUSED:
            case VideoView.STATE_ERROR:
            case VideoView.STATE_BUFFERING:
            case VideoView.STATE_BUFFERED:
            case VideoView.STATE_PLAYBACK_COMPLETED:
                setVisibility(GONE);
                break;
            case VideoView.STATE_IDLE:
                setVisibility(VISIBLE);
                bringToFront();
                mLoading.setVisibility(View.GONE);
                mStartPlay.setVisibility(View.VISIBLE);
                mThumb.setVisibility(View.VISIBLE);
                break;
            case VideoView.STATE_START_ABORT:
                setVisibility(VISIBLE);
                break;
        }
    }

    @Override
    public void onPlayerStateChanged(int playerState) {
   

    }

    @Override
    public void setProgress(int duration, int position) {
   

    }

    @Override
    public void onLockStateChanged(boolean isLocked) {
   

    }
}

TitleView

TitleView 实现的功能主要如下:

  • 在页面初始注册 BatteryReceiver,获取手机电量信息,显示在顶部栏中,在离开页面时取消注册
  • 获取系统时间、视频标题等信息,显示在顶部栏中
  • 点击返回箭头后,退出全屏
  • 点击锁定图标后,锁定屏幕,并隐藏顶部底部栏
    在这里插入图片描述
public class TitleView extends FrameLayout implements IControlComponent {
   

    private ControlWrapper mControlWrapper;

    private LinearLayout mTitleContainer;
    private TextView mTitle;
    private TextView mSysTime;//系统当前时间

    private BatteryReceiver mBatteryReceiver;
    private boolean mIsRegister;//是否注册BatteryReceiver

    public TitleView(@NonNull Context context) {
   
        super(context);
    }

    public TitleView(@NonNull Context context, @Nullable AttributeSet attrs) {
   
        super(context, attrs);
    }

    public TitleView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
   
        super(context, attrs, defStyleAttr);
    }

    {
   
        setVisibility(GONE);
        LayoutInflater.from(getContext()).inflate(R.layout.player_layout_title_view, this, true);
        mTitleContainer = findViewById(R.id.title_container);
        ImageView back = findViewById(R.id.back);
        // 点击返回后,退出全屏
        back.setOnClickListener(new OnClickListener() {
   
            @Override
            public void onClick(View v) {
   
                Activity activity = PlayerUtils.scanForActivity(getContext());
                if (activity != null && mControlWrapper.isFullScreen()) {
   
                    activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
                    mControlWrapper.stopFullScreen();
                }
            }
        });
        mTitle = findViewById(R.id.title);
        mSysTime = findViewById(R.id.sys_time);
        //电量
        ImageView batteryLevel = findViewById(R.id.iv_battery);
        mBatteryReceiver = new BatteryReceiver(batteryLevel);
    }

    public void setTitle(String title) {
   
        mTitle.setText(title);
    }

    @Override
    protected void onDetachedFromWindow() {
   
        super.onDetachedFromWindow();
        // View 与 Window 分离的时候要取消注册 BatteryReceiver
        if (mIsRegister) {
   
            getContext().unregisterReceiver(mBatteryReceiver);
            mIsRegister = false;
        }
    }

    @Override
    protected void onAttachedToWindow() {
   
        super.onAttachedToWindow();
        if (!mIsRegister) {
   
            getContext().registerReceiver(mBatteryReceiver, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
            mIsRegister = true;
        }
    }

    @Override
    public void attach(@NonNull ControlWrapper controlWrapper) {
   
        mControlWrapper = controlWrapper;
    }

    @Override
    public View getView() {
   
        return this;
    }

    @Override
    public void onVisibilityChanged(boolean isVisible, Animation anim) {
   
        //只在全屏时才有效
        if (!mControlWrapper.isFullScreen()) return;
        if (isVisible) {
   
            if (getVisibility() == GONE) {
   
                mSysTime.setText(PlayerUtils.getCurrentSystemTime());
                setVisibility(VISIBLE);
                if (anim != null) {
   
                    startAnimation(anim);
                }
            }
        } else {
   
            if (getVisibility() == VISIBLE) {
   
                setVisibility(GONE);
                if (anim != null) {
   
                    startAnimation(anim);
                }
            }
        }
    }

    @Override
    public void onPlayStateChanged(int playState) {
   
        switch (playState) {
   
            case VideoView.STATE_IDLE:
            case VideoView.STATE_START_ABORT:
            case VideoView.STATE_PREPARING:
            case VideoView.STATE_PREPARED:
            case VideoView.STATE_ERROR:
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值