2017-02-14 308 views
3

我正在尋找好的和簡單的例子/說明如何實現ExoPlayerHLS Adaptive流。我是一個新手,沒有經驗和知識,所以我可以通過git上的代碼示例來了解如何做到這一點。Exoplayer自適應hls流

有太多'移動部件',所以初學者可以在自己的項目中理解和重用它。

有人可以幫助我學習和了解如何使用/實現ExoPlayer以實現此功能?

謝謝!

回答

5

開始使用ExoPlayer的最簡單方法是將其添加爲Gradle依賴項。你需要確保你有包含在你的項目的根目錄下的build.gradle文件jcenter庫:

​​

接下來,在您的模塊的build.gradle文件中的以下內容:

compile 'com.google.android.exoplayer:exoplayer:r2.2.0'

1.您的佈局文件

<?xml version="1.0" encoding="utf-8"?> 
<FrameLayout 
    android:id="@+id/activity_main" 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:app="http://schemas.android.com/apk/res-auto" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent"> 

    <com.google.android.exoplayer2.ui.SimpleExoPlayerView 
     android:id="@+id/player_view" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     android:focusable="true" 
     app:resize_mode="fill"/> 

    <ProgressBar 
     android:id="@+id/progressBar" 
     style="?android:attr/progressBarStyle" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_gravity="center" 
     android:visibility="gone"/> 

</FrameLayout> 

2.您的類文件(活動)

public class VideoPlayerActivity extends AppCompatActivity implements ExoPlayer.EventListener { 

    private SimpleExoPlayerView simpleExoPlayerView; 
    private String hlsVideoUri = "http://playertest.longtailvideo.com/adaptive/bbbfull/bbbfull.m3u8"; 
    private SimpleExoPlayer player; 
    private ProgressBar progressBar; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_video_player); 

     // 1. Create a default TrackSelector 
     Handler mainHandler = new Handler(); 
     BandwidthMeter bandwidthMeter = new DefaultBandwidthMeter(); 
     TrackSelection.Factory videoTrackSelectionFactory = new AdaptiveVideoTrackSelection.Factory(bandwidthMeter); 
     TrackSelector trackSelector = new DefaultTrackSelector(videoTrackSelectionFactory); 

     // 2. Create a default LoadControl 
     LoadControl loadControl = new DefaultLoadControl(); 


     // 3. Create the player 
     player = ExoPlayerFactory.newSimpleInstance(this, trackSelector, loadControl); 

     simpleExoPlayerView = (SimpleExoPlayerView) findViewById(R.id.player_view); 
     simpleExoPlayerView.setPlayer(player); 

     // Measures bandwidth during playback. Can be null if not required. 
     DefaultBandwidthMeter defaultBandwidthMeter = new DefaultBandwidthMeter(); 
     // Produces DataSource instances through which media data is loaded. 
     DataSource.Factory dataSourceFactory = new DefaultDataSourceFactory(this, 
       Util.getUserAgent(this, "Exo2"), defaultBandwidthMeter); 
     // Produces Extractor instances for parsing the media data. 
     ExtractorsFactory extractorsFactory = new DefaultExtractorsFactory(); 
     // This is the MediaSource representing the media to be played. 
     HlsMediaSource hlsMediaSource = new HlsMediaSource(Uri.parse(hlsVideoUri), dataSourceFactory, mainHandler, new AdaptiveMediaSourceEventListener() { 
      @Override 
      public void onLoadStarted(DataSpec dataSpec, int dataType, int trackType, Format trackFormat, int trackSelectionReason, Object trackSelectionData, long mediaStartTimeMs, long mediaEndTimeMs, long elapsedRealtimeMs) { 

      } 

      @Override 
      public void onLoadCompleted(DataSpec dataSpec, int dataType, int trackType, Format trackFormat, int trackSelectionReason, Object trackSelectionData, long mediaStartTimeMs, long mediaEndTimeMs, long elapsedRealtimeMs, long loadDurationMs, long bytesLoaded) { 

      } 

      @Override 
      public void onLoadCanceled(DataSpec dataSpec, int dataType, int trackType, Format trackFormat, int trackSelectionReason, Object trackSelectionData, long mediaStartTimeMs, long mediaEndTimeMs, long elapsedRealtimeMs, long loadDurationMs, long bytesLoaded) { 

      } 

      @Override 
      public void onLoadError(DataSpec dataSpec, int dataType, int trackType, Format trackFormat, int trackSelectionReason, Object trackSelectionData, long mediaStartTimeMs, long mediaEndTimeMs, long elapsedRealtimeMs, long loadDurationMs, long bytesLoaded, IOException error, boolean wasCanceled) { 

      } 

      @Override 
      public void onUpstreamDiscarded(int trackType, long mediaStartTimeMs, long mediaEndTimeMs) { 

      } 

      @Override 
      public void onDownstreamFormatChanged(int trackType, Format trackFormat, int trackSelectionReason, Object trackSelectionData, long mediaTimeMs) { 

      } 
     }); 

     player.addListener(this); 
     player.prepare(hlsMediaSource); 
     simpleExoPlayerView.requestFocus(); 
     player.setPlayWhenReady(true); 

     progressBar = (ProgressBar) findViewById(R.id.progressBar); 
    } 

    @Override 
    public void onTimelineChanged(Timeline timeline, Object manifest) { 

    } 

    @Override 
    public void onTracksChanged(TrackGroupArray trackGroups, TrackSelectionArray trackSelections) { 

    } 

    @Override 
    public void onLoadingChanged(boolean isLoading) { 

    } 

    @Override 
    public void onPlayerStateChanged(boolean playWhenReady, int playbackState) { 

     switch (playbackState) { 
      case ExoPlayer.STATE_BUFFERING: 
       //You can use progress dialog to show user that video is preparing or buffering so please wait 
       progressBar.setVisibility(View.VISIBLE); 
       break; 
      case ExoPlayer.STATE_IDLE: 
       //idle state 
       break; 
      case ExoPlayer.STATE_READY: 
       // dismiss your dialog here because our video is ready to play now 
       progressBar.setVisibility(View.GONE); 
       break; 
      case ExoPlayer.STATE_ENDED: 
       // do your processing after ending of video 
       break; 
     } 
    } 

    @Override 
    public void onPlayerError(ExoPlaybackException error) { 

     AlertDialog.Builder adb = new AlertDialog.Builder(VideoPlayerActivity.this); 
     adb.setTitle("Could not able to stream video"); 
     adb.setMessage("It seems that something is going wrong.\nPlease try again."); 
     adb.setPositiveButton("OK", new DialogInterface.OnClickListener() { 
      @Override 
      public void onClick(DialogInterface dialog, int which) { 
       dialog.dismiss(); 
       finish(); // take out user from this activity. you can skip this 
      } 
     }); 
     AlertDialog ad = adb.create(); 
     ad.show(); 
    } 

    @Override 
    public void onPositionDiscontinuity() { 

    } 

    @Override 
    protected void onPause() { 
     super.onPause(); 
     if (player != null) { 
      player.setPlayWhenReady(false); //to pause a video because now our video player is not in focus 
     } 
    } 

    @Override 
    protected void onDestroy() { 
     super.onDestroy(); 
     player.release(); 
    } 
} 

我認爲這是足以讓初學者。還要記住,該庫的標準音頻和視頻組件依賴於Android 4.1(API級別16)中發佈的Android MediaCodec API。所以它不適用於Android 4.0及以下版本。

不要忘了這個權限添加到manifest file

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

+0

謝謝玉萍!請告訴我們,視頻播放器是否會根據帶寬自動選擇視頻質量?我看到必須實施的方法,但我不明白我該如何使用它? 請隨身攜帶。謝謝:) – hogar

+2

Exoplayer會自動選擇帶寬上的視頻。你不必擔心這一點。 – Vicky

+0

非常感謝你!你救了我! – hogar