mirror of
https://github.com/samsonjs/media.git
synced 2026-04-27 15:07:40 +00:00
Move playback error into PlaybackInfo.
The error is closely related to the playback state IDLE and should be updated in sync with the state to prevent unexpected event ordering and/or keeping the error after re-preparation. Issue:#5407 PiperOrigin-RevId: 265014630
This commit is contained in:
parent
7883eabb38
commit
29af6899fe
5 changed files with 77 additions and 27 deletions
|
|
@ -74,7 +74,6 @@ import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
private int pendingSetPlaybackParametersAcks;
|
private int pendingSetPlaybackParametersAcks;
|
||||||
private PlaybackParameters playbackParameters;
|
private PlaybackParameters playbackParameters;
|
||||||
private SeekParameters seekParameters;
|
private SeekParameters seekParameters;
|
||||||
@Nullable private ExoPlaybackException playbackError;
|
|
||||||
|
|
||||||
// Playback information when there is no pending seek/set source operation.
|
// Playback information when there is no pending seek/set source operation.
|
||||||
private PlaybackInfo playbackInfo;
|
private PlaybackInfo playbackInfo;
|
||||||
|
|
@ -202,13 +201,12 @@ import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
@Override
|
@Override
|
||||||
@Nullable
|
@Nullable
|
||||||
public ExoPlaybackException getPlaybackError() {
|
public ExoPlaybackException getPlaybackError() {
|
||||||
return playbackError;
|
return playbackInfo.playbackError;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void retry() {
|
public void retry() {
|
||||||
if (mediaSource != null
|
if (mediaSource != null && playbackInfo.playbackState == Player.STATE_IDLE) {
|
||||||
&& (playbackError != null || playbackInfo.playbackState == Player.STATE_IDLE)) {
|
|
||||||
prepare(mediaSource, /* resetPosition= */ false, /* resetState= */ false);
|
prepare(mediaSource, /* resetPosition= */ false, /* resetState= */ false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -220,11 +218,13 @@ import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void prepare(MediaSource mediaSource, boolean resetPosition, boolean resetState) {
|
public void prepare(MediaSource mediaSource, boolean resetPosition, boolean resetState) {
|
||||||
playbackError = null;
|
|
||||||
this.mediaSource = mediaSource;
|
this.mediaSource = mediaSource;
|
||||||
PlaybackInfo playbackInfo =
|
PlaybackInfo playbackInfo =
|
||||||
getResetPlaybackInfo(
|
getResetPlaybackInfo(
|
||||||
resetPosition, resetState, /* playbackState= */ Player.STATE_BUFFERING);
|
resetPosition,
|
||||||
|
resetState,
|
||||||
|
/* resetError= */ true,
|
||||||
|
/* playbackState= */ Player.STATE_BUFFERING);
|
||||||
// Trigger internal prepare first before updating the playback info and notifying external
|
// Trigger internal prepare first before updating the playback info and notifying external
|
||||||
// listeners to ensure that new operations issued in the listener notifications reach the
|
// listeners to ensure that new operations issued in the listener notifications reach the
|
||||||
// player after this prepare. The internal player can't change the playback info immediately
|
// player after this prepare. The internal player can't change the playback info immediately
|
||||||
|
|
@ -381,13 +381,13 @@ import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
@Override
|
@Override
|
||||||
public void stop(boolean reset) {
|
public void stop(boolean reset) {
|
||||||
if (reset) {
|
if (reset) {
|
||||||
playbackError = null;
|
|
||||||
mediaSource = null;
|
mediaSource = null;
|
||||||
}
|
}
|
||||||
PlaybackInfo playbackInfo =
|
PlaybackInfo playbackInfo =
|
||||||
getResetPlaybackInfo(
|
getResetPlaybackInfo(
|
||||||
/* resetPosition= */ reset,
|
/* resetPosition= */ reset,
|
||||||
/* resetState= */ reset,
|
/* resetState= */ reset,
|
||||||
|
/* resetError= */ reset,
|
||||||
/* playbackState= */ Player.STATE_IDLE);
|
/* playbackState= */ Player.STATE_IDLE);
|
||||||
// Trigger internal stop first before updating the playback info and notifying external
|
// Trigger internal stop first before updating the playback info and notifying external
|
||||||
// listeners to ensure that new operations issued in the listener notifications reach the
|
// listeners to ensure that new operations issued in the listener notifications reach the
|
||||||
|
|
@ -415,6 +415,7 @@ import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
getResetPlaybackInfo(
|
getResetPlaybackInfo(
|
||||||
/* resetPosition= */ false,
|
/* resetPosition= */ false,
|
||||||
/* resetState= */ false,
|
/* resetState= */ false,
|
||||||
|
/* resetError= */ false,
|
||||||
/* playbackState= */ Player.STATE_IDLE);
|
/* playbackState= */ Player.STATE_IDLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -572,11 +573,6 @@ import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
case ExoPlayerImplInternal.MSG_PLAYBACK_PARAMETERS_CHANGED:
|
case ExoPlayerImplInternal.MSG_PLAYBACK_PARAMETERS_CHANGED:
|
||||||
handlePlaybackParameters((PlaybackParameters) msg.obj, /* operationAck= */ msg.arg1 != 0);
|
handlePlaybackParameters((PlaybackParameters) msg.obj, /* operationAck= */ msg.arg1 != 0);
|
||||||
break;
|
break;
|
||||||
case ExoPlayerImplInternal.MSG_ERROR:
|
|
||||||
ExoPlaybackException playbackError = (ExoPlaybackException) msg.obj;
|
|
||||||
this.playbackError = playbackError;
|
|
||||||
notifyListeners(listener -> listener.onPlayerError(playbackError));
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
throw new IllegalStateException();
|
throw new IllegalStateException();
|
||||||
}
|
}
|
||||||
|
|
@ -635,7 +631,10 @@ import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
}
|
}
|
||||||
|
|
||||||
private PlaybackInfo getResetPlaybackInfo(
|
private PlaybackInfo getResetPlaybackInfo(
|
||||||
boolean resetPosition, boolean resetState, @Player.State int playbackState) {
|
boolean resetPosition,
|
||||||
|
boolean resetState,
|
||||||
|
boolean resetError,
|
||||||
|
@Player.State int playbackState) {
|
||||||
if (resetPosition) {
|
if (resetPosition) {
|
||||||
maskingWindowIndex = 0;
|
maskingWindowIndex = 0;
|
||||||
maskingPeriodIndex = 0;
|
maskingPeriodIndex = 0;
|
||||||
|
|
@ -659,6 +658,7 @@ import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
startPositionUs,
|
startPositionUs,
|
||||||
contentPositionUs,
|
contentPositionUs,
|
||||||
playbackState,
|
playbackState,
|
||||||
|
resetError ? null : playbackInfo.playbackError,
|
||||||
/* isLoading= */ false,
|
/* isLoading= */ false,
|
||||||
resetState ? TrackGroupArray.EMPTY : playbackInfo.trackGroups,
|
resetState ? TrackGroupArray.EMPTY : playbackInfo.trackGroups,
|
||||||
resetState ? emptyTrackSelectorResult : playbackInfo.trackSelectorResult,
|
resetState ? emptyTrackSelectorResult : playbackInfo.trackSelectorResult,
|
||||||
|
|
@ -728,6 +728,7 @@ import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
private final @Player.TimelineChangeReason int timelineChangeReason;
|
private final @Player.TimelineChangeReason int timelineChangeReason;
|
||||||
private final boolean seekProcessed;
|
private final boolean seekProcessed;
|
||||||
private final boolean playbackStateChanged;
|
private final boolean playbackStateChanged;
|
||||||
|
private final boolean playbackErrorChanged;
|
||||||
private final boolean timelineChanged;
|
private final boolean timelineChanged;
|
||||||
private final boolean isLoadingChanged;
|
private final boolean isLoadingChanged;
|
||||||
private final boolean trackSelectorResultChanged;
|
private final boolean trackSelectorResultChanged;
|
||||||
|
|
@ -752,6 +753,9 @@ import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
this.seekProcessed = seekProcessed;
|
this.seekProcessed = seekProcessed;
|
||||||
this.playWhenReady = playWhenReady;
|
this.playWhenReady = playWhenReady;
|
||||||
playbackStateChanged = previousPlaybackInfo.playbackState != playbackInfo.playbackState;
|
playbackStateChanged = previousPlaybackInfo.playbackState != playbackInfo.playbackState;
|
||||||
|
playbackErrorChanged =
|
||||||
|
previousPlaybackInfo.playbackError != playbackInfo.playbackError
|
||||||
|
&& playbackInfo.playbackError != null;
|
||||||
timelineChanged = previousPlaybackInfo.timeline != playbackInfo.timeline;
|
timelineChanged = previousPlaybackInfo.timeline != playbackInfo.timeline;
|
||||||
isLoadingChanged = previousPlaybackInfo.isLoading != playbackInfo.isLoading;
|
isLoadingChanged = previousPlaybackInfo.isLoading != playbackInfo.isLoading;
|
||||||
trackSelectorResultChanged =
|
trackSelectorResultChanged =
|
||||||
|
|
@ -770,6 +774,9 @@ import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
listenerSnapshot,
|
listenerSnapshot,
|
||||||
listener -> listener.onPositionDiscontinuity(positionDiscontinuityReason));
|
listener -> listener.onPositionDiscontinuity(positionDiscontinuityReason));
|
||||||
}
|
}
|
||||||
|
if (playbackErrorChanged) {
|
||||||
|
invokeAll(listenerSnapshot, listener -> listener.onPlayerError(playbackInfo.playbackError));
|
||||||
|
}
|
||||||
if (trackSelectorResultChanged) {
|
if (trackSelectorResultChanged) {
|
||||||
trackSelector.onSelectionActivated(playbackInfo.trackSelectorResult.info);
|
trackSelector.onSelectionActivated(playbackInfo.trackSelectorResult.info);
|
||||||
invokeAll(
|
invokeAll(
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,6 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
// External messages
|
// External messages
|
||||||
public static final int MSG_PLAYBACK_INFO_CHANGED = 0;
|
public static final int MSG_PLAYBACK_INFO_CHANGED = 0;
|
||||||
public static final int MSG_PLAYBACK_PARAMETERS_CHANGED = 1;
|
public static final int MSG_PLAYBACK_PARAMETERS_CHANGED = 1;
|
||||||
public static final int MSG_ERROR = 2;
|
|
||||||
|
|
||||||
// Internal messages
|
// Internal messages
|
||||||
private static final int MSG_PREPARE = 0;
|
private static final int MSG_PREPARE = 0;
|
||||||
|
|
@ -374,19 +373,19 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
maybeNotifyPlaybackInfoChanged();
|
maybeNotifyPlaybackInfoChanged();
|
||||||
} catch (ExoPlaybackException e) {
|
} catch (ExoPlaybackException e) {
|
||||||
Log.e(TAG, "Playback error.", e);
|
Log.e(TAG, "Playback error.", e);
|
||||||
eventHandler.obtainMessage(MSG_ERROR, e).sendToTarget();
|
|
||||||
stopInternal(
|
stopInternal(
|
||||||
/* forceResetRenderers= */ true,
|
/* forceResetRenderers= */ true,
|
||||||
/* resetPositionAndState= */ false,
|
/* resetPositionAndState= */ false,
|
||||||
/* acknowledgeStop= */ false);
|
/* acknowledgeStop= */ false);
|
||||||
|
playbackInfo = playbackInfo.copyWithPlaybackError(e);
|
||||||
maybeNotifyPlaybackInfoChanged();
|
maybeNotifyPlaybackInfoChanged();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
Log.e(TAG, "Source error.", e);
|
Log.e(TAG, "Source error.", e);
|
||||||
eventHandler.obtainMessage(MSG_ERROR, ExoPlaybackException.createForSource(e)).sendToTarget();
|
|
||||||
stopInternal(
|
stopInternal(
|
||||||
/* forceResetRenderers= */ false,
|
/* forceResetRenderers= */ false,
|
||||||
/* resetPositionAndState= */ false,
|
/* resetPositionAndState= */ false,
|
||||||
/* acknowledgeStop= */ false);
|
/* acknowledgeStop= */ false);
|
||||||
|
playbackInfo = playbackInfo.copyWithPlaybackError(ExoPlaybackException.createForSource(e));
|
||||||
maybeNotifyPlaybackInfoChanged();
|
maybeNotifyPlaybackInfoChanged();
|
||||||
} catch (RuntimeException | OutOfMemoryError e) {
|
} catch (RuntimeException | OutOfMemoryError e) {
|
||||||
Log.e(TAG, "Internal runtime error.", e);
|
Log.e(TAG, "Internal runtime error.", e);
|
||||||
|
|
@ -394,11 +393,11 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
e instanceof OutOfMemoryError
|
e instanceof OutOfMemoryError
|
||||||
? ExoPlaybackException.createForOutOfMemoryError((OutOfMemoryError) e)
|
? ExoPlaybackException.createForOutOfMemoryError((OutOfMemoryError) e)
|
||||||
: ExoPlaybackException.createForUnexpected((RuntimeException) e);
|
: ExoPlaybackException.createForUnexpected((RuntimeException) e);
|
||||||
eventHandler.obtainMessage(MSG_ERROR, error).sendToTarget();
|
|
||||||
stopInternal(
|
stopInternal(
|
||||||
/* forceResetRenderers= */ true,
|
/* forceResetRenderers= */ true,
|
||||||
/* resetPositionAndState= */ false,
|
/* resetPositionAndState= */ false,
|
||||||
/* acknowledgeStop= */ false);
|
/* acknowledgeStop= */ false);
|
||||||
|
playbackInfo = playbackInfo.copyWithPlaybackError(error);
|
||||||
maybeNotifyPlaybackInfoChanged();
|
maybeNotifyPlaybackInfoChanged();
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -436,7 +435,11 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
private void prepareInternal(MediaSource mediaSource, boolean resetPosition, boolean resetState) {
|
private void prepareInternal(MediaSource mediaSource, boolean resetPosition, boolean resetState) {
|
||||||
pendingPrepareCount++;
|
pendingPrepareCount++;
|
||||||
resetInternal(
|
resetInternal(
|
||||||
/* resetRenderers= */ false, /* releaseMediaSource= */ true, resetPosition, resetState);
|
/* resetRenderers= */ false,
|
||||||
|
/* releaseMediaSource= */ true,
|
||||||
|
resetPosition,
|
||||||
|
resetState,
|
||||||
|
/* resetError= */ true);
|
||||||
loadControl.onPrepared();
|
loadControl.onPrepared();
|
||||||
this.mediaSource = mediaSource;
|
this.mediaSource = mediaSource;
|
||||||
setState(Player.STATE_BUFFERING);
|
setState(Player.STATE_BUFFERING);
|
||||||
|
|
@ -688,7 +691,8 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
/* resetRenderers= */ false,
|
/* resetRenderers= */ false,
|
||||||
/* releaseMediaSource= */ false,
|
/* releaseMediaSource= */ false,
|
||||||
/* resetPosition= */ true,
|
/* resetPosition= */ true,
|
||||||
/* resetState= */ false);
|
/* resetState= */ false,
|
||||||
|
/* resetError= */ true);
|
||||||
} else {
|
} else {
|
||||||
// Execute the seek in the current media periods.
|
// Execute the seek in the current media periods.
|
||||||
long newPeriodPositionUs = periodPositionUs;
|
long newPeriodPositionUs = periodPositionUs;
|
||||||
|
|
@ -834,7 +838,8 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
/* resetRenderers= */ forceResetRenderers || !foregroundMode,
|
/* resetRenderers= */ forceResetRenderers || !foregroundMode,
|
||||||
/* releaseMediaSource= */ true,
|
/* releaseMediaSource= */ true,
|
||||||
/* resetPosition= */ resetPositionAndState,
|
/* resetPosition= */ resetPositionAndState,
|
||||||
/* resetState= */ resetPositionAndState);
|
/* resetState= */ resetPositionAndState,
|
||||||
|
/* resetError= */ resetPositionAndState);
|
||||||
playbackInfoUpdate.incrementPendingOperationAcks(
|
playbackInfoUpdate.incrementPendingOperationAcks(
|
||||||
pendingPrepareCount + (acknowledgeStop ? 1 : 0));
|
pendingPrepareCount + (acknowledgeStop ? 1 : 0));
|
||||||
pendingPrepareCount = 0;
|
pendingPrepareCount = 0;
|
||||||
|
|
@ -847,7 +852,8 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
/* resetRenderers= */ true,
|
/* resetRenderers= */ true,
|
||||||
/* releaseMediaSource= */ true,
|
/* releaseMediaSource= */ true,
|
||||||
/* resetPosition= */ true,
|
/* resetPosition= */ true,
|
||||||
/* resetState= */ true);
|
/* resetState= */ true,
|
||||||
|
/* resetError= */ false);
|
||||||
loadControl.onReleased();
|
loadControl.onReleased();
|
||||||
setState(Player.STATE_IDLE);
|
setState(Player.STATE_IDLE);
|
||||||
internalPlaybackThread.quit();
|
internalPlaybackThread.quit();
|
||||||
|
|
@ -861,7 +867,8 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
boolean resetRenderers,
|
boolean resetRenderers,
|
||||||
boolean releaseMediaSource,
|
boolean releaseMediaSource,
|
||||||
boolean resetPosition,
|
boolean resetPosition,
|
||||||
boolean resetState) {
|
boolean resetState,
|
||||||
|
boolean resetError) {
|
||||||
handler.removeMessages(MSG_DO_SOME_WORK);
|
handler.removeMessages(MSG_DO_SOME_WORK);
|
||||||
rebuffering = false;
|
rebuffering = false;
|
||||||
mediaClock.stop();
|
mediaClock.stop();
|
||||||
|
|
@ -924,6 +931,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
startPositionUs,
|
startPositionUs,
|
||||||
contentPositionUs,
|
contentPositionUs,
|
||||||
playbackInfo.playbackState,
|
playbackInfo.playbackState,
|
||||||
|
resetError ? null : playbackInfo.playbackError,
|
||||||
/* isLoading= */ false,
|
/* isLoading= */ false,
|
||||||
resetState ? TrackGroupArray.EMPTY : playbackInfo.trackGroups,
|
resetState ? TrackGroupArray.EMPTY : playbackInfo.trackGroups,
|
||||||
resetState ? emptyTrackSelectorResult : playbackInfo.trackSelectorResult,
|
resetState ? emptyTrackSelectorResult : playbackInfo.trackSelectorResult,
|
||||||
|
|
@ -1382,7 +1390,8 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
/* resetRenderers= */ false,
|
/* resetRenderers= */ false,
|
||||||
/* releaseMediaSource= */ false,
|
/* releaseMediaSource= */ false,
|
||||||
/* resetPosition= */ true,
|
/* resetPosition= */ true,
|
||||||
/* resetState= */ false);
|
/* resetState= */ false,
|
||||||
|
/* resetError= */ true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@
|
||||||
package com.google.android.exoplayer2;
|
package com.google.android.exoplayer2;
|
||||||
|
|
||||||
import androidx.annotation.CheckResult;
|
import androidx.annotation.CheckResult;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
import com.google.android.exoplayer2.source.MediaSource.MediaPeriodId;
|
import com.google.android.exoplayer2.source.MediaSource.MediaPeriodId;
|
||||||
import com.google.android.exoplayer2.source.TrackGroupArray;
|
import com.google.android.exoplayer2.source.TrackGroupArray;
|
||||||
import com.google.android.exoplayer2.trackselection.TrackSelectorResult;
|
import com.google.android.exoplayer2.trackselection.TrackSelectorResult;
|
||||||
|
|
@ -51,6 +52,8 @@ import com.google.android.exoplayer2.trackselection.TrackSelectorResult;
|
||||||
public final long contentPositionUs;
|
public final long contentPositionUs;
|
||||||
/** The current playback state. One of the {@link Player}.STATE_ constants. */
|
/** The current playback state. One of the {@link Player}.STATE_ constants. */
|
||||||
@Player.State public final int playbackState;
|
@Player.State public final int playbackState;
|
||||||
|
/** The current playback error, or null if this is not an error state. */
|
||||||
|
@Nullable public final ExoPlaybackException playbackError;
|
||||||
/** Whether the player is currently loading. */
|
/** Whether the player is currently loading. */
|
||||||
public final boolean isLoading;
|
public final boolean isLoading;
|
||||||
/** The currently available track groups. */
|
/** The currently available track groups. */
|
||||||
|
|
@ -93,6 +96,7 @@ import com.google.android.exoplayer2.trackselection.TrackSelectorResult;
|
||||||
startPositionUs,
|
startPositionUs,
|
||||||
/* contentPositionUs= */ C.TIME_UNSET,
|
/* contentPositionUs= */ C.TIME_UNSET,
|
||||||
Player.STATE_IDLE,
|
Player.STATE_IDLE,
|
||||||
|
/* playbackError= */ null,
|
||||||
/* isLoading= */ false,
|
/* isLoading= */ false,
|
||||||
TrackGroupArray.EMPTY,
|
TrackGroupArray.EMPTY,
|
||||||
emptyTrackSelectorResult,
|
emptyTrackSelectorResult,
|
||||||
|
|
@ -124,6 +128,7 @@ import com.google.android.exoplayer2.trackselection.TrackSelectorResult;
|
||||||
long startPositionUs,
|
long startPositionUs,
|
||||||
long contentPositionUs,
|
long contentPositionUs,
|
||||||
@Player.State int playbackState,
|
@Player.State int playbackState,
|
||||||
|
@Nullable ExoPlaybackException playbackError,
|
||||||
boolean isLoading,
|
boolean isLoading,
|
||||||
TrackGroupArray trackGroups,
|
TrackGroupArray trackGroups,
|
||||||
TrackSelectorResult trackSelectorResult,
|
TrackSelectorResult trackSelectorResult,
|
||||||
|
|
@ -136,6 +141,7 @@ import com.google.android.exoplayer2.trackselection.TrackSelectorResult;
|
||||||
this.startPositionUs = startPositionUs;
|
this.startPositionUs = startPositionUs;
|
||||||
this.contentPositionUs = contentPositionUs;
|
this.contentPositionUs = contentPositionUs;
|
||||||
this.playbackState = playbackState;
|
this.playbackState = playbackState;
|
||||||
|
this.playbackError = playbackError;
|
||||||
this.isLoading = isLoading;
|
this.isLoading = isLoading;
|
||||||
this.trackGroups = trackGroups;
|
this.trackGroups = trackGroups;
|
||||||
this.trackSelectorResult = trackSelectorResult;
|
this.trackSelectorResult = trackSelectorResult;
|
||||||
|
|
@ -194,6 +200,7 @@ import com.google.android.exoplayer2.trackselection.TrackSelectorResult;
|
||||||
positionUs,
|
positionUs,
|
||||||
periodId.isAd() ? contentPositionUs : C.TIME_UNSET,
|
periodId.isAd() ? contentPositionUs : C.TIME_UNSET,
|
||||||
playbackState,
|
playbackState,
|
||||||
|
playbackError,
|
||||||
isLoading,
|
isLoading,
|
||||||
trackGroups,
|
trackGroups,
|
||||||
trackSelectorResult,
|
trackSelectorResult,
|
||||||
|
|
@ -217,6 +224,7 @@ import com.google.android.exoplayer2.trackselection.TrackSelectorResult;
|
||||||
startPositionUs,
|
startPositionUs,
|
||||||
contentPositionUs,
|
contentPositionUs,
|
||||||
playbackState,
|
playbackState,
|
||||||
|
playbackError,
|
||||||
isLoading,
|
isLoading,
|
||||||
trackGroups,
|
trackGroups,
|
||||||
trackSelectorResult,
|
trackSelectorResult,
|
||||||
|
|
@ -240,6 +248,31 @@ import com.google.android.exoplayer2.trackselection.TrackSelectorResult;
|
||||||
startPositionUs,
|
startPositionUs,
|
||||||
contentPositionUs,
|
contentPositionUs,
|
||||||
playbackState,
|
playbackState,
|
||||||
|
playbackError,
|
||||||
|
isLoading,
|
||||||
|
trackGroups,
|
||||||
|
trackSelectorResult,
|
||||||
|
loadingMediaPeriodId,
|
||||||
|
bufferedPositionUs,
|
||||||
|
totalBufferedDurationUs,
|
||||||
|
positionUs);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copies playback info with a playback error.
|
||||||
|
*
|
||||||
|
* @param playbackError The error. See {@link #playbackError}.
|
||||||
|
* @return Copied playback info with the playback error.
|
||||||
|
*/
|
||||||
|
@CheckResult
|
||||||
|
public PlaybackInfo copyWithPlaybackError(@Nullable ExoPlaybackException playbackError) {
|
||||||
|
return new PlaybackInfo(
|
||||||
|
timeline,
|
||||||
|
periodId,
|
||||||
|
startPositionUs,
|
||||||
|
contentPositionUs,
|
||||||
|
playbackState,
|
||||||
|
playbackError,
|
||||||
isLoading,
|
isLoading,
|
||||||
trackGroups,
|
trackGroups,
|
||||||
trackSelectorResult,
|
trackSelectorResult,
|
||||||
|
|
@ -263,6 +296,7 @@ import com.google.android.exoplayer2.trackselection.TrackSelectorResult;
|
||||||
startPositionUs,
|
startPositionUs,
|
||||||
contentPositionUs,
|
contentPositionUs,
|
||||||
playbackState,
|
playbackState,
|
||||||
|
playbackError,
|
||||||
isLoading,
|
isLoading,
|
||||||
trackGroups,
|
trackGroups,
|
||||||
trackSelectorResult,
|
trackSelectorResult,
|
||||||
|
|
@ -288,6 +322,7 @@ import com.google.android.exoplayer2.trackselection.TrackSelectorResult;
|
||||||
startPositionUs,
|
startPositionUs,
|
||||||
contentPositionUs,
|
contentPositionUs,
|
||||||
playbackState,
|
playbackState,
|
||||||
|
playbackError,
|
||||||
isLoading,
|
isLoading,
|
||||||
trackGroups,
|
trackGroups,
|
||||||
trackSelectorResult,
|
trackSelectorResult,
|
||||||
|
|
@ -311,6 +346,7 @@ import com.google.android.exoplayer2.trackselection.TrackSelectorResult;
|
||||||
startPositionUs,
|
startPositionUs,
|
||||||
contentPositionUs,
|
contentPositionUs,
|
||||||
playbackState,
|
playbackState,
|
||||||
|
playbackError,
|
||||||
isLoading,
|
isLoading,
|
||||||
trackGroups,
|
trackGroups,
|
||||||
trackSelectorResult,
|
trackSelectorResult,
|
||||||
|
|
|
||||||
|
|
@ -465,10 +465,7 @@ public class AnalyticsCollector
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final void onPlayerError(ExoPlaybackException error) {
|
public final void onPlayerError(ExoPlaybackException error) {
|
||||||
EventTime eventTime =
|
EventTime eventTime = generateLastReportedPlayingMediaPeriodEventTime();
|
||||||
error.type == ExoPlaybackException.TYPE_SOURCE
|
|
||||||
? generateLoadingMediaPeriodEventTime()
|
|
||||||
: generatePlayingMediaPeriodEventTime();
|
|
||||||
for (AnalyticsListener listener : listeners) {
|
for (AnalyticsListener listener : listeners) {
|
||||||
listener.onPlayerError(eventTime, error);
|
listener.onPlayerError(eventTime, error);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -359,6 +359,7 @@ public final class MediaPeriodQueueTest {
|
||||||
/* startPositionUs= */ 0,
|
/* startPositionUs= */ 0,
|
||||||
/* contentPositionUs= */ 0,
|
/* contentPositionUs= */ 0,
|
||||||
Player.STATE_READY,
|
Player.STATE_READY,
|
||||||
|
/* playbackError= */ null,
|
||||||
/* isLoading= */ false,
|
/* isLoading= */ false,
|
||||||
/* trackGroups= */ null,
|
/* trackGroups= */ null,
|
||||||
/* trackSelectorResult= */ null,
|
/* trackSelectorResult= */ null,
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue