Search in sources :

Example 1 with LoadErrorHandlingPolicy

use of androidx.media3.exoplayer.upstream.LoadErrorHandlingPolicy in project media by androidx.

the class DefaultMediaSourceFactory method createMediaSource.

@UnstableApi
@Override
public MediaSource createMediaSource(MediaItem mediaItem) {
    Assertions.checkNotNull(mediaItem.localConfiguration);
    @Nullable String scheme = mediaItem.localConfiguration.uri.getScheme();
    if (scheme != null && scheme.equals(C.SSAI_SCHEME)) {
        return checkNotNull(serverSideAdInsertionMediaSourceFactory).createMediaSource(mediaItem);
    }
    @C.ContentType int type = Util.inferContentTypeForUriAndMimeType(mediaItem.localConfiguration.uri, mediaItem.localConfiguration.mimeType);
    @Nullable MediaSource.Factory mediaSourceFactory = delegateFactoryLoader.getMediaSourceFactory(type);
    checkStateNotNull(mediaSourceFactory, "No suitable media source factory found for content type: " + type);
    MediaItem.LiveConfiguration.Builder liveConfigurationBuilder = mediaItem.liveConfiguration.buildUpon();
    if (mediaItem.liveConfiguration.targetOffsetMs == C.TIME_UNSET) {
        liveConfigurationBuilder.setTargetOffsetMs(liveTargetOffsetMs);
    }
    if (mediaItem.liveConfiguration.minPlaybackSpeed == C.RATE_UNSET) {
        liveConfigurationBuilder.setMinPlaybackSpeed(liveMinSpeed);
    }
    if (mediaItem.liveConfiguration.maxPlaybackSpeed == C.RATE_UNSET) {
        liveConfigurationBuilder.setMaxPlaybackSpeed(liveMaxSpeed);
    }
    if (mediaItem.liveConfiguration.minOffsetMs == C.TIME_UNSET) {
        liveConfigurationBuilder.setMinOffsetMs(liveMinOffsetMs);
    }
    if (mediaItem.liveConfiguration.maxOffsetMs == C.TIME_UNSET) {
        liveConfigurationBuilder.setMaxOffsetMs(liveMaxOffsetMs);
    }
    MediaItem.LiveConfiguration liveConfiguration = liveConfigurationBuilder.build();
    // Make sure to retain the very same media item instance, if no value needs to be overridden.
    if (!liveConfiguration.equals(mediaItem.liveConfiguration)) {
        mediaItem = mediaItem.buildUpon().setLiveConfiguration(liveConfiguration).build();
    }
    MediaSource mediaSource = mediaSourceFactory.createMediaSource(mediaItem);
    List<MediaItem.SubtitleConfiguration> subtitleConfigurations = castNonNull(mediaItem.localConfiguration).subtitleConfigurations;
    if (!subtitleConfigurations.isEmpty()) {
        MediaSource[] mediaSources = new MediaSource[subtitleConfigurations.size() + 1];
        mediaSources[0] = mediaSource;
        for (int i = 0; i < subtitleConfigurations.size(); i++) {
            if (useProgressiveMediaSourceForSubtitles) {
                Format format = new Format.Builder().setSampleMimeType(subtitleConfigurations.get(i).mimeType).setLanguage(subtitleConfigurations.get(i).language).setSelectionFlags(subtitleConfigurations.get(i).selectionFlags).setRoleFlags(subtitleConfigurations.get(i).roleFlags).setLabel(subtitleConfigurations.get(i).label).setId(subtitleConfigurations.get(i).id).build();
                ExtractorsFactory extractorsFactory = () -> new Extractor[] { SubtitleDecoderFactory.DEFAULT.supportsFormat(format) ? new SubtitleExtractor(SubtitleDecoderFactory.DEFAULT.createDecoder(format), format) : new UnknownSubtitlesExtractor(format) };
                mediaSources[i + 1] = new ProgressiveMediaSource.Factory(dataSourceFactory, extractorsFactory).setLoadErrorHandlingPolicy(loadErrorHandlingPolicy).createMediaSource(MediaItem.fromUri(subtitleConfigurations.get(i).uri.toString()));
            } else {
                mediaSources[i + 1] = new SingleSampleMediaSource.Factory(dataSourceFactory).setLoadErrorHandlingPolicy(loadErrorHandlingPolicy).createMediaSource(subtitleConfigurations.get(i), /* durationUs= */
                C.TIME_UNSET);
            }
        }
        mediaSource = new MergingMediaSource(mediaSources);
    }
    return maybeWrapWithAdsMediaSource(mediaItem, maybeClipMediaSource(mediaItem, mediaSource));
}
Also used : SubtitleExtractor(androidx.media3.extractor.text.SubtitleExtractor) Format(androidx.media3.common.Format) AdsMediaSource(androidx.media3.exoplayer.source.ads.AdsMediaSource) DefaultExtractorsFactory(androidx.media3.extractor.DefaultExtractorsFactory) ExtractorsFactory(androidx.media3.extractor.ExtractorsFactory) MediaItem(androidx.media3.common.MediaItem) Extractor(androidx.media3.extractor.Extractor) SubtitleExtractor(androidx.media3.extractor.text.SubtitleExtractor) Nullable(androidx.annotation.Nullable) UnstableApi(androidx.media3.common.util.UnstableApi)

Example 2 with LoadErrorHandlingPolicy

use of androidx.media3.exoplayer.upstream.LoadErrorHandlingPolicy in project media by androidx.

the class DashMediaSource method createPeriod.

@Override
public MediaPeriod createPeriod(MediaPeriodId id, Allocator allocator, long startPositionUs) {
    int periodIndex = (Integer) id.periodUid - firstPeriodId;
    MediaSourceEventListener.EventDispatcher periodEventDispatcher = createEventDispatcher(id, manifest.getPeriod(periodIndex).startMs);
    DrmSessionEventListener.EventDispatcher drmEventDispatcher = createDrmEventDispatcher(id);
    DashMediaPeriod mediaPeriod = new DashMediaPeriod(firstPeriodId + periodIndex, manifest, baseUrlExclusionList, periodIndex, chunkSourceFactory, mediaTransferListener, drmSessionManager, drmEventDispatcher, loadErrorHandlingPolicy, periodEventDispatcher, elapsedRealtimeOffsetMs, manifestLoadErrorThrower, allocator, compositeSequenceableLoaderFactory, playerEmsgCallback, getPlayerId());
    periodsById.put(mediaPeriod.id, mediaPeriod);
    return mediaPeriod;
}
Also used : EventDispatcher(androidx.media3.exoplayer.source.MediaSourceEventListener.EventDispatcher) MediaSourceEventListener(androidx.media3.exoplayer.source.MediaSourceEventListener) DrmSessionEventListener(androidx.media3.exoplayer.drm.DrmSessionEventListener)

Example 3 with LoadErrorHandlingPolicy

use of androidx.media3.exoplayer.upstream.LoadErrorHandlingPolicy in project media by androidx.

the class DefaultDashChunkSource method onChunkLoadError.

@Override
public boolean onChunkLoadError(Chunk chunk, boolean cancelable, LoadErrorHandlingPolicy.LoadErrorInfo loadErrorInfo, LoadErrorHandlingPolicy loadErrorHandlingPolicy) {
    if (!cancelable) {
        return false;
    }
    if (playerTrackEmsgHandler != null && playerTrackEmsgHandler.onChunkLoadError(chunk)) {
        return true;
    }
    // Workaround for missing segment at the end of the period
    if (!manifest.dynamic && chunk instanceof MediaChunk && loadErrorInfo.exception instanceof InvalidResponseCodeException && ((InvalidResponseCodeException) loadErrorInfo.exception).responseCode == 404) {
        RepresentationHolder representationHolder = representationHolders[trackSelection.indexOf(chunk.trackFormat)];
        long segmentCount = representationHolder.getSegmentCount();
        if (segmentCount != DashSegmentIndex.INDEX_UNBOUNDED && segmentCount != 0) {
            long lastAvailableSegmentNum = representationHolder.getFirstSegmentNum() + segmentCount - 1;
            if (((MediaChunk) chunk).getNextChunkIndex() > lastAvailableSegmentNum) {
                missingLastSegment = true;
                return true;
            }
        }
    }
    int trackIndex = trackSelection.indexOf(chunk.trackFormat);
    RepresentationHolder representationHolder = representationHolders[trackIndex];
    @Nullable BaseUrl newBaseUrl = baseUrlExclusionList.selectBaseUrl(representationHolder.representation.baseUrls);
    if (newBaseUrl != null && !representationHolder.selectedBaseUrl.equals(newBaseUrl)) {
        // which will use the new base URL.
        return true;
    }
    LoadErrorHandlingPolicy.FallbackOptions fallbackOptions = createFallbackOptions(trackSelection, representationHolder.representation.baseUrls);
    if (!fallbackOptions.isFallbackAvailable(LoadErrorHandlingPolicy.FALLBACK_TYPE_TRACK) && !fallbackOptions.isFallbackAvailable(LoadErrorHandlingPolicy.FALLBACK_TYPE_LOCATION)) {
        return false;
    }
    @Nullable LoadErrorHandlingPolicy.FallbackSelection fallbackSelection = loadErrorHandlingPolicy.getFallbackSelectionFor(fallbackOptions, loadErrorInfo);
    if (fallbackSelection == null || !fallbackOptions.isFallbackAvailable(fallbackSelection.type)) {
        // Policy indicated to not use any fallback or a fallback type that is not available.
        return false;
    }
    boolean cancelLoad = false;
    if (fallbackSelection.type == LoadErrorHandlingPolicy.FALLBACK_TYPE_TRACK) {
        cancelLoad = trackSelection.blacklist(trackSelection.indexOf(chunk.trackFormat), fallbackSelection.exclusionDurationMs);
    } else if (fallbackSelection.type == LoadErrorHandlingPolicy.FALLBACK_TYPE_LOCATION) {
        baseUrlExclusionList.exclude(representationHolder.selectedBaseUrl, fallbackSelection.exclusionDurationMs);
        cancelLoad = true;
    }
    return cancelLoad;
}
Also used : SingleSampleMediaChunk(androidx.media3.exoplayer.source.chunk.SingleSampleMediaChunk) ContainerMediaChunk(androidx.media3.exoplayer.source.chunk.ContainerMediaChunk) MediaChunk(androidx.media3.exoplayer.source.chunk.MediaChunk) BaseUrl(androidx.media3.exoplayer.dash.manifest.BaseUrl) LoadErrorHandlingPolicy(androidx.media3.exoplayer.upstream.LoadErrorHandlingPolicy) InvalidResponseCodeException(androidx.media3.datasource.HttpDataSource.InvalidResponseCodeException) Nullable(androidx.annotation.Nullable)

Example 4 with LoadErrorHandlingPolicy

use of androidx.media3.exoplayer.upstream.LoadErrorHandlingPolicy in project media by androidx.

the class SsMediaSource method createPeriod.

@Override
public MediaPeriod createPeriod(MediaPeriodId id, Allocator allocator, long startPositionUs) {
    MediaSourceEventListener.EventDispatcher mediaSourceEventDispatcher = createEventDispatcher(id);
    DrmSessionEventListener.EventDispatcher drmEventDispatcher = createDrmEventDispatcher(id);
    SsMediaPeriod period = new SsMediaPeriod(manifest, chunkSourceFactory, mediaTransferListener, compositeSequenceableLoaderFactory, drmSessionManager, drmEventDispatcher, loadErrorHandlingPolicy, mediaSourceEventDispatcher, manifestLoaderErrorThrower, allocator);
    mediaPeriods.add(period);
    return period;
}
Also used : EventDispatcher(androidx.media3.exoplayer.source.MediaSourceEventListener.EventDispatcher) MediaSourceEventListener(androidx.media3.exoplayer.source.MediaSourceEventListener) DrmSessionEventListener(androidx.media3.exoplayer.drm.DrmSessionEventListener)

Example 5 with LoadErrorHandlingPolicy

use of androidx.media3.exoplayer.upstream.LoadErrorHandlingPolicy in project media by androidx.

the class DashMediaPeriod method buildSampleStream.

private ChunkSampleStream<DashChunkSource> buildSampleStream(TrackGroupInfo trackGroupInfo, ExoTrackSelection selection, long positionUs) {
    int embeddedTrackCount = 0;
    boolean enableEventMessageTrack = trackGroupInfo.embeddedEventMessageTrackGroupIndex != C.INDEX_UNSET;
    TrackGroup embeddedEventMessageTrackGroup = null;
    if (enableEventMessageTrack) {
        embeddedEventMessageTrackGroup = trackGroups.get(trackGroupInfo.embeddedEventMessageTrackGroupIndex);
        embeddedTrackCount++;
    }
    boolean enableClosedCaptionTrack = trackGroupInfo.embeddedClosedCaptionTrackGroupIndex != C.INDEX_UNSET;
    TrackGroup embeddedClosedCaptionTrackGroup = null;
    if (enableClosedCaptionTrack) {
        embeddedClosedCaptionTrackGroup = trackGroups.get(trackGroupInfo.embeddedClosedCaptionTrackGroupIndex);
        embeddedTrackCount += embeddedClosedCaptionTrackGroup.length;
    }
    Format[] embeddedTrackFormats = new Format[embeddedTrackCount];
    int[] embeddedTrackTypes = new int[embeddedTrackCount];
    embeddedTrackCount = 0;
    if (enableEventMessageTrack) {
        embeddedTrackFormats[embeddedTrackCount] = embeddedEventMessageTrackGroup.getFormat(0);
        embeddedTrackTypes[embeddedTrackCount] = C.TRACK_TYPE_METADATA;
        embeddedTrackCount++;
    }
    List<Format> embeddedClosedCaptionTrackFormats = new ArrayList<>();
    if (enableClosedCaptionTrack) {
        for (int i = 0; i < embeddedClosedCaptionTrackGroup.length; i++) {
            embeddedTrackFormats[embeddedTrackCount] = embeddedClosedCaptionTrackGroup.getFormat(i);
            embeddedTrackTypes[embeddedTrackCount] = C.TRACK_TYPE_TEXT;
            embeddedClosedCaptionTrackFormats.add(embeddedTrackFormats[embeddedTrackCount]);
            embeddedTrackCount++;
        }
    }
    PlayerTrackEmsgHandler trackPlayerEmsgHandler = manifest.dynamic && enableEventMessageTrack ? playerEmsgHandler.newPlayerTrackEmsgHandler() : null;
    DashChunkSource chunkSource = chunkSourceFactory.createDashChunkSource(manifestLoaderErrorThrower, manifest, baseUrlExclusionList, periodIndex, trackGroupInfo.adaptationSetIndices, selection, trackGroupInfo.trackType, elapsedRealtimeOffsetMs, enableEventMessageTrack, embeddedClosedCaptionTrackFormats, trackPlayerEmsgHandler, transferListener, playerId);
    ChunkSampleStream<DashChunkSource> stream = new ChunkSampleStream<>(trackGroupInfo.trackType, embeddedTrackTypes, embeddedTrackFormats, chunkSource, this, allocator, positionUs, drmSessionManager, drmEventDispatcher, loadErrorHandlingPolicy, mediaSourceEventDispatcher);
    synchronized (this) {
        // The map is also accessed on the loading thread so synchronize access.
        trackEmsgHandlerBySampleStream.put(stream, trackPlayerEmsgHandler);
    }
    return stream;
}
Also used : Format(androidx.media3.common.Format) ChunkSampleStream(androidx.media3.exoplayer.source.chunk.ChunkSampleStream) TrackGroup(androidx.media3.common.TrackGroup) ArrayList(java.util.ArrayList) PlayerTrackEmsgHandler(androidx.media3.exoplayer.dash.PlayerEmsgHandler.PlayerTrackEmsgHandler)

Aggregations

Nullable (androidx.annotation.Nullable)5 Format (androidx.media3.common.Format)4 TrackGroup (androidx.media3.common.TrackGroup)3 LoadEventInfo (androidx.media3.exoplayer.source.LoadEventInfo)3 MediaLoadData (androidx.media3.exoplayer.source.MediaLoadData)3 ChunkHolder (androidx.media3.exoplayer.source.chunk.ChunkHolder)3 DefaultLoadErrorHandlingPolicy (androidx.media3.exoplayer.upstream.DefaultLoadErrorHandlingPolicy)3 LoadErrorHandlingPolicy (androidx.media3.exoplayer.upstream.LoadErrorHandlingPolicy)3 ArrayList (java.util.ArrayList)3 Test (org.junit.Test)3 Uri (android.net.Uri)2 SystemClock (android.os.SystemClock)2 C (androidx.media3.common.C)2 Assertions (androidx.media3.common.util.Assertions)2 Assertions.checkNotNull (androidx.media3.common.util.Assertions.checkNotNull)2 Util (androidx.media3.common.util.Util)2 DataSpec (androidx.media3.datasource.DataSpec)2 HttpDataSource (androidx.media3.datasource.HttpDataSource)2 PlayerId (androidx.media3.exoplayer.analytics.PlayerId)2 DashManifest (androidx.media3.exoplayer.dash.manifest.DashManifest)2