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.mzph.cn/diannao/44628.shtml

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

相关文章

分享一个项目模板electron+vue+ts+vite

分享一个项目模板electronvuetsvite GitHub - xiugou798/electron-vue-ts-vite-template: electron-vue-ts-vite-templateelectron-vue-ts-vite-template. Contribute to xiugou798/electron-vue-ts-vite-template development by creating an account on GitHub.https://gith…

linux之内存泄漏分析

内存泄漏通常是指程序中动态分配的内存没有被适时释放&#xff0c;导致这部分内存在程序的生命周期内一直无法被再次利用。内存泄漏不会直接导致程序崩溃&#xff0c;所以通常不会生成core dump文件。然而&#xff0c;如果程序因为其他原因崩溃&#xff0c;那么core dump文件可…

弱电工程质量保修期是多久?

弱电工程是电力工程的一个分类&#xff0c;弱电可以向人们提供照明用电和空调用电&#xff0c;为人们的生活带来了极大的便利。弱电工程作为一类工程项目存在质量保证问题&#xff0c;在施工完成后需要进行质量检修&#xff0c;施工队应该向业主提供一定的质量保修期&#xff0…

java 数据库连接池的种类和选型

文章目录 1.引言数据库连接池的重要性Java数据库连接池的基本概念连接池需要注意的问题 2.数据库连接池C3P0数据库连接池C3P0的基本介绍C3P0的使用示例 DBCP数据库连接池DBCP的基本介绍DBCP的使用示例 HikariCP数据库连接池&#xff08;广泛使用&#xff09;HikariCP的基本介绍…

LLM大模型应用中的安全对齐的简单理解

LLM大模型应用中的安全对齐的简单理解 随着人工智能技术的不断发展&#xff0c;大规模语言模型&#xff08;如GPT-4&#xff09;的应用越来越广泛。为了保证这些大模型在实际应用中的性能和安全性&#xff0c;安全对齐&#xff08;Safe Alignment&#xff09;成为一个重要的概…

CentOS 7 编译安装 sqlite3

1. 下载 sqlite3 源码 网址&#xff1a; https://www.sqlite.org/download.html [注]&#xff1a;可自行选择版本&#xff0c;也可与笔者保持一致。 wget https://www.sqlite.org/2024/sqlite-autoconf-3460000.tar.gz2. 解压编译并安装 解压源码包&#xff0c;并进入源码…

实验-ENSP实现防火墙区域策略与用户管理

目录 实验拓扑 自己搭建拓扑 实验要求 实验步骤 整通总公司内网 sw3配置vlan 防火墙配置IP 配置安全策略&#xff08;DMZ区内的服务器&#xff0c;办公区仅能在办公时间内&#xff08;9: 00- 18:00)可以访问&#xff0c;生产区的设备全天可以访问&#xff09; 配置nat策…

【代码随想录_Day29】卡码网46. 携带研究材料(二维数组) 46. 携带研究材料(滚动数组/一维) 416 分割等和子集

Day29 OK&#xff0c;今日份的打卡&#xff01;第二十九天 以下是今日份的总结携带研究材料(二维数组)携带研究材料(滚动数组/一维)分割等和子集 以下是今日份的总结 46 携带研究材料(二维数组) 46 携带研究材料(滚动数组/一维) 416 分割等和子集 今天的题目难度不低&#xf…

Android 性能优化之内存优化

文章目录 Android 性能优化之内存优化内存问题内存抖动内存泄露内存溢出 检测工具Memory ProfilerMemory AnalyzerLeakCanary 内存管理机制JavaAndroid 解决内存抖动问题模拟问题代码使用Memory Profiler工具检测优化技巧 内存泄露问题模拟问题代码使用LeakCanary工具检测优化技…

顺序结构 ( 四 ) —— 标准数据类型 【互三互三】

序 C语言提供了丰富的数据类型&#xff0c;本节介绍几种基本的数据类型&#xff1a;整型、实型、字符型。它们都是系统定义的简单数据类型&#xff0c;称为标准数据类型。 整型&#xff08;integer&#xff09; 在C语言中&#xff0c;整型类型标识符为int。根据整型变量的取值范…

开源大势所趋

一、开源项目的发展趋势 技术栈多样化与专业化&#xff1a;随着技术的不断进步&#xff0c;开源项目涵盖了从云计算、大数据、人工智能到区块链、物联网等各个领域&#xff0c;技术栈日益丰富和专业化。这种趋势使得开发者能够根据自己的需求选择最适合的技术工具&#xff0c;促…

dify-api的Dockerfile分析

一.dify-api的Dockerfile文件 dify-api的Dockerfile文件如下所示&#xff1a; # base image FROM python:3.10-slim-bookworm AS baseLABEL maintainer"takatostgmail.com"# install packages FROM base as packagesRUN apt-get update \&& apt-get install…

nginx安装配置视频频服务器-windows

编译安装nginx 1、安装perl 安装地址: https://strawberryperl.com&#xff0c;选择msi安装程序即可 2、安装sed for windows 下载地址&#xff1a;https://sourceforge.net/projects/gnuwin32/files/sed/&#xff0c;执行安装程序结束后&#xff0c;将安装包bin目录配置到…

【seo常见的问题】搜索引擎

1、让网站访问量提高的最好的方法是什么? 了解搜索引擎行为和搜索用户的行为&#xff0c;就是通过观察搜索引擎排名机制获得有效途径&#xff0c;提供效率&#xff0c;并且通过一些相关数据&#xff0c;了解到用户的搜索行为。 2、我要你把一个站的关键词排名排到首页&#x…

【Adobe】动作捕获和动画制作软件Character Animator

Adobe Character Animator 是一款由Adobe公司出品的动作捕获和动画制作软件&#xff0c;旨在帮助用户直观地制作2D&#xff08;二维&#xff09;人物动画、实时动画&#xff0c;并发布动画。这款软件功能强大、操作简单&#xff0c;非常适合动画制作者、直播主以及社交媒体内容…

【STM32 ARM】操作寄存器控制led

文章目录 前言GPIO操作方法led原理图设置时钟APB的概念 设置APB设置输出引脚设置引脚高低电平寄存器寻找寄存器地址 总结 前言 STM32是STMicroelectronics&#xff08;意法半导体&#xff09;公司的一款32位Flash微控制器产品&#xff0c;基于ARM Cortex™-M内核。STM32系列微…

Groovy vs Kotlin 在Gradle配置文件中的差异与选择

人不走空 &#x1f308;个人主页&#xff1a;人不走空 &#x1f496;系列专栏&#xff1a;算法专题 ⏰诗词歌赋&#xff1a;斯是陋室&#xff0c;惟吾德馨 目录 &#x1f308;个人主页&#xff1a;人不走空 &#x1f496;系列专栏&#xff1a;算法专题 ⏰诗词歌…

beyond Compare连接 openWrt 和 VsCode

连接步骤总结 1. 新建会话 -> 文件夹比较 2.点击浏览文件夹 3.在弹出页面 配置 ftp 3.1&#xff09;选中ftp 配置文件 3.2)选中ssh2 3.3)填写我们需要远端连接的主机信息 先点击连接并浏览 得到下方文件夹 弹出无效登录&#xff0c;说明需要密码 我们返回右键刚刚创建的新 …

C++ | Leetcode C++题解之第227题基本计算器II

题目&#xff1a; 题解&#xff1a; class Solution { public:int calculate(string s) {vector<int> stk;char preSign ;int num 0;int n s.length();for (int i 0; i < n; i) {if (isdigit(s[i])) {num num * 10 int(s[i] - 0);}if (!isdigit(s[i]) &&am…

【智能制造-14】机器视觉软件

CCD相机和COMS相机? CCD&#xff08;Charge-Coupled Device&#xff09;相机和CMOS&#xff08;Complementary Metal-Oxide-Semiconductor&#xff09;相机是两种常见的数字图像传感器技术&#xff0c;用于捕捉和处理图像。 CCD相机&#xff1a; CCD相机使用一种称为CCD的光电…