组件化封装思想实战Android App总结七App公共模块之视频SDK模块开发一

241 篇文章 5 订阅

一、几个问题

1、如何自定义一个视频播放器?

Android提供了很多方式,有videoview,有mediaplayer,有surfaceview等等,或者可以使用开源的等等。

2、什么是sdk,为什么要将其封装为一个sdk?

直接实现一个播放器不就可以了吗?

sdk全称是software development kit,也就是软件开发包,常见的就是Android sdk,如果没有Android sdk的话就没有Android api,也就无法开发我们的应用、游戏。还有一些常见的sdk,比如友盟sdk、sharesdk、讯飞语音sdk、高德地图sdk等等。这些sdk都有一个共同的特点,一是它们高度封装,对使用者来说,我们并不关心它内部的实现逻辑,只需要调用它们几个比较简单的接口或者方法就可以实现功能。所以sdk对开发者来说是一个比较常见的名词,但是如果没有做过sdk的话,对我们来说又是一个比较陌生的名词。为什么要封装一个sdk呢?将我们的程序代码高度地封装以后呢,就可以拿来去给别人使用。

3、如何统计我们视频播放次数?

视频播放过程中会发各种各样的监测,这种监测就是监测视频播放的状态,是播放中还是播放完成了,还是播放到第几秒了。

 

4、思维导图

 

二、播放器封装讲解

1、几个问题

①如何定义一个视频播放器?

②了解视频播放器生命周期吗?

 

首先,播放器处于iddle状态,也就是空闲状态。此时调用setDataSource()方法,如果成功的话会到Intialized状态,如果失败的话就会进入的Error状态。在进入到初始化状态Intialized时,如果调用prepareAsync()方法,则进入到准备中Preparing状态,当然也可以通过调用同步方法prepare()同步等待进入Prepared状态。但是,同步的方法prepare()一般情况下是不会用到的,因为Android一般是不允许主线程中有任何耗时操作的。在Prepared状态时可以通过调用start()进入Started状态,在Started状态视频播放就正常播放起来了。在started状态下调用stop()方法,就会进入到Stopped状态,或者调用pause()方法进入到Paused状态,或者等到播放完成进入到completed状态。这三种状态是相互可逆的。也就是completed、Stopped、Paused都可以进入到started状态。

③自定义视频播放器有哪些坑

2、核心知识串讲

①MediaPlayer视频播放核心类

控制视频播放器是否播放成功,是否准备成功,视频播放、暂停、停止、完成的一个流程控制

②TexttureView显示帧数据核心类

与Surfaceview的原理是一样的但是比SurfaceView多了些特性。SurfaceView有三个状态的监听,一个是create()、一个是change()、一个是destroy(),而TextTureView也一样,分别有avalible()、change()、destroy()三个接口的监听,来通知开发者当前texttureview当前处于什么状态,如果是avalible()就可以去加载视频,加载完以后就可以让texttureview去显示

③众多事件接口概述

主要用于监听MediaPlayer当前处于什么状态

常见的几个接口:

OnPreparedListener:异步地告诉程序员mediaplayer处于prepare状态,这时可以调用start()去播放视频了

onErrorListener:不仅要处理正常的逻辑,也要在出现异常的时候保证程序能够正常地运行

onCompletionListener:在视频播放完成后发一个消息通知程序员视频播放完成了,在这里做一些处理。比如当视频播放完成时发送一个监测,就是在这个方法中发送的

onBufferingUpdateListener:在视频不断地缓冲过程中调用,如果视频非常大的话会分段去缓存的。每缓存一段儿,会调用OnBufferingUpdateListener告诉我们现在缓存的状态

3、开发步骤

三、创建视频播放器核心类CustomVideoView

1、CustomViewdeoView,继承自RelativeLayout并且实现了MediaPlayer中的一些监听接口。主要作用是负责视频播放、暂停以及各类事件的触发等等。同时也实现了TextureView.SurfaceTextureListener,这个接口是textureview的回调,会告诉我们现在的textureview是否准备好了,是否改变以及是否有效果。一般情况下实现这些接口,足够做一个比较完善的播放器了

2、定义了一些常量

TIME_MSG:事件类型,后面会在handler中使用

TIME_INVAL:时间间隔,每隔1000毫秒会发一个TIME_MSG出来

STATE_ERROR、STATE_IDLE、STATE_PLAYING、STATE_PAUSING是当前状态的标志,mediaplayer是有生命周期状态的,通过这些状态声明它当前处于什么状态

LOAD_TOTAL_COUNT:视频可能会加载失败,这里定义了一个重试的机制

 

3、定义了一些UI

 

ViewGroup mParentContaine   :  VideoView所要添加到的父容器中

RelativeLayout mPlayerView :  当前父容器的RelativeLayout

TextureView mVideoView:  要显示帧数据上去的那个view

AudioManager audioManager:音频播放器,用来控制音量是否静音

Surface videoSurface :最终真正显示帧数据的类

其余几个Button就是播放按钮

 

4、数据相关的

mUrl :要加载的视频地址

isMute : 是否静音

mScreenWidth:屏幕宽度,默认是屏幕的宽度

mDestationHeight:屏幕默认的高度,默认是16:9算出来的高度

 

5、状态标志位

mIsRealPause: 状态是不是真正进入暂停了

mIsComplete : 播放器是否播放完成了

playerState : 播放器当前处于什么状态,默认处于Idle状态

 

6、相关类

MediaPlayer mediaPlayer : 播放的核心类

ADVideoPlayerListener listener  : 事件的监听,通知外界发生的事件,由外界实现这个监听的逻辑处理

ScreenEventReceiver mScreenReceiver : 自定义的broadcastreceiver,用来监听屏幕是否锁屏。如果屏幕锁屏后,播放器是需要暂停的,如果用户解锁后进入到应用程序,是需要恢复播放的

Handler mHandler : 作用是每隔1s发送一个TIME_MSG事件并通过调用listener的onBufferUpdate来通知当前的播放进度。timer能不用尽量不用,因为它很容易造成内存泄漏。

 

7、构造方法中进行初始化操作

 

8、主要生命周期方法

onVisibilityChanged(View changedView,int visibility) : 所有view都有的生命周期方法,当状态发生变化的时候,会去回调这个函数。如果view由不可见变为可见,此时visibility为visible;如果view由可见变为不可见,此时visibility为gone

 

 

onTouchEvent为事件触摸处理,返回true,表明只要事件传递到视频播放器中,就会把事件消耗掉,主要是为了防止与父容器产生的一些事件冲突

 

 

onClick() :主要是处理一些点击事件,比如点击播放、点击到全屏等等

onCompletion() :是前面的接口onCompleteListener当中的一个方法,当视频播放器播放完成后会回调这个方法

onError() :是onErrorListener中的一个方法,当视频播放器播放出错时会回调这个方法

 

onPrepared():视频播放器已经准备好了,此时可以调用这个方法,可以进行播放,可以调用start()进入播放状态

 

onBufferingUpdate():是缓存的一个更新

 

上面四个方法是textureview的状态更新方法,最重要的是onSurfaceTextureAvailable()方法因为只有处于该状态时才可以为它加载帧数据,否则的话是一片黑屏

 

9、功能性方法

包括加载视频url

暂停视频

恢复视频(包括从就绪状态恢复到播放状态以及从pause状态恢复到播放状态,一旦到resume()状态就说明视频处于播放中)

playBack():是播放完成后回到初始状态,这里的处理逻辑是播放完成后不把视频销毁,而是把播放流跳转到0,处于暂停状态,这样在下次播放时就不需要耗费流量去加载视频了

 

stop():让视频处于停止状态,停止状态和暂停状态不一样。如果处于停止状态,那么只能是去重新prepare()

destroy():就是销毁videoview,不仅会销毁mediaplayer,也会销毁事件的监听。实际上相当于activity的onDestroy()方法

 

seekAndResume()和seekAndPause()其实并不是定义播放器必需的方法,但是由于功能的特殊性,有一个小屏跳转到大屏的播放功能,跳转之后是需要续播的。也就是说小屏播放到第5s的话,跳转到大屏也需要从第5s开始播放,所以需要这两个方法

 

setListener() :设置监听,当事件发生后,会调用listener中对应的方法来通知外界,播放器中产生了哪些方法

 

10、辅助方法

 

 

包括注册和取消注册监听、view的一些显示

 

 

获取播放器的时长以及当前播放的时间等等

 

 

定义播放器最难的有两点,一个是播放器状态的处理,另一个是功能性方法的实现

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值