likes
comments
collection
share

Android 通用视频组件开发

作者站长头像
站长
· 阅读数 33

背景

  • 背景:目前车机的多媒体App都是各自维护自己的UI视图及基础逻辑,会有不少重复代码。并且大多数媒体App都会和本地多媒体有交互,所有媒体App都会接入到MediaCenter,没有统一的接口会导致接入适配成本和维护成本比较高。所以希望能够抽出公共基础功能到sdk中,供所有媒体App使用,从一致性和开发效率上得到提升。
  • 应用App:QQ音乐、杜比播放器、本地多媒体、迷你播放器

快速上手

为了应对不同的使用场景,接入方式有两种:

  • 打包播放器和UI一键接入
  • 单独视频UI(自行实现播放器)

可根据实际使用场景选择其一即可,如无特殊原因建议选择第一种方式。

1 添加依赖

在app的Gradle中加入以下依赖:

implementation 'com.max.media:media-video:$mediaVersion'

2 初始化播放器

PlayerInitializer.init(context, isVideo = true, enableMediaCenter = true)
  • Context:上下文对象,必填
  • isVideo:视频还是音频,必填
  • enableMediaCenter :是否接入媒体中心,默认true

3 接入视频UI组件

添加FlexPlayerView布局,用于展示视频内容及播控组件:

<com.flex.uniteplayer.ui.FlexPlayerView
    android:id="@+id/player_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>

4 配置视频组件

可通过FlexPlayerView对视频组件进行设置:

接口说明
fun setTitleBarVisible(visible: Boolean)隐藏视频标题栏,包括标题和左侧关闭
fun enableUpDownGesture(enable: Boolean)设置是否支持上下手势
bindControlView(listener: ControlViewListener)绑定视频控件UI,获取组件UI控制器,可直接管理视频组件。如果需要对视频组件做更多操作可使用此接口(后文会详细说明)

5 播放视频

5.1 创建播放器

首先创建一个播放器FlexSimlePlayer:

class FlexSimplePlayer(context: Context?,
    isVideo: Boolean,
    enableParkDetect: Boolean = true,
    enableParkDialog: Boolean = true)

参数说明:

参数说明
context上下文;
enableParkDetect只针对视频生效,是否启用行车娱乐限制,非驻车档会自动暂停视频播放;
enableParkDialog只针对视频生效,是否弹出行车娱乐限制框,设置为disable后需要应用可以自己实现提示界面;

5.2 开始播放

player.startPlay(context: Context,
        mediaData: List<MediaData>,
        view: FlexPlayerView?,
        listener: FlexMediaListener?,
        mediaCenterData: MediaCenterData? = null)

参数说明:

参数说明
context上下文,注意视频播放要使用activity的context,因为行车娱乐限制需要弹框
mediaData媒体列表,每个媒体item包括url、metadata、mimetiype,其中url是媒体地址,可以是本地、在线点播或直播地址,medadata是media3的原始类型,title和artist字段会显示在mini播放器和PSD上,mimeTypes指定媒体类型,url是对应后缀的无需设置,有些比如优酷投屏中有一个直播url是/m3u8结尾 而不是.m3u8结尾 需要设置mimeTypes = MimeTypes.APPLICATION_M3U8;
view类型为FlexPlayerView,自实现UI的此参数设置为null
listener媒体播放监听回调,具体回调接口后面详细展开,不需要监听设置为null
mediaCenterData媒体中心中需要用的数据,比如应用包名、图标等,具体类型后面详细展开,这里需要注意的是sourceType要设置为6,在媒体中心中对应SourceType.SOURCE_TYPE_ONLINE。

5.3 更新播放列表

fun updateMediaItems(mediaData: List<MediaData>)

5.4 停止播放

player.stopPlay()

到这里,视频就可以正常播放了。当然这个是最简单的播放,更多详细的可以参考:统一媒体播放器接入指南

对于已有播放器且对播放器有特定要求的App而言,可以选择单独接入视频UI,保持全局统一。

视频组件设置接口

在快速上手第4步“配置视频组件”中提到一个接口:bindControlView()

接口定义如下:

 /**
* 提供给APP的接口,用于APP定制视频控制UI
*/
interface ControlViewListener {
    fun onBindView(controlView: IPlayerCallback.ViewController)
}

方法onBindeView返回的是ViewController,视频组件提供的控制器,可以针对视频组件进行更细致的配置。

下面详细讲解ViewController,标红的为常用接口,希望重点关注!

1 设置全屏模式

 /**
* 设置2/3 屏样式
*/
fun setAppFrameWH()

/**
* 设置全屏样式
*/
fun setFullScreenWH()

全屏App必设接口

针对全屏和2/3屏有不同的UI样式(包括ICON大小、间距等等),所以在切换全屏模式的时候一定要同步设置接口,否则UI布局会异常。默认为2/3屏样式

2 自定义功能Button

为了适配更多的应用场景,我们将播放器下方最多5个Button开放两种定制方法。最左侧固定为播放按钮,不能修改,其余5个均可以自定义,如果不设置则默认不显示。

  • 对于只需要简单设置button的icon和点击事件的场景,可以直接使用方案一

  • 对于需要对Button做更多定制功能的,比如动效、动态替换、长按、双击事件等,需要使用方案二

· 方案一

如前描述,通过此方法可以轻松修改Button的Icon及点击事件

方法名非常直观,如下:

 /**
* 设置Left Button2样式
*  @param resId
*  @param clickListener 点击事件
*/
fun setLeftButton2(
    @DrawableRes resId: Int = 0,
    clickListener: OnClickListener? = null,
    visible: Boolean = true,
)

/**
* 设置Left Button3样式
*  @param resId
*  @param clickListener 点击事件
*/
fun setLeftButton3(
    @DrawableRes resId: Int = 0,
    clickListener: OnClickListener? = null,
    visible: Boolean = true,
)

/**
* 设置right Button1样式
*  @param resId
*  @param clickListener 点击事件
*/
fun setRightButton1(
    @DrawableRes resId: Int = 0,
    clickListener: OnClickListener? = null,
    visible: Boolean = true,
)

/**
* 设置right Button2样式
*  @param resId
*  @param clickListener 点击事件
*/
fun setRightButton2(
    @DrawableRes resId: Int = 0,
    clickListener: OnClickListener? = null,
    visible: Boolean = true,
)

/**
* 设置right Button3样式
*  @param resId
*  @param clickListener 点击事件
*/
fun setRightButton3(
    @DrawableRes resId: Int = 0,
    clickListener: OnClickListener? = null,
    visible: Boolean = true,
)

顾名思义,找到你需要自定义的Button,按照参数设置即可

· 方案二

如果你需要针对Button做更深入的定制,那么可以通过以下接口直接拿到Button实例,则可以设置你需要的任何属性。

 /**
* 获取Button
*  @param viewType 根据Type获取对应的Button
*/
fun getButton(viewType: ButtonType): ImageView

3 获取进度条

对于部分App需要自定义进度条,或者拿到进度条实例做一些监听及修改,可以通过以下接口实现:

 /**
* 获取进度条
*/
fun getProgressBar(): FlexProgressBar

4 设置关闭按钮左边距

 /**
* 设置关闭按钮距离
*/
fun setCloseMargin(left: Int, top: Int = CLOSE_MARGIN_TOP)

5 设置进度条左右边距


/**
* 设置进度条距离
*/
fun setProgressMargin(bottom: Int,
                      left: Int = BOTTOM_BAR_MARGIN_LEFT,
                      right: Int = BOTTOM_BAR_MARGIN_RIGHT)

6 设置Loading延迟显示时间

默认1000ms内的loading不进行展示,若需要不控制loading时长则可以该属性设置为0.

ViewController.loadingDelayDurationMillisecond

Q&A

1 可以让播放器和视频组件版本独立吗?

可以,并且这个是推荐的做法。

目前播放器内部集成了视频组件,也就是说只需要依赖视频播放器即可包含视频组件。但是视频组件和播放器版本是分开管理的,可能播放器的版本是滞后的。建议依赖了视频播放器之后,在单独加一个视频组件的依赖,如下:

implementation 'com.max.mediaplayer:uniteplayer:$playerVersion'
implementation 'com.max.media:media-video:$mediaVersion'

版本更新记录

内测版

仅SNAPSHOT:

**版本(内测版,仅SNAPSHOT)更新日志
0.5.01. 视频基础控制; 2. 支持配置底部icon的资源id和点击事件
0.6.01. 修复手势滑动bug
0.6.21. 修复底部icon接口Bug
0.7.01. 增加了错误页提示 2. 修复部分rom不能调亮度的问题3. 自适应平板和车机4. 修复暂停后拖动进度条持续loading的问题
0.8.61. 支持禁用上下滑手势2. 调整视频View层级
0.9.01. 支持监听视频组件的双击、长按事件2. 去掉toggleControlView接口

正式版

版本更新日志
1.0.01. 修改controlView实例的获取方式,改为异步调用2. 支持2/3屏和全屏两套UI布局模式一键切换 1) 2/3屏模式:controlView.setAppFrameWH()2)全屏模式:controlView.setFullScreenWH()3. 支持自定义LoadingView、进度条边距及icon尺寸4. 修改UI走查问题
1.1.01. 修复视频时长小于1h时格式问题2. 优化上下手势和Dock栏冲突3. 调节亮度时取消自动调节亮度勾选4. 修复持续上下手势,Tips闪烁5. Loading态支持调起控件6. 处理加载页和错误页互斥逻辑
1.2.01. 上下手势不主动调起播控UI2. 视频手势层级优化3. Loading支持播控UI调起4. UI样式优化
1.2.21. 滑动进度条时,显示进度Tips2. 进度条及底部Bar优化
1.2.31. 滑动进度,展示进度Tips
1.2.51. 调整进度条样式
1.2.6优化全屏状态下标题栏位置
1.2.71. 优化全屏Toast位置(居中改到顶部)
1.3.51. [视频播放器UI]优化在车机屏幕下双击/单击事件的阈值和行为2. [视频播放器UI]优化在电话场景下播放器依然能够点击的问题3. [视频播放器UI]支持自定义播放器UI控制效果4. [视频播放器UI]支持自定义loading延迟时长,默认1s内loading不显示.5. [视频播放器UI]支持3/2全屏无缝播放效果6. [音乐播放器]大小播放器设计/动效支持
转载自:https://juejin.cn/post/7385375139305275411
评论
请登录