Ich verwende Exoplayer, um HLS-Video in meiner App zu spielen. Das Problem ist, dass ich BehindLiveWindowException bekomme und ich eine Lösung gefunden habe, Spieler neu zu initialisieren, wenn diese Ausnahme auftritt. Aber irgendwie kann ich diese Ausnahme in meiner Klasse nicht verstehen, damit ich den Player reinitialisieren kann.ExoPlayer - Kann nicht fangen BehindLiveWindowException
Stattdessen kann ich BLWE Ausnahme in Logcat sehen, aber ein Neustart des Players tritt nie auf.
Bitte kann mir jemand sagen, was mache ich falsch, ist mein Code-Schnipsel hier:
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) {
}}
Dank