Exoplayer+Exomedia打造自定義視訊播放器
寫在前面的話
- 對App視訊播放模組進行擴充套件,需要自定義播放器的樣式、監聽視訊播放過程中各種事件(播放開始、暫停、重新播放、結束、拖拽進度條、橫豎屏切換等)、橫豎屏切換、手動控制播放進度等。
- 自定義功能性、擴充套件性較好的視訊播放模組。初次技術選型時利用github上比較流行的JieCaoVideoPlayer進行二次開發,基本實現了功能需求,但缺點也比較明顯:1.機型及視訊相容性差,2.擴充套件性不佳,3.bug較多,故放棄之。
- 最後選用Google"親兒子"視訊播放框架Exoplayer,配合第三方庫Exomedia進行擴充套件開發,完全實現了專案需求,並達到了較好的相容性及播放效果。
相關連結
exoplayer
exomedia
基本使用
新增依賴
-
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();
-
}
-
}