Exoplayer+Exomedia打造自定义播放器(二)
来源:互联网 发布:程序员用什么画流程图 编辑:程序博客网 时间:2024/05/28 17:06
Exomedia源码分析
VideoControls 播放器基类
继承自RelativeLayout,播放器基类。作用是提供一些默认的播放器基本组件;提供反射控制器布局、显示加载进度、播放器隐藏显示动画等方法;设置监听回调等等;
- 基类只提供abstract方法,由子类具体实现。
public abstract class VideoControls extends RelativeLayout { //默认的视频播放器组件 protected TextView currentTimeTextView; protected TextView endTimeTextView; protected TextView titleTextView; protected TextView subTitleTextView; protected TextView descriptionTextView; ... /** * 反射默认播放组件(开始/暂停按钮,快进后退,进度条等) */ protected void retrieveViews() { currentTimeTextView = (TextView) findViewById(R.id.exomedia_controls_current_time); endTimeTextView = (TextView) findViewById(R.id.exomedia_controls_end_time); titleTextView = (TextView) findViewById(R.id.exomedia_controls_title); subTitleTextView = (TextView) findViewById(R.id.exomedia_controls_sub_title); descriptionTextView = (TextView) findViewById(R.id.exomedia_controls_description); } ... //设置进度条 public abstract void setPosition(@IntRange(from = 0) long position); //设置总时长 public abstract void setDuration(@IntRange(from = 0) long duration); //更新进度 public abstract void updateProgress(@IntRange(from = 0) long position, @IntRange(from = 0) long duration, @IntRange(from = 0, to = 100) int bufferPercent); //反射播放控制器总体布局 @LayoutRes protected abstract int getLayoutResource(); ... }
VideoControlsMobile 默认播放器
布局文件
- exomedia_default_controls_mobile.xml
- 布局分为三部分:上方视频信息框,中间加载进度框,下方控制器(对应id:
exomedia_controls_text_container/exomedia_controls_video_loading/exomedia_controls_interactive_container
) - 默认播放器中视频信息框设置为不显示.
Java
继承VideoControls类,具体实现父类的虚拟方法.
public class VideoControlsMobile extends VideoControls { //进度条 protected SeekBar seekBar; //用户手动拖拽进度条 protected boolean userInteracting = false; //反射布局 @Override protected int getLayoutResource() { return R.layout.exomedia_default_controls_mobile; } @Override public void setPosition(@IntRange(from = 0L) long position) { //继承自VideoView : 当前视频时间 currentTimeTextView.setText(TimeFormatUtil.formatMs(position)); seekBar.setProgress((int) position); } @Override public void setDuration(@IntRange(from = 0L) long duration) { if (duration != seekBar.getMax()) { //继承自VideoView : 视频长度 endTimeTextView.setText(TimeFormatUtil.formatMs(duration)); seekBar.setMax((int) duration); } } @Override public void updateProgress(@IntRange(from = 0L) long position, @IntRange(from = 0L) long duration, @IntRange(from = 0L, to = 100L) int bufferPercent) { if (!userInteracting) { //设置seekbar的缓冲进度和真实进度的关系 seekBar.setSecondaryProgress((int) (seekBar.getMax() * ((float) bufferPercent / 100))); seekBar.setProgress((int) position); currentTimeTextView.setText(TimeFormatUtil.formatMs(position)); } } ...}
具体实现自行参考源码,这里不再赘述。
自定义播放器
Exomedia作为模块导入
github下载zip文件,把其中的library作为module导入工程即可.
布局文件
- 复制默认播放器布局文件
exomedia_default_controls_mobile.xml
文件并重命名. - 由于继承
VideoControls
类,基类中已经设置了对默认布局文件的引用,故不要删除已经存在的代码:不需要的按钮只需设置android:visibility="gone"
,要改变控件样式把原来id赋给新的控件即可。 具体代码请根据个人需求自行编写,下面举例说明:
<!--设置视频文字信息不可见--><LinearLayout android:id="@+id/exomedia_controls_text_container" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentTop="true" android:background="@drawable/exomedia_default_controls_text_background" android:orientation="vertical" android:paddingBottom="16dp" android:paddingLeft="16dp" android:paddingRight="16dp" android:paddingTop="16dp" android:visibility="gone"> <TextView android:id="@+id/exomedia_controls_title" android:layout_width="match_parent" android:layout_height="wrap_content" android:textColor="@android:color/white" android:textSize="16sp" android:textStyle="bold" tools:text="The Video Title"/> ... </LinearLayout><!--播放按钮位置调整,改变样式--> <RelativeLayout android:id="@+id/exomedia_controls_play_pause_btn_container" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:background="@drawable/shape_circle_enable_pausebtn"> <!--id不变--> <ImageButton android:id="@+id/exomedia_controls_play_pause_btn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@android:color/transparent" android:minHeight="@dimen/exomedia_min_button_height" android:minWidth="@dimen/exomedia_min_button_height" app:srcCompat="@drawable/exomedia_ic_play_arrow_white" tools:ignore="ContentDescription"/> </RelativeLayout>
- 背景黑色为了方便设计,真正使用时请去掉,否则会遮挡住视频播放。
Java
- 与默认播放器的实现方法一样,自定义
MyVideoControls extends VideoControls
,并让该类反射自定义的布局文件实现定制播放器的效果。 - 如果在自定义的布局文件中添加了控件,在此对其业务逻辑进行处理。
public class MyVideoControlsMobile extends VideoControls { //自己添加的开始/暂停按钮的容器 protected RelativeLayout pauseBtnContainer; //反射自己的布局 @Override protected int getLayoutResource() { return R.layout.my_exomedia_controls_mobile; } @Override protected void animateVisibility(boolean toVisible) { if (isVisible == toVisible) { return; } if (!hideEmptyTextContainer || !isTextContainerEmpty()) { textContainer.startAnimation(new TopViewHideShowAnimation(textContainer, toVisible, CONTROL_VISIBILITY_ANIMATION_LENGTH)); } if (!isLoading) { controlsContainer.startAnimation(new BottomViewHideShowAnimation(controlsContainer, toVisible, CONTROL_VISIBILITY_ANIMATION_LENGTH)); } //设置自定义的开始/暂停按钮的可见性 if (toVisible) { pauseBtnContainer.setVisibility(View.VISIBLE); } else { pauseBtnContainer.setVisibility(View.GONE); } isVisible = toVisible; onVisibilityChanged(); } @Override public void showLoading(boolean initialLoad) { if (isLoading) { return; } isLoading = true; loadingProgressBar.setVisibility(View.VISIBLE); if (initialLoad) { controlsContainer.setVisibility(View.GONE); //控制器不可见时,开始/暂停按钮也不可见 pauseBtnContainer.setVisibility(View.GONE); } else { //按钮不可以点击 pauseBtnContainer.setBackgroundResource(R.drawable.shape_circle_disable_pausebtn); playPauseButton.setEnabled(false); previousButton.setEnabled(false); nextButton.setEnabled(false); return; } show(); } @Override public void finishLoading() { if (!isLoading) { return; } isLoading = false; loadingProgressBar.setVisibility(View.GONE); //控制器可见时,开始/暂停按钮也可见 pauseBtnContainer.setVisibility(View.VISIBLE); controlsContainer.setVisibility(View.VISIBLE); playPauseButton.setEnabled(true); previousButton.setEnabled(enabledViews.get(com.devbrackets.android.exomedia.R.id.exomedia_controls_previous_btn, true)); nextButton.setEnabled(enabledViews.get(com.devbrackets.android.exomedia.R.id.exomedia_controls_next_btn, true)); pauseBtnContainer.setBackgroundResource(R.drawable.shape_circle_enable_pausebtn); updatePlaybackState(videoView != null && videoView.isPlaying()); } }
在此仅说明了定制播放器的流程,代码请根据具体业务需求自行实现。
深度定制
把Exomedia作为模组导入以后,直接修改与VideoControls相关的类和xml,以实现更加灵活、扩展性更好的自定义播放器。
其他
相关文章请点击下面链接:
- Exoplayer+Exomedia打造自定义播放器(一)
- Exoplayer+Exomedia之玩转视频播放事件监听
阅读全文
1 0
- Exoplayer+Exomedia打造自定义播放器(二)
- Exoplayer+Exomedia打造自定义视频播放器(一)
- Exoplayer+Exomedia之玩转视频播放事件监听
- Android视频播放器Exoplayer自定义
- 使用google开源框架Exoplayer开发自定义播放器
- 使用google开源框架Exoplayer开发自定义播放器
- 【翻译】安卓新播放器EXOplayer介绍
- ExoPlayer 播放器开发指南(译)
- ExoPlayer 播放器开发指南(译)
- ExoPlayer利用自定义DataSource实现直接播放AES加密音频
- HTML5+CSS3+JQuery打造自定义视频播放器
- 基于directShow,打造全能播放器系列之二
- 基于directShow,打造全能播放器系列之二
- 使用Vitamio库打造万能播放器(二)
- android 视频播放 Google exoplayer
- ExoPlayer
- ExoPlayer
- android ExoPlayer(可扩展的播放器)-GitHub开源项目(解决方案)
- hibernate中boolean的问题
- SharedPreferences和SQLite
- c/c++从编译到执行的过程
- Trie 树
- 计算两个整数的二进制中有几个二进制不同
- Exoplayer+Exomedia打造自定义播放器(二)
- Eclipse自动生成变量名声明(按方法返回值为本地变量赋值)
- R语言学习
- 搭建游戏服务器的问题笔记
- ActiveListManager API
- 一个故事教你看懂什么是数字证书,它的原理是什么?它的作用是什么?
- 【JavaWeb_Part08】白娘子你就算淹了这深圳,我他妈也要去玩我的 Spring
- 洛谷 马的遍历
- linux服务器上下载的csv文件在window环境下用excel打开的乱码问题解决