Search in sources :

Example 1 with PlaybackException

use of com.google.android.exoplayer2.PlaybackException in project ExoPlayer by google.

the class MediaMetricsListener method getErrorInfo.

private static ErrorInfo getErrorInfo(PlaybackException error, Context context, boolean lastIoErrorForManifest) {
    if (error.errorCode == PlaybackException.ERROR_CODE_REMOTE_ERROR) {
        return new ErrorInfo(PlaybackErrorEvent.ERROR_PLAYER_REMOTE, /* subErrorCode= */
        0);
    }
    // Unpack the PlaybackException.
    // TODO(b/190203080): Use error codes instead of the Exception's cause where possible.
    boolean isRendererExoPlaybackException = false;
    int rendererFormatSupport = C.FORMAT_UNSUPPORTED_TYPE;
    if (error instanceof ExoPlaybackException) {
        ExoPlaybackException exoPlaybackException = (ExoPlaybackException) error;
        isRendererExoPlaybackException = exoPlaybackException.type == ExoPlaybackException.TYPE_RENDERER;
        rendererFormatSupport = exoPlaybackException.rendererFormatSupport;
    }
    Throwable cause = checkNotNull(error.getCause());
    if (cause instanceof IOException) {
        if (cause instanceof HttpDataSource.InvalidResponseCodeException) {
            int responseCode = ((HttpDataSource.InvalidResponseCodeException) cause).responseCode;
            return new ErrorInfo(PlaybackErrorEvent.ERROR_IO_BAD_HTTP_STATUS, /* subErrorCode= */
            responseCode);
        } else if (cause instanceof HttpDataSource.InvalidContentTypeException || cause instanceof ParserException) {
            return new ErrorInfo(lastIoErrorForManifest ? PlaybackErrorEvent.ERROR_PARSING_MANIFEST_MALFORMED : PlaybackErrorEvent.ERROR_PARSING_CONTAINER_MALFORMED, /* subErrorCode= */
            0);
        } else if (cause instanceof HttpDataSource.HttpDataSourceException || cause instanceof UdpDataSource.UdpDataSourceException) {
            if (NetworkTypeObserver.getInstance(context).getNetworkType() == C.NETWORK_TYPE_OFFLINE) {
                return new ErrorInfo(PlaybackErrorEvent.ERROR_IO_NETWORK_UNAVAILABLE, /* subErrorCode= */
                0);
            } else {
                @Nullable Throwable detailedCause = cause.getCause();
                if (detailedCause instanceof UnknownHostException) {
                    return new ErrorInfo(PlaybackErrorEvent.ERROR_IO_DNS_FAILED, /* subErrorCode= */
                    0);
                } else if (detailedCause instanceof SocketTimeoutException) {
                    return new ErrorInfo(PlaybackErrorEvent.ERROR_IO_CONNECTION_TIMEOUT, /* subErrorCode= */
                    0);
                } else if (cause instanceof HttpDataSource.HttpDataSourceException && ((HttpDataSource.HttpDataSourceException) cause).type == HttpDataSource.HttpDataSourceException.TYPE_OPEN) {
                    return new ErrorInfo(PlaybackErrorEvent.ERROR_IO_NETWORK_CONNECTION_FAILED, /* subErrorCode= */
                    0);
                } else {
                    return new ErrorInfo(PlaybackErrorEvent.ERROR_IO_CONNECTION_CLOSED, /* subErrorCode= */
                    0);
                }
            }
        } else if (error.errorCode == PlaybackException.ERROR_CODE_BEHIND_LIVE_WINDOW) {
            return new ErrorInfo(PlaybackErrorEvent.ERROR_PLAYER_BEHIND_LIVE_WINDOW, /* subErrorCode= */
            0);
        } else if (cause instanceof DrmSession.DrmSessionException) {
            // Unpack DrmSessionException.
            cause = checkNotNull(cause.getCause());
            if (Util.SDK_INT >= 21 && cause instanceof MediaDrm.MediaDrmStateException) {
                String diagnosticsInfo = ((MediaDrm.MediaDrmStateException) cause).getDiagnosticInfo();
                int subErrorCode = Util.getErrorCodeFromPlatformDiagnosticsInfo(diagnosticsInfo);
                int errorCode = getDrmErrorCode(subErrorCode);
                return new ErrorInfo(errorCode, subErrorCode);
            } else if (Util.SDK_INT >= 23 && cause instanceof MediaDrmResetException) {
                return new ErrorInfo(PlaybackErrorEvent.ERROR_DRM_SYSTEM_ERROR, /* subErrorCode= */
                0);
            } else if (Util.SDK_INT >= 18 && cause instanceof NotProvisionedException) {
                return new ErrorInfo(PlaybackErrorEvent.ERROR_DRM_PROVISIONING_FAILED, /* subErrorCode= */
                0);
            } else if (Util.SDK_INT >= 18 && cause instanceof DeniedByServerException) {
                return new ErrorInfo(PlaybackErrorEvent.ERROR_DRM_DEVICE_REVOKED, /* subErrorCode= */
                0);
            } else if (cause instanceof UnsupportedDrmException) {
                return new ErrorInfo(PlaybackErrorEvent.ERROR_DRM_SCHEME_UNSUPPORTED, /* subErrorCode= */
                0);
            } else if (cause instanceof DefaultDrmSessionManager.MissingSchemeDataException) {
                return new ErrorInfo(PlaybackErrorEvent.ERROR_DRM_CONTENT_ERROR, /* subErrorCode= */
                0);
            } else {
                return new ErrorInfo(PlaybackErrorEvent.ERROR_DRM_OTHER, /* subErrorCode= */
                0);
            }
        } else if (cause instanceof FileDataSource.FileDataSourceException && cause.getCause() instanceof FileNotFoundException) {
            @Nullable Throwable notFoundCause = checkNotNull(cause.getCause()).getCause();
            if (Util.SDK_INT >= 21 && notFoundCause instanceof ErrnoException && ((ErrnoException) notFoundCause).errno == OsConstants.EACCES) {
                return new ErrorInfo(PlaybackErrorEvent.ERROR_IO_NO_PERMISSION, /* subErrorCode= */
                0);
            } else {
                return new ErrorInfo(PlaybackErrorEvent.ERROR_IO_FILE_NOT_FOUND, /* subErrorCode= */
                0);
            }
        } else {
            return new ErrorInfo(PlaybackErrorEvent.ERROR_IO_OTHER, /* subErrorCode= */
            0);
        }
    } else if (isRendererExoPlaybackException && (rendererFormatSupport == C.FORMAT_UNSUPPORTED_TYPE || rendererFormatSupport == C.FORMAT_UNSUPPORTED_SUBTYPE)) {
        return new ErrorInfo(PlaybackErrorEvent.ERROR_DECODING_FORMAT_UNSUPPORTED, /* subErrorCode= */
        0);
    } else if (isRendererExoPlaybackException && rendererFormatSupport == C.FORMAT_EXCEEDS_CAPABILITIES) {
        return new ErrorInfo(PlaybackErrorEvent.ERROR_DECODING_FORMAT_EXCEEDS_CAPABILITIES, /* subErrorCode= */
        0);
    } else if (isRendererExoPlaybackException && rendererFormatSupport == C.FORMAT_UNSUPPORTED_DRM) {
        return new ErrorInfo(PlaybackErrorEvent.ERROR_DRM_SCHEME_UNSUPPORTED, /* subErrorCode= */
        0);
    } else if (cause instanceof MediaCodecRenderer.DecoderInitializationException) {
        @Nullable String diagnosticsInfo = ((MediaCodecRenderer.DecoderInitializationException) cause).diagnosticInfo;
        int subErrorCode = Util.getErrorCodeFromPlatformDiagnosticsInfo(diagnosticsInfo);
        return new ErrorInfo(PlaybackErrorEvent.ERROR_DECODER_INIT_FAILED, subErrorCode);
    } else if (cause instanceof MediaCodecDecoderException) {
        @Nullable String diagnosticsInfo = ((MediaCodecDecoderException) cause).diagnosticInfo;
        int subErrorCode = Util.getErrorCodeFromPlatformDiagnosticsInfo(diagnosticsInfo);
        return new ErrorInfo(PlaybackErrorEvent.ERROR_DECODING_FAILED, subErrorCode);
    } else if (cause instanceof OutOfMemoryError) {
        return new ErrorInfo(PlaybackErrorEvent.ERROR_DECODING_FAILED, /* subErrorCode= */
        0);
    } else if (cause instanceof AudioSink.InitializationException) {
        int subErrorCode = ((AudioSink.InitializationException) cause).audioTrackState;
        return new ErrorInfo(PlaybackErrorEvent.ERROR_AUDIO_TRACK_INIT_FAILED, subErrorCode);
    } else if (cause instanceof AudioSink.WriteException) {
        int subErrorCode = ((AudioSink.WriteException) cause).errorCode;
        return new ErrorInfo(PlaybackErrorEvent.ERROR_AUDIO_TRACK_WRITE_FAILED, subErrorCode);
    } else if (Util.SDK_INT >= 16 && cause instanceof MediaCodec.CryptoException) {
        int subErrorCode = ((MediaCodec.CryptoException) cause).getErrorCode();
        int errorCode = getDrmErrorCode(subErrorCode);
        return new ErrorInfo(errorCode, subErrorCode);
    } else {
        return new ErrorInfo(PlaybackErrorEvent.ERROR_PLAYER_OTHER, /* subErrorCode= */
        0);
    }
}
Also used : AudioSink(com.google.android.exoplayer2.audio.AudioSink) DefaultDrmSessionManager(com.google.android.exoplayer2.drm.DefaultDrmSessionManager) FileNotFoundException(java.io.FileNotFoundException) MediaDrm(android.media.MediaDrm) MediaCodec(android.media.MediaCodec) HttpDataSource(com.google.android.exoplayer2.upstream.HttpDataSource) NotProvisionedException(android.media.NotProvisionedException) UnsupportedDrmException(com.google.android.exoplayer2.drm.UnsupportedDrmException) ParserException(com.google.android.exoplayer2.ParserException) UnknownHostException(java.net.UnknownHostException) MediaDrmResetException(android.media.MediaDrmResetException) ExoPlaybackException(com.google.android.exoplayer2.ExoPlaybackException) IOException(java.io.IOException) SuppressLint(android.annotation.SuppressLint) DeniedByServerException(android.media.DeniedByServerException) SocketTimeoutException(java.net.SocketTimeoutException) ErrnoException(android.system.ErrnoException) UdpDataSource(com.google.android.exoplayer2.upstream.UdpDataSource) MediaCodecDecoderException(com.google.android.exoplayer2.mediacodec.MediaCodecDecoderException) Nullable(androidx.annotation.Nullable)

Example 2 with PlaybackException

use of com.google.android.exoplayer2.PlaybackException in project ExoPlayer by google.

the class DrmPlaybackTest method clearkeyPlayback.

@Test
public void clearkeyPlayback() throws Exception {
    MockWebServer mockWebServer = new MockWebServer();
    mockWebServer.enqueue(new MockResponse().setResponseCode(200).setBody(CLEARKEY_RESPONSE));
    mockWebServer.start();
    MediaItem mediaItem = new MediaItem.Builder().setUri("asset:///media/drm/sample_fragmented_clearkey.mp4").setDrmConfiguration(new MediaItem.DrmConfiguration.Builder(C.CLEARKEY_UUID).setLicenseUri(mockWebServer.url("license").toString()).build()).build();
    AtomicReference<ExoPlayer> player = new AtomicReference<>();
    ConditionVariable playbackComplete = new ConditionVariable();
    AtomicReference<PlaybackException> playbackException = new AtomicReference<>();
    getInstrumentation().runOnMainSync(() -> {
        player.set(new ExoPlayer.Builder(getInstrumentation().getContext()).build());
        player.get().addListener(new Player.Listener() {

            @Override
            public void onPlaybackStateChanged(@Player.State int playbackState) {
                if (playbackState == Player.STATE_ENDED) {
                    playbackComplete.open();
                }
            }

            @Override
            public void onPlayerError(PlaybackException error) {
                playbackException.set(error);
                playbackComplete.open();
            }
        });
        player.get().setMediaItem(mediaItem);
        player.get().prepare();
        player.get().play();
    });
    playbackComplete.block();
    getInstrumentation().runOnMainSync(() -> player.get().release());
    getInstrumentation().waitForIdleSync();
    assertThat(playbackException.get()).isNull();
}
Also used : PlaybackException(com.google.android.exoplayer2.PlaybackException) MockResponse(okhttp3.mockwebserver.MockResponse) Player(com.google.android.exoplayer2.Player) ExoPlayer(com.google.android.exoplayer2.ExoPlayer) AtomicReference(java.util.concurrent.atomic.AtomicReference) ExoPlayer(com.google.android.exoplayer2.ExoPlayer) ConditionVariable(com.google.android.exoplayer2.util.ConditionVariable) MediaItem(com.google.android.exoplayer2.MediaItem) MockWebServer(okhttp3.mockwebserver.MockWebServer) Test(org.junit.Test)

Example 3 with PlaybackException

use of com.google.android.exoplayer2.PlaybackException in project ExoPlayer by google.

the class MediaSessionConnector method invalidateMediaSessionPlaybackState.

/**
 * Updates the playback state of the media session.
 *
 * <p>Apps normally only need to call this method when the custom actions provided by a {@link
 * CustomActionProvider} changed and the playback state needs to be updated immediately.
 */
public final void invalidateMediaSessionPlaybackState() {
    PlaybackStateCompat.Builder builder = new PlaybackStateCompat.Builder();
    @Nullable Player player = this.player;
    if (player == null) {
        builder.setActions(buildPrepareActions()).setState(PlaybackStateCompat.STATE_NONE, /* position= */
        0, /* playbackSpeed= */
        0, /* updateTime= */
        SystemClock.elapsedRealtime());
        mediaSession.setRepeatMode(PlaybackStateCompat.REPEAT_MODE_NONE);
        mediaSession.setShuffleMode(PlaybackStateCompat.SHUFFLE_MODE_NONE);
        mediaSession.setPlaybackState(builder.build());
        return;
    }
    Map<String, CustomActionProvider> currentActions = new HashMap<>();
    for (CustomActionProvider customActionProvider : customActionProviders) {
        @Nullable PlaybackStateCompat.CustomAction customAction = customActionProvider.getCustomAction(player);
        if (customAction != null) {
            currentActions.put(customAction.getAction(), customActionProvider);
            builder.addCustomAction(customAction);
        }
    }
    customActionMap = Collections.unmodifiableMap(currentActions);
    Bundle extras = new Bundle();
    @Nullable PlaybackException playbackError = player.getPlayerError();
    boolean reportError = playbackError != null || customError != null;
    int sessionPlaybackState = reportError ? PlaybackStateCompat.STATE_ERROR : getMediaSessionPlaybackState(player.getPlaybackState(), player.getPlayWhenReady());
    if (customError != null) {
        builder.setErrorMessage(customError.first, customError.second);
        if (customErrorExtras != null) {
            extras.putAll(customErrorExtras);
        }
    } else if (playbackError != null && errorMessageProvider != null) {
        Pair<Integer, String> message = errorMessageProvider.getErrorMessage(playbackError);
        builder.setErrorMessage(message.first, message.second);
    }
    long activeQueueItemId = queueNavigator != null ? queueNavigator.getActiveQueueItemId(player) : MediaSessionCompat.QueueItem.UNKNOWN_ID;
    float playbackSpeed = player.getPlaybackParameters().speed;
    extras.putFloat(EXTRAS_SPEED, playbackSpeed);
    float sessionPlaybackSpeed = player.isPlaying() ? playbackSpeed : 0f;
    @Nullable MediaItem currentMediaItem = player.getCurrentMediaItem();
    if (currentMediaItem != null && !MediaItem.DEFAULT_MEDIA_ID.equals(currentMediaItem.mediaId)) {
        extras.putString(PLAYBACK_STATE_EXTRAS_KEY_MEDIA_ID, currentMediaItem.mediaId);
    }
    builder.setActions(buildPrepareActions() | buildPlaybackActions(player)).setActiveQueueItemId(activeQueueItemId).setBufferedPosition(player.getBufferedPosition()).setState(sessionPlaybackState, player.getCurrentPosition(), sessionPlaybackSpeed, /* updateTime= */
    SystemClock.elapsedRealtime()).setExtras(extras);
    @Player.RepeatMode int repeatMode = player.getRepeatMode();
    mediaSession.setRepeatMode(repeatMode == Player.REPEAT_MODE_ONE ? PlaybackStateCompat.REPEAT_MODE_ONE : repeatMode == Player.REPEAT_MODE_ALL ? PlaybackStateCompat.REPEAT_MODE_ALL : PlaybackStateCompat.REPEAT_MODE_NONE);
    mediaSession.setShuffleMode(player.getShuffleModeEnabled() ? PlaybackStateCompat.SHUFFLE_MODE_ALL : PlaybackStateCompat.SHUFFLE_MODE_NONE);
    mediaSession.setPlaybackState(builder.build());
}
Also used : PlaybackException(com.google.android.exoplayer2.PlaybackException) Player(com.google.android.exoplayer2.Player) HashMap(java.util.HashMap) Bundle(android.os.Bundle) PlaybackStateCompat(android.support.v4.media.session.PlaybackStateCompat) MediaItem(com.google.android.exoplayer2.MediaItem) Nullable(androidx.annotation.Nullable) Pair(android.util.Pair)

Example 4 with PlaybackException

use of com.google.android.exoplayer2.PlaybackException in project ExoPlayer by google.

the class ExoPlayerTest method errorThrownDuringPlaylistUpdate_keepsConsistentPlayerState.

@Test
public void errorThrownDuringPlaylistUpdate_keepsConsistentPlayerState() {
    FakeMediaSource source1 = new FakeMediaSource(new FakeTimeline(), ExoPlayerTestRunner.VIDEO_FORMAT, ExoPlayerTestRunner.AUDIO_FORMAT);
    FakeMediaSource source2 = new FakeMediaSource(new FakeTimeline(), ExoPlayerTestRunner.AUDIO_FORMAT);
    AtomicInteger audioRendererEnableCount = new AtomicInteger(0);
    FakeRenderer videoRenderer = new FakeRenderer(C.TRACK_TYPE_VIDEO);
    FakeRenderer audioRenderer = new FakeRenderer(C.TRACK_TYPE_AUDIO) {

        @Override
        protected void onEnabled(boolean joining, boolean mayRenderStartOfStream) throws ExoPlaybackException {
            if (audioRendererEnableCount.incrementAndGet() == 2) {
                // Fail when enabling the renderer for the second time during the playlist update.
                throw createRendererException(new IllegalStateException(), ExoPlayerTestRunner.AUDIO_FORMAT, PlaybackException.ERROR_CODE_UNSPECIFIED);
            }
        }
    };
    AtomicReference<Timeline> timelineAfterError = new AtomicReference<>();
    AtomicReference<TracksInfo> trackInfosAfterError = new AtomicReference<>();
    AtomicReference<TrackSelectionArray> trackSelectionsAfterError = new AtomicReference<>();
    AtomicInteger mediaItemIndexAfterError = new AtomicInteger();
    ActionSchedule actionSchedule = new ActionSchedule.Builder(TAG).executeRunnable(new PlayerRunnable() {

        @Override
        public void run(ExoPlayer player) {
            player.addAnalyticsListener(new AnalyticsListener() {

                @Override
                public void onPlayerError(EventTime eventTime, PlaybackException error) {
                    timelineAfterError.set(player.getCurrentTimeline());
                    trackInfosAfterError.set(player.getCurrentTracksInfo());
                    trackSelectionsAfterError.set(player.getCurrentTrackSelections());
                    mediaItemIndexAfterError.set(player.getCurrentMediaItemIndex());
                }
            });
        }
    }).pause().waitForIsLoading(true).waitForIsLoading(false).removeMediaItem(0).build();
    ExoPlayerTestRunner testRunner = new ExoPlayerTestRunner.Builder(context).setMediaSources(source1, source2).setActionSchedule(actionSchedule).setRenderers(videoRenderer, audioRenderer).build();
    assertThrows(ExoPlaybackException.class, () -> testRunner.start(/* doPrepare= */
    true).blockUntilActionScheduleFinished(TIMEOUT_MS).blockUntilEnded(TIMEOUT_MS));
    assertThat(timelineAfterError.get().getWindowCount()).isEqualTo(1);
    assertThat(mediaItemIndexAfterError.get()).isEqualTo(0);
    assertThat(trackInfosAfterError.get().getTrackGroupInfos()).hasSize(1);
    assertThat(trackInfosAfterError.get().getTrackGroupInfos().get(0).getTrackGroup().getFormat(0)).isEqualTo(ExoPlayerTestRunner.AUDIO_FORMAT);
    // Video renderer.
    assertThat(trackSelectionsAfterError.get().get(0)).isNull();
    // Audio renderer.
    assertThat(trackSelectionsAfterError.get().get(1)).isNotNull();
}
Also used : AnalyticsListener(com.google.android.exoplayer2.analytics.AnalyticsListener) FakeMediaSource(com.google.android.exoplayer2.testutil.FakeMediaSource) ActionSchedule(com.google.android.exoplayer2.testutil.ActionSchedule) PlayerRunnable(com.google.android.exoplayer2.testutil.ActionSchedule.PlayerRunnable) TestExoPlayerBuilder(com.google.android.exoplayer2.testutil.TestExoPlayerBuilder) AtomicReference(java.util.concurrent.atomic.AtomicReference) TrackSelectionArray(com.google.android.exoplayer2.trackselection.TrackSelectionArray) FakeRenderer(com.google.android.exoplayer2.testutil.FakeRenderer) NoUidTimeline(com.google.android.exoplayer2.testutil.NoUidTimeline) SinglePeriodTimeline(com.google.android.exoplayer2.source.SinglePeriodTimeline) FakeTimeline(com.google.android.exoplayer2.testutil.FakeTimeline) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) FakeTimeline(com.google.android.exoplayer2.testutil.FakeTimeline) ExoPlayerTestRunner(com.google.android.exoplayer2.testutil.ExoPlayerTestRunner) Test(org.junit.Test)

Example 5 with PlaybackException

use of com.google.android.exoplayer2.PlaybackException in project ExoPlayer by google.

the class EventLogger method getEventString.

private String getEventString(EventTime eventTime, String eventName, @Nullable String eventDescription, @Nullable Throwable throwable) {
    String eventString = eventName + " [" + getEventTimeString(eventTime);
    if (throwable instanceof PlaybackException) {
        eventString += ", errorCode=" + ((PlaybackException) throwable).getErrorCodeName();
    }
    if (eventDescription != null) {
        eventString += ", " + eventDescription;
    }
    @Nullable String throwableString = Log.getThrowableString(throwable);
    if (!TextUtils.isEmpty(throwableString)) {
        eventString += "\n  " + throwableString.replace("\n", "\n  ") + '\n';
    }
    eventString += "]";
    return eventString;
}
Also used : PlaybackException(com.google.android.exoplayer2.PlaybackException) Util.getFormatSupportString(com.google.android.exoplayer2.util.Util.getFormatSupportString) Nullable(androidx.annotation.Nullable)

Aggregations

PlaybackException (com.google.android.exoplayer2.PlaybackException)8 Nullable (androidx.annotation.Nullable)7 ExoPlaybackException (com.google.android.exoplayer2.ExoPlaybackException)4 Test (org.junit.Test)4 AtomicReference (java.util.concurrent.atomic.AtomicReference)3 ExoPlayer (com.google.android.exoplayer2.ExoPlayer)2 MediaItem (com.google.android.exoplayer2.MediaItem)2 Player (com.google.android.exoplayer2.Player)2 EventTime (com.google.android.exoplayer2.analytics.AnalyticsListener.EventTime)2 TestExoPlayerBuilder (com.google.android.exoplayer2.testutil.TestExoPlayerBuilder)2 SuppressLint (android.annotation.SuppressLint)1 DeniedByServerException (android.media.DeniedByServerException)1 MediaCodec (android.media.MediaCodec)1 MediaDrm (android.media.MediaDrm)1 MediaDrmResetException (android.media.MediaDrmResetException)1 NotProvisionedException (android.media.NotProvisionedException)1 Bundle (android.os.Bundle)1 PlaybackStateCompat (android.support.v4.media.session.PlaybackStateCompat)1 ErrnoException (android.system.ErrnoException)1 Pair (android.util.Pair)1