自己做网站下载怎么,动画设计实训报告,海安网站设计,国家建设工程注册管理中心网站简介
统一播放器提供媒体播放一致性的交互和视觉体验#xff0c;减少各个媒体应用和场景独自开发的重复工作量#xff0c;实现媒体播放链路的一致性#xff0c;减少碎片化的Bug。本文面向应用开发者介绍如何快速接入媒体播放器。
主要功能#xff1a;
新设计的统一播放U…简介
统一播放器提供媒体播放一致性的交互和视觉体验减少各个媒体应用和场景独自开发的重复工作量实现媒体播放链路的一致性减少碎片化的Bug。本文面向应用开发者介绍如何快速接入媒体播放器。
主要功能
新设计的统一播放UI组件视频支持的手势操作包括左右滑拖动进度、左上下滑调节亮度、右上下滑调节音量、双击暂停/播放同时对外暴露了长按手势接口应用可以实现类似快进快退功能支持方控、Mini播放器、PSD的播控和状态显示应用只需要申请媒体中心权限的license即可支持媒体中心的状态保持和语音控制通道需要APP中接入对应的接口支持视频行车娱乐限制非P档播放视频会暂停播放弹框提示使用原生的的media3 1.3.0版本支持原生的androidx 和framework media session支持音频焦点自管理包括电话状态的播控也基于音频焦点统一处理
整体架构图如下 应用通过配置UI然后创建MediaController播放媒体controler端接入了行车娱乐限制的检测和提示service端实现了google原生的media3 session service媒体中心通过mediasession和播放器连接底层使用media3 exoplayer播放和音频焦点管理
接入流程
1、配置依赖
implementation com.max.mediaplayer:uniteplayer:1.x.x备注uniteplayer中包含了视频控制UI组件当只需要修复控制UI组件的bug时可以更新整体uniteplayer播放器组件也可以只增加UI组件的依赖比如implementation (‘com.max.media:media-video:1.2.0’)。
2、初始化
建议在application创建的时候调用初始化接口
init(context: Context, isVideo: Boolean, enableMediaCenter: Boolean false)
参数说明context应用contextisVideo是否视频应用视频会初始化车机相关的adapterapi音乐目前不会初始化enableMediaCenter需要远程方控、语音控制、mini播放器控制这些能力时设置为true否则为false默认为false
3、接入 UI 组件 视频应用
这里的UI组件只针对视频应用音频应用的UI组件在媒体组件库中参考媒体视频组件。
1配置PlayerView
在布局中增加FlexPlayerView视频内容显示和播控UI都在此view中一般默认配置如下即可
com.max.uniteplayer.ui.FlexPlayerViewandroid:idid/player_viewandroid:layout_widthmatch_parentandroid:layout_heightmatch_parent/其中播控UI是可单独接入的若需定制接入见视频组件接入文档。
2配置视频渲染view
一般情况下不需要特别配置支持的定制视频显示view参数如下
比如在上面FlexPlayerView xml中用app:surface_type“surface_view”
surface_typesurface类型取值如下默认是surface_view类型
attr namesurface_type formatenum enum namenone value0/ enum namesurface_view value1/ enum nametexture_view value2/ enum namespherical_gl_surface_view value3/ enum namevideo_decoder_gl_surface_view value4//attrresize_mode取值如下默认fit模式 attr nameresize_mode formatenum enum namefit value0/ enum namefixed_width value1/enum namefixed_height value2/ enum namefill value3/ enum namezoom value4/ /attrfirst_render_delay首帧显示延迟时长用于规避首帧渲染慢闪拉伸的问题int型单位ms一舨不需要设置默认0
3配置视频播控View
FlexPlayerView本身对外暴露了两个接口
接口说明fun setTitleBarVisible(visible: Boolean)因此视频播放器中顶部title和关闭按钮一般应用自己实现的可以通过此接口隐藏fun enableUpDownGesture(enable: Boolean)使能上下滑动默认播放器是支持的可以设置false关闭bindControlView(listener: FlexPlayerView.ControlViewListener)获取视频播控view控制器提供更多配置能力比如增加手势监听回调、添加自定义的播控按钮等具体可以参考视频组件接入文档。
4、使用播放器播放
有3种播放接口选择其中一个
1FlexSimplePlayer
封装的最高层播放接口内部封装好了原生MediaItem对象简单的视频播放场景推荐使用此接口
class FlexSimplePlayer(context: Context?,isVideo: Boolean,enableParkDetect: Boolean true,enableParkDialog: Boolean true,controllerCallback: FlexControllerCallback? null)参数说明
参数说明context上下文enableParkDetect只针对视频生效是否启用行车娱乐限制非驻车档会自动暂停视频播放默认是强制要求的enableParkDialog只针对视频生效是否弹出行车娱乐限制框设置为disable后需要应用可以自己实现提示界面
开始播放
player.startPlay(context: Context,mediaData: ListMediaData,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_M3U8view类型为FlexPlayerView自实现UI的此参数设置为nulllistener媒体播放监听回调具体回调接口后面详细展开不需要监听设置为nullmediaCenterData媒体中心中需要用的数据比如应用包名、图标等具体类型后面详细展开这里需要注意的是sourceType要设置为6在媒体中心中对应SourceType.SOURCE_TYPE_ONLINE。controllerCallback媒体中心回调的方法包括播放/暂停、上/下曲切换在此回调中可以实现自定义处理逻辑并屏蔽底层播放器的响应
退出界面停止播放停止播放后会释放所有播放资源
player.stopPlay()
页面切换的处理建议
视频应用界面退到后台onPuse暂停 player.pause()
视频应用从后台回到前台onResume player.play()
更新播放列表
fun updateMediaItems(mediaData: ListMediaData)
在已经进入播放状态下更换播放的视频建议使用该接口避免重新startPlay()会更慢。
2FlexMediaController
音频类应用复杂场景建议使用该接口。
FlexSimplePlayer下层的接口使用该接口需要自己创建MediaItemmimeType需要调用util接口设置。适合需要自己构建比较复杂的mediaitem场景另外没有直接提供暂停和播放接口需要调用成员player的暂停和播放接口。
构造方法解释同FlexSimplePlayer。
开始播放
fun startPlay(context: Context,mediaItems: ListMediaItem,view: FlexPlayerView?,listener: FlexMediaListener?,customData: MediaCenterData?,controllerCallback: FlexControllerCallback? null)参数说明
参数说明context上下文注意视频播放要使用activity的context因为行车娱乐限制需要弹框mediaItems媒体列表原生类型包括媒体urlmetadatamimetype等view类型为FlexPlayerView自实现UI的此参数设置为nulllistener媒体播放监听回调具体回调接口后面详细展开不需要监听设置为nullmediaCenterData媒体中心中需要用的数据比如应用包名、图标等具体类型后面详细展开这里需要注意的是sourceType要设置为6在媒体中心中对应SourceType.SOURCE_TYPE_ONLINE。controllerCallback媒体中心回调的方法包括播放/暂停、上/下曲切换在此回调中可以实现自定义处理逻辑并屏蔽底层播放器的响应
FlexControllerCallback接口
interface FlexControllerCallback {companion object {const val KEY_ACTION_TYPE actionTypeconst val KEY_CALLBACK_RESULT callbackResultconst val TYPE_PLAY 1const val TYPE_NEXT 2const val TYPE_PREVIOUS 3const val RESULT_OK 0const val RESULT_BLOCK 1}fun onDefaultCallback(bundle: Bundle): Bundle?{return Bundle.EMPTY}fun onPlayAction(): Int?{return RESULT_OK}fun onSeekToNext(): Int?{return RESULT_OK}fun onSeekToPrevious(): Int?{return RESULT_OK}
}接口描述
接口说明onPlayAction(): Int?媒体中心调用过来的播放/暂停接口onSeekToNext(): Int?媒体中心调用过来的下一首接口onSeekToPrevious(): Int?媒体中心调用过来的上一首接口
退出界面停止播放停止播放后会释放所有播放资源
player.stopPlay()
页面切换的处理建议
视频应用界面退到后台onPuse暂停 player.player?.pause()
视频应用从后台回到前台onResume player.player?.play()
更新播放列表
fun updateMediaItems(mediaItems: ListMediaItem)
在已经进入播放状态下更换播放的视频建议使用该接口避免重新startPlay()会更慢。
3FlexExoPlayerController
此接口一般不会用到前面两个接口默认会启动sessionservice支持媒体中心的连接此接口直接返回exoplayer播放器不会创建mediasession不支持媒体中心连接支持视频行车娱乐限制。使用媒体UI组件和播放器需要在应用中自行对接适用于定制化比较多不需要远程播放支持的视频播放场景目前只用在赛道模式。建议优先选用前面两种方式播放。
构造方法解释同FlexSimplePlayer。
fun getExoPlayer(audioFocus: Boolean false,mediaListener: FlexMediaListener? null): ExoPlayer?参数和返回值
参数说明audioFocus是否打开音频焦点自管理默认是false。在赛道模式情况存在两个视频同时播的情况需要设置为false否则因为音频焦点抢占不能同时播放其他场景建议设置为truemediaListener状态回调同前面两个接口具体参数后面详细描述返回值media3 ExoPlayer对象。
5、状态回调接口
自定义的播放回调接口
interface FlexMediaListener{//player加载完成fun onLoadPlayerFinished(player: Player?) {}//返回true不会自动播放需要调用play()后才能播放默认falsefun pauseWhenStart(): Boolean {return false}//直接返回player的状态接口更多复杂场景建议拿player对象处理fun onPlaybackStateChange(state: Int){}fun onPlayWhenReadyChanged(ready: Boolean, reason: Int) {}fun onMediaItemTransition(mediaItem: MediaItem?, reason: Int) {}//播放异常fun onPlayerError(errorCode: Int, errorData: Bundle?) {}//只针对视频播放视频时检测到非驻车状态回调会自动暂停播放fun onStartVideoWhenNoPark() {}//只针对视频非驻车播放视频弹框点击关闭按钮后的回调fun onStopVideoWhenNoPark() {}//关闭播放页面fun onClose(){}//退出应用fun onExitApp() {}//Mote: This is callback from media center, not from playerfun onSeekToNext(): Boolean {return false}fun onSeekToPrevious(): Boolean {return false}
}接口描述
接口说明onLoadPlayerFinished(player: Player?)开始播放是异步的调用此回调表示已完成了到服务端的连接返回了有效的player接口fun pauseWhenStart(): Boolean开始播放后是否自动暂停需要用户手动点击播放默认falsefun onPlaybackStateChange(state: Int) fun onPlayWhenReadyChanged(ready: Boolean, reason: Int) fun onMediaItemTransition(mediaItem: MediaItem?, reason: Int)原生Player接口播放状态变化的透传state取值Player.STATE_IDLE还未开始播放STATE_BUFFERING缓冲中STATE_READY准备好播放结合PlayWhenReady状态来判断true为播放中false为暂停STATE_ENDED播放结束onPlayWhenReadyChanged取值 true为播放中false为暂停onMediaItemTransition切歌可以通过这里判断fun onPlayerError(errorCode: Int, errorData: Bundle?)播放异常errorCode时原生的错误码errorData暂时没有用到fun onStartVideoWhenNoPark()只针对视频档检测到非P档播放视频时会回调此接口fun onStopVideoWhenNoPark()只针对视频非P播放视频弹框后点击关闭按钮或弹框自动退出时的回调fun onClose()用户点击左上角关闭按钮fun onExitApp()退出应用暂未用到fun onSeekToNext()方控或PSD切换下一曲操作会回调返回true表示应用来接管下一曲操作不会调用底层播放器的下一曲接口返回false底层会调用播放器的下一曲接口 目前投屏用到fun onSeekToPrevious()方控或PSD切换上一曲操作会回调返回true表示应用来接管上一曲操作不会调用底层播放器的上一曲接口返回false底层会调用播放器的上一曲接口投屏用到
6、语音控制
媒体中心语音控制接口声明支持的语音语义以及处理语音控制的回调
fun declareVrSemanticsCapability(channelInfo: MCVrChannelInfo?,vrSemanticCallback: VrSemanticCallback)参数说明
参数说明channelInfoMCVrChannelInfo类型具体字段 mediaPackageName: 应用包名 mediaVersion: 应用版本 mediaDescription: 应用描述 channelDataType: 通道类型一般设置为0 semantics: IntArray 支持的语义数组MCSemanticsType.CONTROL_PLAY等vrSemanticCallback语音的回调具体的实现可参考媒体中心接入文档
7、播放状态保持
媒体中心的状态保持功能可实现应用的自启动通过媒体中心拉起首先在开始播放的时候需要在mediacenterdata中设置recoveryIntent
示例 val intent Intent()intent.setPackage(com.max.example)intent.action com.max.example.action.RecoverServiceintent.putExtra(type, StateRecover)后面在车机重启后通过如下接口获取之前的播放状态
fun getRecoveryPlaybackInfo (infoCallback: ConsumerMCPlaybackInfo?)
其中MCPlaybackInfo类型和媒体中心中的MusicPlaybackInfo对应通过其中的包名可以判断上一次是否自己播放然后更新媒体中心到迷你播放器实现重启播放恢复的功能。
8、自定义通道
1媒体中心通道
媒体中心通道用于更新Mini播放器和PSD状态
接口FlexMediaController.sendCustomAction(action: Int, bundle: Bundle? null)
更新歌词 val bd Bundle()bd.putString(Constants.KEY_LYRIC_STRING, hello lyric)mediaController?.sendCustomAction(Constants.ACTION_UPDATE_LYRIC, bd)更新播放状态
用于在非播放状态下强制更新媒体信息到媒体中心。 mediaController?.sendCustomAction(Constants.ACTION_UPDATE_MEDIACENTER, null)2远程MediaSession通道
远程Mediasession主要用于更新RSD的信息。
Androidx原生接口MediaController.sendCustomCommand(command: SessionCommand, bundle: Bundle)
设置歌词 val bd Bundle()bd.putString(lyrics, lyric)bd.putString(lyrics_tr, lyricTr) //英文歌词it.sendCustomCommand(SessionCommand(Constants.COMMAND_SET_SESSION_EXTRA,Bundle.EMPTY), bd)设置试看点 val bd Bundle()bd.putBoolean(isCanTrail, isCanTrail)//true试听歌曲false非试听歌曲bd.putLong(trail_start, start)bd.putLong(trail_end, end)it.sendCustomCommand(SessionCommand(Constants.COMMAND_SET_SESSION_EXTRA,Bundle.EMPTY), bd)9、更多功能使用原生Player/MediaController接口
有其他更多播放场景的需求可以通过FlexSimplePlayer/FlexMediaController/player直接拿到media3的原始player对象实现。
注意事项
Media3要求工程的compileSDK34这个改动会影响编译过程不影响运行时。可能会涉及少量系统接口参数适配否则编译会报错targetSDK建议不动Player的接口调用在主线程进行对应的状态listener回调也会在主线程中需要在同一个线程中否则会报异常startPlay()和stopPlay()调用时机需要匹配比如在onCreateView中调用startPlay() 在onDestoryView中调用stopPlay()或者在startPlay()之前先调用stopPlay()全屏的视频播放activity的decorView.windowSystemUiVisibility需要设置View.SYSTEM_UI_FLAG_FULLSCREEN这样行车娱乐限制的弹框会根据全屏的状态隐藏状态栏和docker栏当前版本还不支持mediasession service多进程
参考Demo
uniteplayerdemo视频
音频类可参考杜比播放器和网易云音乐APP等应用附网易云APP的播放架构 遗留问题
1、电话中播放控制还未在框架中实现需要应用来处理