Android 通用视频组件开发

背景

  • 目前车机的多媒体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.FlexPlayerViewandroid: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. 上下手势不主动调起播控UI
2. 视频手势层级优化
3. Loading支持播控UI调起
4. UI样式优化
1.2.21. 滑动进度条时,显示进度Tips
2. 进度条及底部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. [音乐播放器]大小播放器设计/动效支持

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/374235.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【动态规划Ⅳ】二维数组的动态规划——最小路径和

二维数组的动态规划 最小路径和64. 最小路径和原地修改数组定义二维数组进行状态转移优化&#xff1a;用 一维数组进行状态转移相似题目&#xff1a;LCR 166. 珠宝的最高价值 120. 三角形最小路径和原地修改数组定义二维数组进行状态转移一维数组进行状态转移自底向上&#xff…

推荐一个比 Jenkins 使用更简单的项目构建和部署工具

最近发现了一个比 Jenkins 使用更简单的项目构建和部署工具&#xff0c;完全可以满足个人以及一些小企业的需求&#xff0c;分享一下。 项目介绍 Jpom 是一款 Java 开发的简单轻量的低侵入式在线构建、自动部署、日常运维、项目监控软件。 日常开发中&#xff0c;Jpom 可以解…

【R语言+Gephi】利用R语言和Gephi实现共发生网络的可视化

【R语言Gephi】利用R语言和Gephi实现共发生网络的可视化 注&#xff1a;本文仅作为自己的学习记录以备以后复习查阅 一 概述 Gephi是一款开源免费的多平台网络分析软件&#xff0c;在Windows、Linux和Mac os上均可以运行&#xff0c;像他们官网所说的&#xff0c;他们致力于…

Excel第29享:基于sum嵌套sumifs的多条件求和

1、需求描述 如下图所示&#xff0c;现要统计12.17-12.23这一周各个人员的“上班工时&#xff08;a1&#xff09;”。 下图为系统直接导出的工时数据明细样例。 2、解决思路 首先&#xff0c;确定逻辑&#xff1a;“对多个条件&#xff08;日期、人员&#xff09;进行“工时”…

ONLYOFFICE 8.1版本版本桌面编辑器测评

ONLYOFFICE官网链接&#xff1a;ONLYOFFICE - 企业在线办公应用软件 | ONLYOFFICE ONLYOFFICE在线办公套件&#xff1a;在线办公套件 | ONLYOFFICE ONLYOFFICE在线PDF编辑器、阅读器和转换器&#xff1a;在线PDF查看器和转换器 | ONLYOFFICE ONLYOFFICE 8.1版本桌面编辑器是…

【中项第三版】系统集成项目管理工程师 | 第 4 章 信息系统架构⑤ | 4.8 - 4.9

前言 第4章对应的内容选择题和案例分析都会进行考查&#xff0c;这一章节属于技术相关的内容&#xff0c;学习要以教材为准。本章分值预计在4-5分。 目录 4.8 云原生架构 4.8.1 发展概述 4.8.2 架构定义 4.8.3 基本原则 4.8.4 常用架构模式 4.8.5 云原生案例 4.9 本章…

【DevOps】在云原生时代的角色与重要性探索

&#x1f407;明明跟你说过&#xff1a;个人主页 &#x1f3c5;个人专栏&#xff1a;《未来已来&#xff1a;云原生之旅》&#x1f3c5; &#x1f516;行路有良友&#xff0c;便是天堂&#x1f516; 目录 一、引言 1、什么是云原生 2、云原生的核心特性 3、什么是DevOps…

昇思25天学习打卡营第14天|基于MindNLP的文本解码原理

基于MindNLP的文本解码原理 文本解码 文本解码是自然语言处理中的一个关键步骤,特别是在任务如机器翻译、文本摘要、自动回复生成等领域。解码过程涉及将编码器(如语言模型、翻译模型等)的输出转换为可读的文本序列。以下是一些常见的文本解码方法和原理: 1. 自回归解码:…

安装nodejs | npm报错

nodejs安装步骤: 官网&#xff1a;https://nodejs.org/en/ 在官网下载nodejs: 双击下载下来的msi安装包&#xff0c;一直点next&#xff0c;我选的安装目录是默认的: 测试是否安装成功&#xff1a; 输入cmd打开命令提示符&#xff0c;输入node -v可以看到版本&#xff0c;说…

Django项目创建的基本准备工作【4】

【 一 】软件开发模式 官话下面 人话 瀑布开发就是将什东西都定义好了在进行开发对吧 敏捷就是进行模块化一样 分批进行 规定一个时间段完成什么样的功能。 总结来说&#xff0c;瀑布开发强调在项目开始之前进行详细的计划和准备&#xff0c;并按照预定的顺序逐步进行&#x…

E. Beautiful Array(cf954div3)

题意&#xff1a;给定一个数组&#xff0c;可以先对数组进行任意排序&#xff0c;每次操作可以选择一个ai&#xff0c;将它变成aik&#xff0c; 想让这个数组变成一个美丽数组&#xff08;回文数组&#xff09;&#xff0c;求最少操作次数 分析&#xff1a; 先找出相同的数字…

使用Docker制作python项目镜像

各docker桌面版本集合&#xff1a;如果提示新版本系统不支持&#xff0c;可下载旧版本 我也分享在下面。 链接: https://pan.baidu.com/s/1HvaO2wOIE3pNE0bM7Qm3sA?pwdg7ky 提取码: g7ky –来自百度网盘超级会员v2的分享 来源参考&#xff1a;https://zhuanlan.zhihu.com/p/65…

【Linux】命令执行的判断依据:;,,||

在某些情况下&#xff0c;很多命令我想要一次输入去执行&#xff0c;而不想要分次执行时&#xff0c;该如何是好&#xff1f; 基本上有两个选择&#xff0c; 一个是通过shell脚本脚本去执行&#xff0c;一种则是通过下面的介绍来一次入多个命令。 1.cmd&#xff1a;cmd&#…

【RHCE】基于用户认证和TLS加密的HTTP服务(HTTPS)

目录 一、创建用户账号 二、TLS加密 三、配置http服务子配置文件 四、创建访问http服务的文件夹以及输入重定向到文件 五、配置Linux本地仓库以及Windows下的本地仓库 六、基础操作 七、测试 一、创建用户账号 用户认证 # 创建两个账户 [rootlocalhost ~]# htpasswd -…

前端面试39(关于git)

针对前端开发者的Git面试题可以覆盖Git的基础概念、常用命令、工作流程、团队协作、以及解决冲突等方面。以下是一些具体的Git面试 Git基础知识 什么是Git&#xff1f; Git是一个分布式版本控制系统&#xff0c;用于跟踪计算机文件的更改&#xff0c;并协调多个人共同在一个项…

C++ | Leetcode C++题解之第225题用队列实现栈

题目&#xff1a; 题解&#xff1a; class MyStack { public:queue<int> q;/** Initialize your data structure here. */MyStack() {}/** Push element x onto stack. */void push(int x) {int n q.size();q.push(x);for (int i 0; i < n; i) {q.push(q.front());…

【雷达原理】数字波束形成(DBF)

目录 一、数字波束形成1.1 DBF原理1.2 工程应用实现方式1.2.1 预先存储权矢量1.2.2 利用DFT/FFT实现DBF 二、DBF应用2.1 通道间相干积累2.2 测量目标角度 三、MATLAB代码 一、数字波束形成 数字波束形成&#xff08;Digital Beam Forming&#xff0c;DBF) 技术&#xff0c;是针…

智驭未来:人工智能与目标检测的深度交融

在科技日新月异的今天&#xff0c;人工智能&#xff08;AI&#xff09;如同一股不可阻挡的浪潮&#xff0c;正以前所未有的速度重塑着我们的世界。在众多AI应用领域中&#xff0c;目标检测以其独特的魅力和广泛的应用前景&#xff0c;成为了连接现实与智能世界的桥梁。本文旨在…

2024最新国际版抖音TikTok安装教程,免root免拔卡安卓+iOS,附全套安装工具!

我是阿星&#xff0c;今天给大家带来是2024年最新TikTok国际版抖音的下载和安装教程&#xff0c;而且还是免root免拔卡的那种&#xff0c;安卓和iOS都能用哦&#xff01;由于某些原因&#xff0c;国内用户并不能使用TikTok。今天阿星就教一下大家怎么安装TikTok。 TikTok在全球…

杜比全景声——空间音频技术

什么是杜比&#xff1f;是否是标清、高清、超清之上的更清晰的格式&#xff1f;杜比全景声 和传统多声道立体声的差别&#xff1f;杜比全景声音频的渲染方式&#xff1f;车载平台上杜比技术的应用&#xff1f; 杜比技术的起源 杜比实验室&#xff08;Dolby Laboratories&…