转载自:https://blog.csdn.net/xunshishi/article/details/74171321
写在前面的话
- 对App视频播放模块进行扩展,需要自定义播放器的样式、监听视频播放过程中各种事件(播放开始、暂停、重新播放、结束、拖拽进度条、横竖屏切换等)、横竖屏切换、手动控制播放进度等。
- 自定义功能性、扩展性较好的视频播放模块。初次技术选型时利用github上比较流行的JieCaoVideoPlayer进行二次开发,基本实现了功能需求,但缺点也比较明显:1.机型及视频兼容性差,2.扩展性不佳,3.bug较多,故放弃之。
- 最后选用Google"亲儿子"视频播放框架Exoplayer,配合第三方库Exomedia进行扩展开发,完全实现了项目需求,并达到了较好的兼容性及播放效果。
相关链接
exoplayer
- exoplayer https://github.com/google/ExoPlayer
- exoplayer 官方开发指导 https://google.github.io/ExoPlayer/guide.html
- exoplayer 文档 http://google.github.io/ExoPlayer/doc/reference/
exomedia
- exomedia https://github.com/brianwernick/ExoMedia
- exomedia 文档 https://devbrackets.com/dev/libs/docs/exomedia/4.0.0/index.html
基本使用
添加依赖
-
compile 'com.google.android.exoplayer:exoplayer:r2.4.1'
-
compile 'com.devbrackets.android:exomedia:4.0.2'
AndroidManifest
- 权限 联网/更改设置
-
<uses-permission android:name="android.permission.INTERNET"/>
-
<uses-permission android:name="android.permission.CHANGE_CONFIGURATION"/>
- Activity 横竖屏切换/默认竖屏
-
<activity
-
android:name=".ui.activity.XunshiVideoDemoActivity"
-
android:configChanges="orientation|screenSize|keyboardHidden"
-
android:screenOrientation="portrait">
-
</activity>
XML
-
<?xml version="1.0" encoding="utf-8"?>
-
<RelativeLayout
-
xmlns:android="http://schemas.android.com/apk/res/android"
-
xmlns:app="http://schemas.android.com/apk/res-auto"
-
xmlns:tools="http://schemas.android.com/tools"
-
android:layout_width="match_parent"
-
android:layout_height="match_parent">
-
<!--exomedia-->
-
<com.devbrackets.android.exomedia.ui.widget.VideoView
-
android:id="@+id/exomedia_videoview"
-
android:layout_width="match_parent"
-
android:layout_height="match_parent"
-
android:background="@color/black"
-
app:useDefaultControls="true"/>
-
</RelativeLayout>
Java
Application级
-
兼容性问题解决
从github下载Exoplayer-release.zip,将extensions中的okhttp扩展文件夹中的OkHttpDataSourse.java和OkHttpDataSourceFactory.java文件考入自己的工程中. -
自定义Application继承父类,调用兼容性解决方法.
-
public class XunshiVideoDemoApplication extends Application {
-
@Override
-
public void onCreate() {
-
super.onCreate();
-
//兼容性配置
-
configureExoMedia();
-
}
-
/**
-
* 机型适配
-
*/
-
private void configureExoMedia() {
-
// 把MediaSources注册使用Okhttp客户端,而不是apache标准
-
// OkHttpDataSourceFactory指的是---->Exoplayer扩展库的`extension-okhttp`
-
ExoMedia.setHttpDataSourceFactoryProvider(new ExoMedia.HttpDataSourceFactoryProvider() {
-
@NonNull
-
@Override
-
public HttpDataSource.BaseFactory provide(@NonNull String userAgent, @Nullable TransferListener<? super DataSource> listener) {
-
return new OkHttpDataSourceFactory(new OkHttpClient(), userAgent, listener);
-
}
-
});
-
}
-
}
- 配置完毕后解决大多数机型兼容性问题.
Activity级
- 注意VideoView导包
import com.devbrackets.android.exomedia.ui.widget.VideoView;
- 调用
-
public class XunshiVideoDemoActivity extends AppCompatActivity {
-
@Override
-
protected void onCreate(Bundle savedInstanceState) {
-
super.onCreate(savedInstanceState);
-
//声明VideoView
-
VideoView mVideoView;
-
//反射
-
mVideoView = (VideoView) findViewById(R.id.exomedia_videoview);
-
//设置播放路径
-
mVideoView.setVideoURI(Uri.parse("http://www.asdfzxcv.cn/demovideo.mp4"));
-
//开始播放
-
mVideoView.start();
-
}
-
}
此时已经可以加载并观看视频了.
- 横竖屏切换
- 声明一个Button用于横竖屏切换
Button btnOrient;
- 在Activity的回调函数onConfigurationChanged()中配置横竖屏切换.
-
@Override
-
public void onConfigurationChanged(Configuration newConfig) {
-
if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
-
//切换到了横屏
-
//按钮的图标变化
-
btnOrient.setBackground(getResources().getDrawable(R.drawable.fullscreen_exit));
-
} else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
-
//切换到了竖屏
-
//按钮的图标变化
-
btnOrient.setBackground(getResources().getDrawable(R.drawable.fullscreen));
-
}
-
super.onConfigurationChanged(newConfig);
-
}
生命周期相关
- 播放器声明周期
- 开始播放
void mVideoView.start();
- 重新播放(不释放资源)
void mVideoView.restart();
- 暂停播放(不释放资源)
void mVideoView.pause();
- 销毁
void mVideoView.release();
- 是否正在播放中
boolean mVideoView.isPlaying();
- 与Activity生命周期配合使用
-
boolean pausedInOnStop = false;
-
@Override
-
protected void onStart() {
-
super.onStart();
-
if (mVideoView != null) {
-
if (pausedInOnStop) {
-
mVideoView.start();
-
pausedInOnStop = false;
-
}
-
}
-
}
-
@Override
-
protected void onStop() {
-
super.onStop();
-
if (mVideoView != null) {
-
if (mVideoView.isPlaying()) {
-
pausedInOnStop = true;
-
mVideoView.pause();
-
}
-
}
-
}
-
@Override
-
protected void onDestroy() {
-
super.onDestroy();
-
if (mVideoView != null) {
-
mVideoView.release();
-
}
-
}