一步步自定义视频播放器——TextureView+MediaPlayer自定义视频播放器

本篇参考封装一个视频播放器,原文已经写的非常棒了,本篇加入了个人对其内容的理解。秉承不重复造轮子的良好理念,接下来开始拆解轮子。内容非常多,我都差点放弃写,有耐心的请往下看

github上非常棒的视频相关开源项目有:
最炫的哔哩哔哩的ijkplayer
JiaoziVideoPlayer 基于ijkplayer
GSYVideoPlayer 基于ijkplayer

结合前三篇内容,我们已经对MediaPlayer,SurfaceView,TextureView有了基本了解。相比SurfaceView,TextureView的类View特性,使其更加灵活。因此,我们选择TextureView结合MediaPlayer的方式来自定义视频播放器。只要你静下心来,跟着源码一步步敲,慢慢理解,你就会发现原来自定义视频播放器并不难。

核心思想

类似MVC模式
- NiceVideoPlayer:自定义播放界面,其主要是MediaPlayer和TextureView结合,负责视频数据解析和显示。
- NiceVideoController:控制界面,主要是控制暂停,播放,亮度,音量等
- INiceVideoPlayer:接口,定义了视频播放的相关方法,例如播放,暂停,获取当前播放状态等。

INiceVideoPlayer接口

定义接口前我们先思考下我们需要VideoPlayer实现什么功能,给VideoContronller提供哪些方法。

  1. 播放状态,根据前面的知识我们知道,MediaPlayer有多种状态,我们需要判断MediaPlayer的状态
 /******************************
     * 以下方判断播放器当前的播放状态
     ******************************/
    boolean isIdle();//是否空闲
    boolean isPreparing();
    boolean isPrepared();
    boolean isBufferingPlaying();
    boolean isBufferingPaused();
    boolean isPlaying();
    boolean isPaused();
    boolean isError();
    boolean isCompleted();
  1. 播放模式,基本的播放模式有正常模式,全屏模式,以及小窗口模式
/*************************
     * 播放器模式
     *************************/
    boolean isFullScreen();
    boolean isTinyWindow();
    boolean isNormal();

    /**
     * 进入全屏模式
     */
    void enterFullScreen();

    /**
     * 退出全屏模式
     * @return
     */
    boolean exitFullScreen();

    /**
     * 进入小窗口模式
     */
    void enterTinyWindow();

    /**
     * 退出小窗口模式
     * @return
     */
    boolean exitTinyWindow();
  1. 播放控制
 /**
     * 开始播放
     */
    void start();

    /**
     * 从指定位置开始播放
     *
     * @param position 播放位置
     */
    void start(long position);

    /**
     * 重新播放,播放器被暂停,播放错误,播放完成后需要调用这个方法重新播放
     */
    void restart();

    /**
     * 暂停播放
     */
    void pause();

    /**
     * 释放videoPlayer
     */
    void releasePlayer();

    /**
     * 释放
     */
    void  release();

完整代码

public interface INiceVideoPlayer {
   

    /**
     * 设置视频的url,以及headers
     *
     * @param url     视频地址,可以是本地,也可以是网络
     * @param headers 请求header
     */
    void setUp(String url, Map<String, String> headers);

    /***************
     * 播放控制
     ****************/

    /**
     * 开始播放
     */
    void start();

    /**
     * 从指定位置开始播放
     *
     * @param position 播放位置
     */
    void start(long position);

    /**
     * 重新播放,播放器被暂停,播放错误,播放完成后需要调用这个方法重新播放
     */
    void restart();

    /**
     * 暂停播放
     */
    void pause();

    /**
     * 释放videoPlayer
     */
    void releasePlayer();

    /**
     * 释放
     */
    void release();


    /**
     * seek到指定的位置继续播放
     *
     * @param pos
     */
    void seekTo(long pos);

    /**
     * 开始播放时,是否重上一次的位置继续播放
     *
     * @param continueFromLastPosition 上次播放位置
     */
    void continueFromLastPostion(boolean continueFromLastPosition);

    /**
     * 获取当前的播放位置
     */
    long getCurrentPostion();

    /**
     * 获取视频缓冲百分比
     */
    int getBufferPercentage();

    /**
     * 设置音量
     *
     * @param volume 音量值
     */
    void setVolume(int volume);

    /**
     * 获取最大音量
     *
     * @return
     */
    int getMaxVolume();

    /**
     * 获取当前的音量
     *
     * @return
     */
    int getVolume();

    /**
     * 获取总时长
     *
     * @return
     */
    long getDuration();


    /******************************
     * 播放器当前的播放状态
     ******************************/
    boolean isIdle();//是否空闲

    boolean isPreparing();

    boolean isPrepared();

    boolean isBufferingPlaying();

    boolean isBufferingPaused();

    boolean isPlaying();

    boolean isPaused();

    boolean isError();

    boolean isCompleted();


    /*************************
     * 播放器模式
     *************************/
    boolean isFullScreen();

    boolean isTinyWindow();

    boolean isNormal();

    /**
     * 进入全屏模式
     */
    void enterFullScreen();

    /**
     * 退出全屏模式
     *
     * @return
     */
    boolean exitFullScreen();

    /**
     * 进入小窗口模式
     */
    void enterTinyWindow();

    /**
     * 退出小窗口模式
     *
     * @return
     */
    boolean exitTinyWindow();
}

NiceVideoPlayer

定义播放状态,我们知道MediaPlayer在初始化和reset处于 Idle状态即STATE_IDLE。

播放视频时,MediaPlayer准备就绪(Prepared)后没有马上进入播放状态,中间有一个时间延迟时间段,然后开始渲染图像。所以将Prepared——>“开始渲染”中间这个时间段定义为STATE_PREPARED。

如果是播放网络视频,在播放过程中,缓冲区数据不足时MediaPlayer内部会停留在某一帧画面以进行缓冲。正在缓冲时,MediaPlayer可能是在正在播放也可能是暂停状态,因为在缓冲时如果用户主动点击了暂停,就是处于STATE_BUFFERING_PAUSED,所以缓冲有STATE_BUFFERING_PLAYING和STATE_BUFFERING_PAUSED两种状态,缓冲结束后,恢复播放或暂停。

 /****************
     * 播放状态
     ****************/
    /**
     * 播放错误
     */
    public static final int STATE_ERROR = -1;
    /**
     * 播放未开始
     */
    public static final int STATE_IDLE = 0;
    /**
     * 播放准备中
     */
    public static final int STATE_PREPARING = 1;
    /**
     * 播放准备就绪
     */
    public static final int STATE_PREPARED = 2;
    /**
     * 正在播放
     */
    public static final int STATE_PLAYING = 3;
    /**
     * 暂停播放
     */
    public static final int STATE_PAUSED = 4;
    /**
     * 正在缓冲,播放器正在播放时,缓冲区数据不足,进行缓冲,缓冲区数据足够后恢复
     */
    public static final int STATE_BUFFERING_PLAYING =5;
    /**
     * 正在缓冲(播放器正在播放时,缓冲区数据不足,进行缓冲,此时暂停播放器,继续缓冲,缓冲区数据足够后恢复暂停
     **/
    public static final int STATE_BUFFERING_PAUSED = 6;
    /**
     * 播放完成
     */
    public static final int STATE_COMPLETED = 7;

播放模式普通模式,全屏模式,小屏模式

 /*************
     * 播放模式
     *************/
    /**
     * 普通模式
     */
    public static final int MODE_NORMAL = 10;
    /**
     * 全屏模式
     */
    public static final int MODE_FULL_SCREEN = 11;
    /**
     * 小窗口模式
     */
    public static final int MODE_TINY_WINDOW = 
  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值