mirror of
https://github.com/TeamNewPipe/NewPipe
synced 2024-12-23 00:20:32 +00:00
updated: onPlayerError to not catch unspecified source errors so notifications are created.
updated: Throwable usage to Exceptions. updated: minor styles and documentations.
This commit is contained in:
parent
b81eb35f3d
commit
d289dc8a53
@ -1961,13 +1961,12 @@ public final class Player implements
|
|||||||
final boolean showPrev = playQueue.getIndex() != 0;
|
final boolean showPrev = playQueue.getIndex() != 0;
|
||||||
final boolean showNext = playQueue.getIndex() + 1 != playQueue.getStreams().size();
|
final boolean showNext = playQueue.getIndex() + 1 != playQueue.getStreams().size();
|
||||||
final boolean showQueue = playQueue.getStreams().size() > 1 && !popupPlayerSelected();
|
final boolean showQueue = playQueue.getStreams().size() > 1 && !popupPlayerSelected();
|
||||||
boolean showSegment = false;
|
/* only when stream has segments and is not playing in popup player */
|
||||||
showSegment = /*only when stream has segment and playing in fullscreen player*/
|
final boolean showSegment = !popupPlayerSelected()
|
||||||
!popupPlayerSelected()
|
&& !getCurrentStreamInfo()
|
||||||
&& !getCurrentStreamInfo()
|
.map(StreamInfo::getStreamSegments)
|
||||||
.map(StreamInfo::getStreamSegments)
|
.map(List::isEmpty)
|
||||||
.map(List::isEmpty)
|
.orElse(/*no stream info=*/true);
|
||||||
.orElse(/*no stream info=*/true);
|
|
||||||
|
|
||||||
binding.playPreviousButton.setVisibility(showPrev ? View.VISIBLE : View.INVISIBLE);
|
binding.playPreviousButton.setVisibility(showPrev ? View.VISIBLE : View.INVISIBLE);
|
||||||
binding.playPreviousButton.setAlpha(showPrev ? 1.0f : 0.0f);
|
binding.playPreviousButton.setAlpha(showPrev ? 1.0f : 0.0f);
|
||||||
@ -2014,7 +2013,7 @@ public final class Player implements
|
|||||||
+ "playWhenReady = [" + playWhenReady + "], "
|
+ "playWhenReady = [" + playWhenReady + "], "
|
||||||
+ "reason = [" + reason + "]");
|
+ "reason = [" + reason + "]");
|
||||||
}
|
}
|
||||||
final int playbackState = simpleExoPlayer == null
|
final int playbackState = exoPlayerIsNull()
|
||||||
? com.google.android.exoplayer2.Player.STATE_IDLE
|
? com.google.android.exoplayer2.Player.STATE_IDLE
|
||||||
: simpleExoPlayer.getPlaybackState();
|
: simpleExoPlayer.getPlaybackState();
|
||||||
updatePlaybackState(playWhenReady, playbackState);
|
updatePlaybackState(playWhenReady, playbackState);
|
||||||
@ -2026,8 +2025,7 @@ public final class Player implements
|
|||||||
Log.d(TAG, "ExoPlayer - onPlaybackStateChanged() called with: "
|
Log.d(TAG, "ExoPlayer - onPlaybackStateChanged() called with: "
|
||||||
+ "playbackState = [" + playbackState + "]");
|
+ "playbackState = [" + playbackState + "]");
|
||||||
}
|
}
|
||||||
final boolean playWhenReady = simpleExoPlayer != null && simpleExoPlayer.getPlayWhenReady();
|
updatePlaybackState(getPlayWhenReady(), playbackState);
|
||||||
updatePlaybackState(playWhenReady, playbackState);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updatePlaybackState(final boolean playWhenReady, final int playbackState) {
|
private void updatePlaybackState(final boolean playWhenReady, final int playbackState) {
|
||||||
@ -2486,6 +2484,19 @@ public final class Player implements
|
|||||||
//////////////////////////////////////////////////////////////////////////*/
|
//////////////////////////////////////////////////////////////////////////*/
|
||||||
//region ExoPlayer listeners (that didn't fit in other categories)
|
//region ExoPlayer listeners (that didn't fit in other categories)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>Listens for event or state changes on ExoPlayer. When any event happens, we check for
|
||||||
|
* changes in the currently-playing metadata and update the encapsulating
|
||||||
|
* {@link Player}. Downstream listeners are also informed.
|
||||||
|
*
|
||||||
|
* <p>When the renewed metadata contains any error, it is reported as a notification.
|
||||||
|
* This is done because not all source resolution errors are {@link PlaybackException}, which
|
||||||
|
* are also captured by {@link ExoPlayer} and stops the playback.
|
||||||
|
*
|
||||||
|
* @param player The {@link com.google.android.exoplayer2.Player} whose state changed.
|
||||||
|
* @param events The {@link com.google.android.exoplayer2.Player.Events} that has triggered
|
||||||
|
* the player state changes.
|
||||||
|
**/
|
||||||
@Override
|
@Override
|
||||||
public void onEvents(@NonNull final com.google.android.exoplayer2.Player player,
|
public void onEvents(@NonNull final com.google.android.exoplayer2.Player player,
|
||||||
@NonNull final com.google.android.exoplayer2.Player.Events events) {
|
@NonNull final com.google.android.exoplayer2.Player.Events events) {
|
||||||
@ -2602,11 +2613,12 @@ public final class Player implements
|
|||||||
* <li>{@link PlaybackException#ERROR_CODE_BEHIND_LIVE_WINDOW BEHIND_LIVE_WINDOW}:
|
* <li>{@link PlaybackException#ERROR_CODE_BEHIND_LIVE_WINDOW BEHIND_LIVE_WINDOW}:
|
||||||
* If the playback on livestreams are lagged too far behind the current playable
|
* If the playback on livestreams are lagged too far behind the current playable
|
||||||
* window. Then we seek to the latest timestamp and restart the playback.
|
* window. Then we seek to the latest timestamp and restart the playback.
|
||||||
|
* This error is <b>catchable</b>.
|
||||||
* </li>
|
* </li>
|
||||||
* <li>From {@link PlaybackException#ERROR_CODE_IO_INVALID_HTTP_CONTENT_TYPE BAD_IO} to
|
* <li>From {@link PlaybackException#ERROR_CODE_IO_INVALID_HTTP_CONTENT_TYPE BAD_IO} to
|
||||||
* {@link PlaybackException#ERROR_CODE_PARSING_MANIFEST_UNSUPPORTED UNSUPPORTED_FORMATS}:
|
* {@link PlaybackException#ERROR_CODE_PARSING_MANIFEST_UNSUPPORTED UNSUPPORTED_FORMATS}:
|
||||||
* If the stream source is validated by the extractor but not recognized by the player,
|
* If the stream source is validated by the extractor but not recognized by the player,
|
||||||
* then we can try to recover playback by signal an error on the {@link PlayQueue}.</li>
|
* then we can try to recover playback by signalling an error on the {@link PlayQueue}.</li>
|
||||||
* <li>For {@link PlaybackException#ERROR_CODE_TIMEOUT PLAYER_TIMEOUT},
|
* <li>For {@link PlaybackException#ERROR_CODE_TIMEOUT PLAYER_TIMEOUT},
|
||||||
* {@link PlaybackException#ERROR_CODE_IO_UNSPECIFIED MEDIA_SOURCE_RESOLVER_TIMEOUT} and
|
* {@link PlaybackException#ERROR_CODE_IO_UNSPECIFIED MEDIA_SOURCE_RESOLVER_TIMEOUT} and
|
||||||
* {@link PlaybackException#ERROR_CODE_IO_NETWORK_CONNECTION_FAILED NO_NETWORK}:
|
* {@link PlaybackException#ERROR_CODE_IO_NETWORK_CONNECTION_FAILED NO_NETWORK}:
|
||||||
@ -2617,8 +2629,8 @@ public final class Player implements
|
|||||||
* We terminate the playback.</li>
|
* We terminate the playback.</li>
|
||||||
* <li>For any other unspecified issue internal: We set a recovery and try to restart
|
* <li>For any other unspecified issue internal: We set a recovery and try to restart
|
||||||
* the playback.</li>
|
* the playback.</li>
|
||||||
* In the case of decoder/renderer or unspecified errors, the player will create a
|
* For any error above that is <b>not</b> explicitly <b>catchable</b>, the player will
|
||||||
* notification so the users are aware.
|
* create a notification so users are aware.
|
||||||
* </ul>
|
* </ul>
|
||||||
* @see com.google.android.exoplayer2.Player.Listener#onPlayerError(PlaybackException)
|
* @see com.google.android.exoplayer2.Player.Listener#onPlayerError(PlaybackException)
|
||||||
* */
|
* */
|
||||||
@ -2627,7 +2639,6 @@ public final class Player implements
|
|||||||
public void onPlayerError(@NonNull final PlaybackException error) {
|
public void onPlayerError(@NonNull final PlaybackException error) {
|
||||||
Log.e(TAG, "ExoPlayer - onPlayerError() called with:", error);
|
Log.e(TAG, "ExoPlayer - onPlayerError() called with:", error);
|
||||||
|
|
||||||
setRecovery();
|
|
||||||
saveStreamProgressState();
|
saveStreamProgressState();
|
||||||
boolean isCatchableException = false;
|
boolean isCatchableException = false;
|
||||||
|
|
||||||
@ -2652,7 +2663,6 @@ public final class Player implements
|
|||||||
case ERROR_CODE_PARSING_MANIFEST_UNSUPPORTED:
|
case ERROR_CODE_PARSING_MANIFEST_UNSUPPORTED:
|
||||||
// Source errors, signal on playQueue and move on:
|
// Source errors, signal on playQueue and move on:
|
||||||
if (!exoPlayerIsNull() && playQueue != null) {
|
if (!exoPlayerIsNull() && playQueue != null) {
|
||||||
isCatchableException = true;
|
|
||||||
playQueue.error();
|
playQueue.error();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -2660,11 +2670,6 @@ public final class Player implements
|
|||||||
case ERROR_CODE_IO_UNSPECIFIED:
|
case ERROR_CODE_IO_UNSPECIFIED:
|
||||||
case ERROR_CODE_IO_NETWORK_CONNECTION_FAILED:
|
case ERROR_CODE_IO_NETWORK_CONNECTION_FAILED:
|
||||||
case ERROR_CODE_IO_NETWORK_CONNECTION_TIMEOUT:
|
case ERROR_CODE_IO_NETWORK_CONNECTION_TIMEOUT:
|
||||||
// Don't create notification on timeout/networking errors:
|
|
||||||
isCatchableException = true;
|
|
||||||
setRecovery();
|
|
||||||
reloadPlayQueueManager();
|
|
||||||
break;
|
|
||||||
case ERROR_CODE_UNSPECIFIED:
|
case ERROR_CODE_UNSPECIFIED:
|
||||||
// Reload playback on unexpected errors:
|
// Reload playback on unexpected errors:
|
||||||
setRecovery();
|
setRecovery();
|
||||||
@ -3010,10 +3015,9 @@ public final class Player implements
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void saveStreamProgressStateCompleted() {
|
public void saveStreamProgressStateCompleted() {
|
||||||
getCurrentStreamInfo().ifPresent(info -> {
|
// current stream has ended, so the progress is its duration (+1 to overcome rounding)
|
||||||
// current stream has ended, so the progress is its duration (+1 to overcome rounding)
|
getCurrentStreamInfo().ifPresent(info ->
|
||||||
saveStreamProgressState((info.getDuration() + 1) * 1000);
|
saveStreamProgressState((info.getDuration() + 1) * 1000));
|
||||||
});
|
|
||||||
}
|
}
|
||||||
//endregion
|
//endregion
|
||||||
|
|
||||||
@ -3414,7 +3418,8 @@ public final class Player implements
|
|||||||
case VIDEO_STREAM:
|
case VIDEO_STREAM:
|
||||||
if (currentMetadata == null
|
if (currentMetadata == null
|
||||||
|| !currentMetadata.getMaybeQuality().isPresent()
|
|| !currentMetadata.getMaybeQuality().isPresent()
|
||||||
|| info.getVideoStreams().size() + info.getVideoOnlyStreams().size() == 0) {
|
|| (info.getVideoStreams().isEmpty()
|
||||||
|
&& info.getVideoOnlyStreams().isEmpty())) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3684,10 +3689,8 @@ public final class Player implements
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Normalize mismatching language strings
|
// Normalize mismatching language strings
|
||||||
final List<String> preferredLanguages =
|
final String preferredLanguage = trackSelector.getParameters()
|
||||||
trackSelector.getParameters().preferredTextLanguages;
|
.preferredTextLanguages.stream().findFirst().orElse(null);
|
||||||
final String preferredLanguage =
|
|
||||||
preferredLanguages.isEmpty() ? null : preferredLanguages.get(0);
|
|
||||||
// Build UI
|
// Build UI
|
||||||
buildCaptionMenu(availableLanguages);
|
buildCaptionMenu(availableLanguages);
|
||||||
if (trackSelector.getParameters().getRendererDisabled(textRenderer)
|
if (trackSelector.getParameters().getRendererDisabled(textRenderer)
|
||||||
|
@ -24,12 +24,12 @@ public final class ExceptionTag implements MediaItemTag {
|
|||||||
@NonNull
|
@NonNull
|
||||||
private final PlayQueueItem item;
|
private final PlayQueueItem item;
|
||||||
@NonNull
|
@NonNull
|
||||||
private final List<Throwable> errors;
|
private final List<Exception> errors;
|
||||||
@Nullable
|
@Nullable
|
||||||
private final Object extras;
|
private final Object extras;
|
||||||
|
|
||||||
private ExceptionTag(@NonNull final PlayQueueItem item,
|
private ExceptionTag(@NonNull final PlayQueueItem item,
|
||||||
@NonNull final List<Throwable> errors,
|
@NonNull final List<Exception> errors,
|
||||||
@Nullable final Object extras) {
|
@Nullable final Object extras) {
|
||||||
this.item = item;
|
this.item = item;
|
||||||
this.errors = errors;
|
this.errors = errors;
|
||||||
@ -37,13 +37,13 @@ public final class ExceptionTag implements MediaItemTag {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static ExceptionTag of(@NonNull final PlayQueueItem playQueueItem,
|
public static ExceptionTag of(@NonNull final PlayQueueItem playQueueItem,
|
||||||
@NonNull final List<Throwable> errors) {
|
@NonNull final List<Exception> errors) {
|
||||||
return new ExceptionTag(playQueueItem, errors, null);
|
return new ExceptionTag(playQueueItem, errors, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
@Override
|
@Override
|
||||||
public List<Throwable> getErrors() {
|
public List<Exception> getErrors() {
|
||||||
return errors;
|
return errors;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ import androidx.annotation.Nullable;
|
|||||||
**/
|
**/
|
||||||
public interface MediaItemTag {
|
public interface MediaItemTag {
|
||||||
|
|
||||||
List<Throwable> getErrors();
|
List<Exception> getErrors();
|
||||||
|
|
||||||
int getServiceId();
|
int getServiceId();
|
||||||
|
|
||||||
|
@ -29,7 +29,7 @@ public final class PlaceholderTag implements MediaItemTag {
|
|||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
@Override
|
@Override
|
||||||
public List<Throwable> getErrors() {
|
public List<Exception> getErrors() {
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,7 +47,7 @@ public final class StreamInfoTag implements MediaItemTag {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<Throwable> getErrors() {
|
public List<Exception> getErrors() {
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,7 +36,7 @@ public class FailedMediaSource extends BaseMediaSource implements ManagedMediaSo
|
|||||||
|
|
||||||
private final String TAG = "FailedMediaSource@" + Integer.toHexString(hashCode());
|
private final String TAG = "FailedMediaSource@" + Integer.toHexString(hashCode());
|
||||||
private final PlayQueueItem playQueueItem;
|
private final PlayQueueItem playQueueItem;
|
||||||
private final Throwable error;
|
private final Exception error;
|
||||||
private final long retryTimestamp;
|
private final long retryTimestamp;
|
||||||
private final MediaItem mediaItem;
|
private final MediaItem mediaItem;
|
||||||
/**
|
/**
|
||||||
@ -51,7 +51,7 @@ public class FailedMediaSource extends BaseMediaSource implements ManagedMediaSo
|
|||||||
* @param retryTimestamp epoch timestamp when this MediaSource can be refreshed
|
* @param retryTimestamp epoch timestamp when this MediaSource can be refreshed
|
||||||
*/
|
*/
|
||||||
public FailedMediaSource(@NonNull final PlayQueueItem playQueueItem,
|
public FailedMediaSource(@NonNull final PlayQueueItem playQueueItem,
|
||||||
@NonNull final Throwable error,
|
@NonNull final Exception error,
|
||||||
final long retryTimestamp) {
|
final long retryTimestamp) {
|
||||||
this.playQueueItem = playQueueItem;
|
this.playQueueItem = playQueueItem;
|
||||||
this.error = error;
|
this.error = error;
|
||||||
@ -68,7 +68,7 @@ public class FailedMediaSource extends BaseMediaSource implements ManagedMediaSo
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static FailedMediaSource of(@NonNull final PlayQueueItem playQueueItem,
|
public static FailedMediaSource of(@NonNull final PlayQueueItem playQueueItem,
|
||||||
@NonNull final Throwable error,
|
@NonNull final Exception error,
|
||||||
final long retryWaitMillis) {
|
final long retryWaitMillis) {
|
||||||
return new FailedMediaSource(playQueueItem, error,
|
return new FailedMediaSource(playQueueItem, error,
|
||||||
System.currentTimeMillis() + retryWaitMillis);
|
System.currentTimeMillis() + retryWaitMillis);
|
||||||
|
@ -441,7 +441,8 @@ public class MediaSourceManager {
|
|||||||
if (throwable instanceof ExtractionException) {
|
if (throwable instanceof ExtractionException) {
|
||||||
return FailedMediaSource.of(stream, new StreamInfoLoadException(throwable));
|
return FailedMediaSource.of(stream, new StreamInfoLoadException(throwable));
|
||||||
}
|
}
|
||||||
return FailedMediaSource.of(stream, throwable, /*immediatelyRetryable=*/0L);
|
return FailedMediaSource
|
||||||
|
.of(stream, new Exception(throwable), /*immediatelyRetryable=*/0L);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user