1. 程式人生 > >Exoplayer+Exomedia打造自定義視訊播放器

Exoplayer+Exomedia打造自定義視訊播放器

寫在前面的話

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

相關連結

exoplayer

exomedia

基本使用

新增依賴

  1. compile 'com.google.android.exoplayer:exoplayer:r2.4.1'

  2. compile 'com.devbrackets.android:exomedia:4.0.2'

AndroidManifest

  1. 許可權 聯網/更改設定
  1. <uses-permission android:name="android.permission.INTERNET"/>

  2. <uses-permission android:name="android.permission.CHANGE_CONFIGURATION"/>

  1. Activity 橫豎屏切換/預設豎屏
  1. <activity

  2. android:name=".ui.activity.XunshiVideoDemoActivity"

  3. android:configChanges="orientation|screenSize|keyboardHidden"

  4. android:screenOrientation="portrait">

  5. </activity>

XML

  1. <?xml version="1.0" encoding="utf-8"?>

  2. <RelativeLayout

  3. xmlns:android="http://schemas.android.com/apk/res/android"

  4. xmlns:app="http://schemas.android.com/apk/res-auto"

  5. xmlns:tools="http://schemas.android.com/tools"

  6. android:layout_width="match_parent"

  7. android:layout_height="match_parent">

  8. <!--exomedia-->

  9. <com.devbrackets.android.exomedia.ui.widget.VideoView

  10. android:id="@+id/exomedia_videoview"

  11. android:layout_width="match_parent"

  12. android:layout_height="match_parent"

  13. android:background="@color/black"

  14. app:useDefaultControls="true"/>

  15. </RelativeLayout>

Java

Application級

  1. 相容性問題解決
    從github下載Exoplayer-release.zip,將extensions中的okhttp擴充套件資料夾中的OkHttpDataSourse.java和OkHttpDataSourceFactory.java檔案考入自己的工程中.

  2. 自定義Application繼承父類,呼叫相容性解決方法.

  1. public class XunshiVideoDemoApplication extends Application {

  2. @Override

  3. public void onCreate() {

  4. super.onCreate();

  5. //相容性配置

  6. configureExoMedia();

  7. }

  8. /**

  9. * 機型適配

  10. */

  11. private void configureExoMedia() {

  12. // 把MediaSources註冊使用Okhttp客戶端,而不是apache標準

  13. // OkHttpDataSourceFactory指的是---->Exoplayer擴充套件庫的`extension-okhttp`

  14. ExoMedia.setHttpDataSourceFactoryProvider(new ExoMedia.HttpDataSourceFactoryProvider() {

  15. @NonNull

  16. @Override

  17. public HttpDataSource.BaseFactory provide(@NonNull String userAgent, @Nullable TransferListener<? super DataSource> listener) {

  18. return new OkHttpDataSourceFactory(new OkHttpClient(), userAgent, listener);

  19. }

  20. });

  21. }

  22. }

  1. 配置完畢後解決大多數機型相容性問題.

Activity級

  1. 注意VideoView導包
import com.devbrackets.android.exomedia.ui.widget.VideoView;
  1. 呼叫
  1. public class XunshiVideoDemoActivity extends AppCompatActivity {

  2. @Override

  3. protected void onCreate(Bundle savedInstanceState) {

  4. super.onCreate(savedInstanceState);

  5. //宣告VideoView

  6. VideoView mVideoView;

  7. //反射

  8. mVideoView = (VideoView) findViewById(R.id.exomedia_videoview);

  9. //設定播放路徑

  10. mVideoView.setVideoURI(Uri.parse("http://www.asdfzxcv.cn/demovideo.mp4"));

  11. //開始播放

  12. mVideoView.start();

  13. }

  14. }

此時已經可以載入並觀看視訊了.

  1. 橫豎屏切換
  • 宣告一個Button用於橫豎屏切換
Button btnOrient;
  • 在Activity的回撥函式onConfigurationChanged()中配置橫豎屏切換.
  1. @Override

  2. public void onConfigurationChanged(Configuration newConfig) {

  3. if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {

  4. //切換到了橫屏

  5. //按鈕的圖示變化

  6. btnOrient.setBackground(getResources().getDrawable(R.drawable.fullscreen_exit));

  7. } else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {

  8. //切換到了豎屏

  9. //按鈕的圖示變化

  10. btnOrient.setBackground(getResources().getDrawable(R.drawable.fullscreen));

  11. }

  12. super.onConfigurationChanged(newConfig);

  13. }

生命週期相關

  1. 播放器宣告週期
  • 開始播放
void mVideoView.start();
  • 重新播放(不釋放資源)
void mVideoView.restart();
  • 暫停播放(不釋放資源)
void mVideoView.pause();
  • 銷燬
void mVideoView.release();
  • 是否正在播放中
boolean mVideoView.isPlaying();
  1. 與Activity生命週期配合使用
  1. boolean pausedInOnStop = false;

  2. @Override

  3. protected void onStart() {

  4. super.onStart();

  5. if (mVideoView != null) {

  6. if (pausedInOnStop) {

  7. mVideoView.start();

  8. pausedInOnStop = false;

  9. }

  10. }

  11. }

  12. @Override

  13. protected void onStop() {

  14. super.onStop();

  15. if (mVideoView != null) {

  16. if (mVideoView.isPlaying()) {

  17. pausedInOnStop = true;

  18. mVideoView.pause();

  19. }

  20. }

  21. }

  22. @Override

  23. protected void onDestroy() {

  24. super.onDestroy();

  25. if (mVideoView != null) {

  26. mVideoView.release();

  27. }

  28. }