2017-05-11 4 views
0

J'utilise exoplayer afin de lire des vidéos HLS dans mon application. Le problème est que je reçois BehindLiveWindowException et j'ai trouvé une solution pour réinitialiser le lecteur si cette exception se produit. Mais de toute façon je ne peux pas attraper cette exception dans ma classe afin que je puisse réinitialiser le joueur. Au lieu de cela, je peux voir l'exception BLWE dans logcat, mais le redémarrage du lecteur ne se produit jamais.ExoPlayer - Impossible d'attraper BehindLiveWindowException

S'il vous plaît quelqu'un peut me dire ce que je fais mal, mon extrait de code est ici:

public class MainViewModel extends BaseObservable implements ExoPlayer.EventListener { 

private static final String MAIN_VIEWMODEL_TAG = "MAIN_VIEWMODEL"; 
private static MainViewModel mainViewModel; 
private final Context context; 
private final Realm realm; 
private LinearLayoutManager mLinearLayoutManager; 
private List<ChannelRCV> channelRCVList; 
private ChannelRecyclerViewAdapter recyclerViewAdapter; 
private ChannelRCV currentChannelRCV; 
private SimpleExoPlayer player; 
private Handler mainHandler; 
private BandwidthMeter bandwidthMeter; 
private TrackSelection.Factory videoTrackSelectionFactory; 
private TrackSelector trackSelector; 
private LoadControl loadControl; 
private DataSource.Factory dataSourceFactory; 
private MediaSource videoSource; 
private PlayerHelper playerHelper; 


//TODO CONSTRUCTOR MainViewModel 
private MainViewModel(Context context) { 
    this.context = context; 
    recyclerViewAdapter = new ChannelRecyclerViewAdapter(); 

    //channelRCVList = convertList(dbHelper.getWebTvChannelDao().loadAll()); 
    //currentChannelRCV = channelRCVList.get(0); 

    realm = Realm.getDefaultInstance(); 


    //Log.i(MAIN_VIEWMODEL_TAG, "DB IS EMPTY: "+ realm.isEmpty()); 
    channelRCVList = Converter.convertList(realm.where(WebTvChannel.class).findAll()); 

    ForTest forTest = new ForTest(); 

    forTest.test1(); 

    Log.i(MAIN_VIEWMODEL_TAG, channelRCVList.size() + ""); 
    currentChannelRCV = channelRCVList.get(0); 
    recyclerViewAdapter.setList(channelRCVList); 
    recyclerViewAdapter.notifyDataSetChanged(); 
    downloadEpgScheduler(); 

} 

public static MainViewModel getInstance(Context context) { 

    if (mainViewModel == null) { 
     mainViewModel = new MainViewModel(context); 
     mainViewModel.setupPlayer(); 
     return mainViewModel; 
    } else 
     return mainViewModel; 
} 

private static boolean isBehindLiveWindow(ExoPlaybackException e) { 
    if (e.type != ExoPlaybackException.TYPE_SOURCE) { 
     return false; 
    } 
    Throwable cause = e.getSourceException(); 
    while (cause != null) { 
     if (cause instanceof BehindLiveWindowException) { 
      return true; 
     } 
     cause = cause.getCause(); 
    } 
    return false; 
} 

private List<ChannelRCV> convertList(List<WebTvChannel> webTvChannels) { 
    List<ChannelRCV> channelRCVs = new ArrayList<>(); 
    for (WebTvChannel ch : webTvChannels) { 
     channelRCVs.add(new ChannelRCV(ch.getName(), ch.getUrl())); 
    } 

    return channelRCVs; 
} 

@Bindable 
public SimpleExoPlayer getPlayer() { 
    return player; 
} 

public void setPlayer(SimpleExoPlayer player) { 

    this.player = player; 

    notifyPropertyChanged(BR.player); 
} 

public void setupPlayer() { 
    //System.out.println(player); 
    if (player != null) { 

     //player.clearVideoSurface(); 

     player.release(); 

    } 

    mainHandler = new Handler(); 
    bandwidthMeter = new DefaultBandwidthMeter(); 

    videoTrackSelectionFactory = new AdaptiveTrackSelection.Factory(bandwidthMeter); 
    trackSelector = new DefaultTrackSelector(videoTrackSelectionFactory); 
    loadControl = new DefaultLoadControl(); 

    player = ExoPlayerFactory.newSimpleInstance(context, trackSelector, loadControl, null, SimpleExoPlayer.STATE_BUFFERING); 

    DefaultBandwidthMeter defaultBandwidthMeter = new DefaultBandwidthMeter(); 
    dataSourceFactory = new DefaultHttpDataSourceFactory(Util.getUserAgent(context, "AOC"), defaultBandwidthMeter); 
    videoSource = new HlsMediaSource(Uri.parse(currentChannelRCV.getUrl()), 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) { 
      Log.i(MAIN_VIEWMODEL_TAG,"onLoadStarted"); 
     } 

     @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) { 
      Log.i(MAIN_VIEWMODEL_TAG,"onLoadCompleted"); 
     } 

     @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) { 
      Log.i(MAIN_VIEWMODEL_TAG, "onLoadCanceled"); 
     } 

     @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) { 
      Log.i(MAIN_VIEWMODEL_TAG, "onLoadError2"); 
      player.release(); 
      setupPlayer(); 
     } 

     @Override 
     public void onUpstreamDiscarded(int trackType, long mediaStartTimeMs, long mediaEndTimeMs) { 
      Log.i(MAIN_VIEWMODEL_TAG, "onUpstreamDiscarded"); 
     } 

     @Override 
     public void onDownstreamFormatChanged(int trackType, Format trackFormat, int trackSelectionReason, Object trackSelectionData, long mediaTimeMs) { 
      Log.i(MAIN_VIEWMODEL_TAG, "onDownstreamFormatChanged"); 
     } 

    }); 

    player.prepare(videoSource); 

    player.setPlayWhenReady(true); 

    setPlayer(player); 


} 

public void changeChannel(ChannelRCV channelRCV) { 

    if (channelRCV.getUrl() == null) { 
     Toast.makeText(context, "No resoureces for this channel", Toast.LENGTH_SHORT).show(); 
     return; 
    } 

    videoSource = new HlsMediaSource(Uri.parse(currentChannelRCV.getUrl()), 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) { 
      Log.i(MAIN_VIEWMODEL_TAG,"onLoadStarted"); 
     } 

     @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) { 
      Log.i(MAIN_VIEWMODEL_TAG,"onLoadCompleted"); 
     } 

     @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) { 
      Log.i(MAIN_VIEWMODEL_TAG, "onLoadCanceled"); 
     } 

     @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) { 
      setupPlayer(); 
      Log.e("onLoadError", "ERROR 1"); 
      Log.e("onLoadError", error.toString()); 
      Log.i(MAIN_VIEWMODEL_TAG, "onLoadError1"); 

     } 

     @Override 
     public void onUpstreamDiscarded(int trackType, long mediaStartTimeMs, long mediaEndTimeMs) { 
      Log.i(MAIN_VIEWMODEL_TAG, "onDownstreamFormatChanged"); 

     } 

     @Override 
     public void onDownstreamFormatChanged(int trackType, Format trackFormat, int trackSelectionReason, Object trackSelectionData, long mediaTimeMs) { 
      Log.i(MAIN_VIEWMODEL_TAG, "onDownstreamFormatChanged"); 
     } 

    }); 
    player.prepare(videoSource); 
    player.setPlayWhenReady(true); 
    setPlayer(player); 

} 

public ChannelRecyclerViewAdapter getRecyclerViewAdapter() { 
    return recyclerViewAdapter; 
} 

public LinearLayoutManager getLinearLayoutManager() { 

    mLinearLayoutManager = new LinearLayoutManager(context); 
    mLinearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL); 
    mLinearLayoutManager.setSmoothScrollbarEnabled(true); 
    return mLinearLayoutManager; 
} 

public int fullscreen() { 
    return WindowManager.LayoutParams.FLAG_FULLSCREEN; 
} 

public void onClick(View view, ChannelRCV channelRCV) { 
    //view.setBackgroundColor(Color.parseColor("#FFFFFF")); 
    currentChannelRCV = channelRCV; 
    changeChannel(channelRCV); 
} 

// TODO Scheduler 
private void downloadEpgScheduler() { 

    ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor(); 

    scheduler.scheduleAtFixedRate(new Runnable() { 
     public void run() { 

      //code goes here 
      Log.i(MAIN_VIEWMODEL_TAG, "SCHEDULER STARTED"); 
      Intent download = new Intent(context, ScheduledDownloadEpgService.class); 
      download.putExtra("package", "AT - WebTV"); 
      // 
      // context.startService(download); 

     } 
    }, 0, 5, TimeUnit.MINUTES); 
} 

private void indirectChannelChange() { 
    changeChannel(currentChannelRCV); 
} 

public void updateRecyclerViewList(List<ChannelRCV> channelRCVs) { 

    channelRCVList = channelRCVs; 
    recyclerViewAdapter.setList(channelRCVs); 
    changeChannel(channelRCVs.get(0)); 
    recyclerViewAdapter.notifyDataSetChanged(); 
    player.release(); 
    setupPlayer(); 

} 

@Override 
public void onTimelineChanged(Timeline timeline, Object manifest) { 
    Log.e("onTimelineChanged", "onTimelineChanged"); 

} 

@Override 
public void onTracksChanged(TrackGroupArray trackGroups, TrackSelectionArray trackSelections) { 
    Log.e("onTracksChanged", "onTracksChanged"); 

} 

@Override 
public void onLoadingChanged(boolean isLoading) { 
    Log.i("onLoadingChanged", "Loading Changed"); 
} 

@Override 
public void onPlayerStateChanged(boolean playWhenReady, int playbackState) { 
    Log.i("onPlayerStateChanged", "Player State Changed"); 
} 

@Override 
public void onPlayerError(ExoPlaybackException error) { 
    //System.out.println("///////////////////////////////////////////////////////////////////// onPlayerError"); 
    Log.e("OnPlayerError", "Error ExoPlayer"); 
    if (isBehindLiveWindow(error)) { 
     Log.e("OnPlayerError", "starting again"); 

     player.release(); 
     setupPlayer(); 

     //changeChannel(currentChannelRCV); 
    } 
} 


@Override 
public void onPositionDiscontinuity() { 
    Log.i(MAIN_VIEWMODEL_TAG, "onPositionDiscontinuity"); 
} 

@Override 
public void onPlaybackParametersChanged(PlaybackParameters playbackParameters) { 
    Log.i("onPlaybackParamChanged", "Player State Changed"); 
} 

public void stopPlayer() { 
    player.stop(); 
    player.release(); 

} 

public void setVodUrl(String url) { 


}} 

Merci

Répondre

0

J'ai trouvé la solution! Au lieu de mettre en œuvre ExoPlayer.EventListener Je viens d'ajouter à l'auditeur d'objets exoPlayer comme suit:

exoPlayer.addListener(new ExoPlayer.EventListener() { 
      @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) { 

      } 

      @Override 
      public void onPlayerError(ExoPlaybackException error) { 
       Log.e(PLAYER_ACTIVITY_TAG, "SOME ERROR IN PLAYER"); 
       if (isBehindLiveWindow(error)) { 
        setupPlayer(); 
       } 
      } 

      @Override 
      public void onPositionDiscontinuity() { 

      } 

      @Override 
      public void onPlaybackParametersChanged(PlaybackParameters playbackParameters) { 

      } 
     }); 

et méthode isBehindLiveWindow

private static boolean isBehindLiveWindow(ExoPlaybackException e) { 
     if (e.type != ExoPlaybackException.TYPE_SOURCE) { 
      return false; 
     } 
     Throwable cause = e.getSourceException(); 
     while (cause != null) { 
      if (cause instanceof BehindLiveWindowException) { 
       return true; 
      } 
      cause = cause.getCause(); 
     } 
     return false; 
    } 

Maintenant, en cas d'erreur joueur redémarre automatiquement.