Search in sources :

Example 56 with Assertions.checkNotNull

use of com.google.android.exoplayer2.util.Assertions.checkNotNull in project ExoPlayer by google.

the class DashUtil method loadInitializationData.

/**
 * Loads initialization data for the {@code representation} and optionally index data then returns
 * a {@link BundledChunkExtractor} which contains the output.
 *
 * @param chunkExtractor The {@link ChunkExtractor} to use.
 * @param dataSource The source from which the data should be loaded.
 * @param representation The representation which initialization chunk belongs to.
 * @param baseUrlIndex The index of the base URL with which to resolve the request URI.
 * @param loadIndex Whether to load index data too.
 * @throws IOException Thrown when there is an error while loading.
 */
private static void loadInitializationData(ChunkExtractor chunkExtractor, DataSource dataSource, Representation representation, int baseUrlIndex, boolean loadIndex) throws IOException {
    RangedUri initializationUri = Assertions.checkNotNull(representation.getInitializationUri());
    @Nullable RangedUri requestUri;
    if (loadIndex) {
        @Nullable RangedUri indexUri = representation.getIndexUri();
        if (indexUri == null) {
            return;
        }
        // It's common for initialization and index data to be stored adjacently. Attempt to merge
        // the two requests together to request both at once.
        requestUri = initializationUri.attemptMerge(indexUri, representation.baseUrls.get(baseUrlIndex).url);
        if (requestUri == null) {
            loadInitializationData(dataSource, representation, baseUrlIndex, chunkExtractor, initializationUri);
            requestUri = indexUri;
        }
    } else {
        requestUri = initializationUri;
    }
    loadInitializationData(dataSource, representation, baseUrlIndex, chunkExtractor, requestUri);
}
Also used : RangedUri(com.google.android.exoplayer2.source.dash.manifest.RangedUri) Nullable(androidx.annotation.Nullable)

Example 57 with Assertions.checkNotNull

use of com.google.android.exoplayer2.util.Assertions.checkNotNull in project ExoPlayer by google.

the class TestExoPlayerBuilder method build.

/**
 * Builds an {@link ExoPlayer} using the provided values or their defaults.
 */
public ExoPlayer build() {
    Assertions.checkNotNull(looper, "TestExoPlayer builder run on a thread without Looper and no Looper specified.");
    // Do not update renderersFactory and renderers here, otherwise their getters may
    // return different values before and after build() is called, making them confusing.
    RenderersFactory playerRenderersFactory = renderersFactory;
    if (playerRenderersFactory == null) {
        playerRenderersFactory = (eventHandler, videoRendererEventListener, audioRendererEventListener, textRendererOutput, metadataRendererOutput) -> renderers != null ? renderers : new Renderer[] { new FakeVideoRenderer(eventHandler, videoRendererEventListener), new FakeAudioRenderer(eventHandler, audioRendererEventListener) };
    }
    ExoPlayer.Builder builder = new ExoPlayer.Builder(context, playerRenderersFactory).setTrackSelector(trackSelector).setLoadControl(loadControl).setBandwidthMeter(bandwidthMeter).setAnalyticsCollector(new DefaultAnalyticsCollector(clock)).setClock(clock).setUseLazyPreparation(useLazyPreparation).setLooper(looper).setSeekBackIncrementMs(seekBackIncrementMs).setSeekForwardIncrementMs(seekForwardIncrementMs);
    if (mediaSourceFactory != null) {
        builder.setMediaSourceFactory(mediaSourceFactory);
    }
    return builder.build();
}
Also used : Renderer(com.google.android.exoplayer2.Renderer) RenderersFactory(com.google.android.exoplayer2.RenderersFactory) ExoPlayer(com.google.android.exoplayer2.ExoPlayer) DefaultAnalyticsCollector(com.google.android.exoplayer2.analytics.DefaultAnalyticsCollector)

Example 58 with Assertions.checkNotNull

use of com.google.android.exoplayer2.util.Assertions.checkNotNull in project ExoPlayer by google.

the class TimelineAsserts method assertPeriodCounts.

/**
 * Asserts that period counts for each window are set correctly. Also asserts that {@link
 * Window#firstPeriodIndex} and {@link Window#lastPeriodIndex} are set correctly, and it asserts
 * the correct behavior of {@link Timeline#getNextWindowIndex(int, int, boolean)}.
 */
public static void assertPeriodCounts(Timeline timeline, int... expectedPeriodCounts) {
    int windowCount = timeline.getWindowCount();
    assertThat(windowCount).isEqualTo(expectedPeriodCounts.length);
    int[] accumulatedPeriodCounts = new int[windowCount + 1];
    accumulatedPeriodCounts[0] = 0;
    for (int i = 0; i < windowCount; i++) {
        accumulatedPeriodCounts[i + 1] = accumulatedPeriodCounts[i] + expectedPeriodCounts[i];
    }
    assertThat(timeline.getPeriodCount()).isEqualTo(accumulatedPeriodCounts[accumulatedPeriodCounts.length - 1]);
    Window window = new Window();
    Period period = new Period();
    for (int i = 0; i < windowCount; i++) {
        timeline.getWindow(i, window);
        assertThat(window.firstPeriodIndex).isEqualTo(accumulatedPeriodCounts[i]);
        assertThat(window.lastPeriodIndex).isEqualTo(accumulatedPeriodCounts[i + 1] - 1);
    }
    int expectedWindowIndex = 0;
    for (int i = 0; i < timeline.getPeriodCount(); i++) {
        timeline.getPeriod(i, period, true);
        while (i >= accumulatedPeriodCounts[expectedWindowIndex + 1]) {
            expectedWindowIndex++;
        }
        assertThat(period.windowIndex).isEqualTo(expectedWindowIndex);
        Object periodUid = Assertions.checkNotNull(period.uid);
        assertThat(timeline.getIndexOfPeriod(periodUid)).isEqualTo(i);
        assertThat(timeline.getUidOfPeriod(i)).isEqualTo(periodUid);
        for (int repeatMode : REPEAT_MODES) {
            if (i < accumulatedPeriodCounts[expectedWindowIndex + 1] - 1) {
                assertThat(timeline.getNextPeriodIndex(i, period, window, repeatMode, false)).isEqualTo(i + 1);
            } else {
                int nextWindow = timeline.getNextWindowIndex(expectedWindowIndex, repeatMode, false);
                int nextPeriod = nextWindow == C.INDEX_UNSET ? C.INDEX_UNSET : accumulatedPeriodCounts[nextWindow];
                assertThat(timeline.getNextPeriodIndex(i, period, window, repeatMode, false)).isEqualTo(nextPeriod);
            }
        }
    }
}
Also used : Window(com.google.android.exoplayer2.Timeline.Window) Period(com.google.android.exoplayer2.Timeline.Period)

Example 59 with Assertions.checkNotNull

use of com.google.android.exoplayer2.util.Assertions.checkNotNull in project ExoPlayer by google.

the class MediaCodecRenderer method maybeInitCodecOrBypass.

protected final void maybeInitCodecOrBypass() throws ExoPlaybackException {
    if (codec != null || bypassEnabled || inputFormat == null) {
        // We have a codec, are bypassing it, or don't have a format to decide how to render.
        return;
    }
    if (sourceDrmSession == null && shouldUseBypass(inputFormat)) {
        initBypass(inputFormat);
        return;
    }
    setCodecDrmSession(sourceDrmSession);
    String mimeType = inputFormat.sampleMimeType;
    if (codecDrmSession != null) {
        if (mediaCrypto == null) {
            @Nullable FrameworkCryptoConfig sessionCryptoConfig = getFrameworkCryptoConfig(codecDrmSession);
            if (sessionCryptoConfig == null) {
                @Nullable DrmSessionException drmError = codecDrmSession.getError();
                if (drmError != null) {
                // Continue for now. We may be able to avoid failure if a new input format causes the
                // session to be replaced without it having been used.
                } else {
                    // The drm session isn't open yet.
                    return;
                }
            } else {
                try {
                    mediaCrypto = new MediaCrypto(sessionCryptoConfig.uuid, sessionCryptoConfig.sessionId);
                } catch (MediaCryptoException e) {
                    throw createRendererException(e, inputFormat, PlaybackException.ERROR_CODE_DRM_SYSTEM_ERROR);
                }
                mediaCryptoRequiresSecureDecoder = !sessionCryptoConfig.forceAllowInsecureDecoderComponents && mediaCrypto.requiresSecureDecoderComponent(mimeType);
            }
        }
        if (FrameworkCryptoConfig.WORKAROUND_DEVICE_NEEDS_KEYS_TO_CONFIGURE_CODEC) {
            @DrmSession.State int drmSessionState = codecDrmSession.getState();
            if (drmSessionState == DrmSession.STATE_ERROR) {
                DrmSessionException drmSessionException = Assertions.checkNotNull(codecDrmSession.getError());
                throw createRendererException(drmSessionException, inputFormat, drmSessionException.errorCode);
            } else if (drmSessionState != DrmSession.STATE_OPENED_WITH_KEYS) {
                // Wait for keys.
                return;
            }
        }
    }
    try {
        maybeInitCodecWithFallback(mediaCrypto, mediaCryptoRequiresSecureDecoder);
    } catch (DecoderInitializationException e) {
        throw createRendererException(e, inputFormat, PlaybackException.ERROR_CODE_DECODER_INIT_FAILED);
    }
}
Also used : DrmSessionException(com.google.android.exoplayer2.drm.DrmSession.DrmSessionException) FrameworkCryptoConfig(com.google.android.exoplayer2.drm.FrameworkCryptoConfig) Nullable(androidx.annotation.Nullable) MediaCrypto(android.media.MediaCrypto) MediaCryptoException(android.media.MediaCryptoException)

Example 60 with Assertions.checkNotNull

use of com.google.android.exoplayer2.util.Assertions.checkNotNull in project ExoPlayer by google.

the class SegmentDownloader method download.

@Override
public final void download(@Nullable ProgressListener progressListener) throws IOException, InterruptedException {
    ArrayDeque<Segment> pendingSegments = new ArrayDeque<>();
    ArrayDeque<SegmentDownloadRunnable> recycledRunnables = new ArrayDeque<>();
    if (priorityTaskManager != null) {
        priorityTaskManager.add(C.PRIORITY_DOWNLOAD);
    }
    try {
        CacheDataSource dataSource = cacheDataSourceFactory.createDataSourceForDownloading();
        // Get the manifest and all of the segments.
        M manifest = getManifest(dataSource, manifestDataSpec, /* removing= */
        false);
        if (!streamKeys.isEmpty()) {
            manifest = manifest.copy(streamKeys);
        }
        List<Segment> segments = getSegments(dataSource, manifest, /* removing= */
        false);
        // Sort the segments so that we download media in the right order from the start of the
        // content, and merge segments where possible to minimize the number of server round trips.
        Collections.sort(segments);
        mergeSegments(segments, cacheKeyFactory);
        // Scan the segments, removing any that are fully downloaded.
        int totalSegments = segments.size();
        int segmentsDownloaded = 0;
        long contentLength = 0;
        long bytesDownloaded = 0;
        for (int i = segments.size() - 1; i >= 0; i--) {
            DataSpec dataSpec = segments.get(i).dataSpec;
            String cacheKey = cacheKeyFactory.buildCacheKey(dataSpec);
            long segmentLength = dataSpec.length;
            if (segmentLength == C.LENGTH_UNSET) {
                long resourceLength = ContentMetadata.getContentLength(cache.getContentMetadata(cacheKey));
                if (resourceLength != C.LENGTH_UNSET) {
                    segmentLength = resourceLength - dataSpec.position;
                }
            }
            long segmentBytesDownloaded = cache.getCachedBytes(cacheKey, dataSpec.position, segmentLength);
            bytesDownloaded += segmentBytesDownloaded;
            if (segmentLength != C.LENGTH_UNSET) {
                if (segmentLength == segmentBytesDownloaded) {
                    // The segment is fully downloaded.
                    segmentsDownloaded++;
                    segments.remove(i);
                }
                if (contentLength != C.LENGTH_UNSET) {
                    contentLength += segmentLength;
                }
            } else {
                contentLength = C.LENGTH_UNSET;
            }
        }
        // Download the segments.
        @Nullable ProgressNotifier progressNotifier = progressListener != null ? new ProgressNotifier(progressListener, contentLength, totalSegments, bytesDownloaded, segmentsDownloaded) : null;
        pendingSegments.addAll(segments);
        while (!isCanceled && !pendingSegments.isEmpty()) {
            // Block until there aren't any higher priority tasks.
            if (priorityTaskManager != null) {
                priorityTaskManager.proceed(C.PRIORITY_DOWNLOAD);
            }
            // Create and execute a runnable to download the next segment.
            CacheDataSource segmentDataSource;
            byte[] temporaryBuffer;
            if (!recycledRunnables.isEmpty()) {
                SegmentDownloadRunnable recycledRunnable = recycledRunnables.removeFirst();
                segmentDataSource = recycledRunnable.dataSource;
                temporaryBuffer = recycledRunnable.temporaryBuffer;
            } else {
                segmentDataSource = cacheDataSourceFactory.createDataSourceForDownloading();
                temporaryBuffer = new byte[BUFFER_SIZE_BYTES];
            }
            Segment segment = pendingSegments.removeFirst();
            SegmentDownloadRunnable downloadRunnable = new SegmentDownloadRunnable(segment, segmentDataSource, progressNotifier, temporaryBuffer);
            addActiveRunnable(downloadRunnable);
            executor.execute(downloadRunnable);
            // Clean up runnables that have finished.
            for (int j = activeRunnables.size() - 1; j >= 0; j--) {
                SegmentDownloadRunnable activeRunnable = (SegmentDownloadRunnable) activeRunnables.get(j);
                // it's already finished.
                if (pendingSegments.isEmpty() || activeRunnable.isDone()) {
                    try {
                        activeRunnable.get();
                        removeActiveRunnable(j);
                        recycledRunnables.addLast(activeRunnable);
                    } catch (ExecutionException e) {
                        Throwable cause = Assertions.checkNotNull(e.getCause());
                        if (cause instanceof PriorityTooLowException) {
                            // We need to schedule this segment again in a future loop iteration.
                            pendingSegments.addFirst(activeRunnable.segment);
                            removeActiveRunnable(j);
                            recycledRunnables.addLast(activeRunnable);
                        } else if (cause instanceof IOException) {
                            throw (IOException) cause;
                        } else {
                            // The cause must be an uncaught Throwable type.
                            Util.sneakyThrow(cause);
                        }
                    }
                }
            }
            // Don't move on to the next segment until the runnable for this segment has started. This
            // drip feeds runnables to the executor, rather than providing them all up front.
            downloadRunnable.blockUntilStarted();
        }
    } finally {
        // Cancel them to speed this up.
        for (int i = 0; i < activeRunnables.size(); i++) {
            activeRunnables.get(i).cancel(/* interruptIfRunning= */
            true);
        }
        // do this for the case where the main download thread was interrupted as part of cancelation.
        for (int i = activeRunnables.size() - 1; i >= 0; i--) {
            activeRunnables.get(i).blockUntilFinished();
            removeActiveRunnable(i);
        }
        if (priorityTaskManager != null) {
            priorityTaskManager.remove(C.PRIORITY_DOWNLOAD);
        }
    }
}
Also used : IOException(java.io.IOException) ArrayDeque(java.util.ArrayDeque) PriorityTooLowException(com.google.android.exoplayer2.util.PriorityTaskManager.PriorityTooLowException) CacheDataSource(com.google.android.exoplayer2.upstream.cache.CacheDataSource) DataSpec(com.google.android.exoplayer2.upstream.DataSpec) ExecutionException(java.util.concurrent.ExecutionException) Nullable(androidx.annotation.Nullable)

Aggregations

Nullable (androidx.annotation.Nullable)28 Format (com.google.android.exoplayer2.Format)10 ArrayList (java.util.ArrayList)9 MediaItem (com.google.android.exoplayer2.MediaItem)8 DataSpec (com.google.android.exoplayer2.upstream.DataSpec)5 Matcher (java.util.regex.Matcher)5 SuppressLint (android.annotation.SuppressLint)4 Context (android.content.Context)4 Uri (android.net.Uri)4 MediaSource (com.google.android.exoplayer2.source.MediaSource)4 DataSource (com.google.android.exoplayer2.upstream.DataSource)4 StatsDataSource (com.google.android.exoplayer2.upstream.StatsDataSource)4 Activity (android.app.Activity)3 Intent (android.content.Intent)3 SQLException (android.database.SQLException)3 SQLiteDatabase (android.database.sqlite.SQLiteDatabase)3 Bundle (android.os.Bundle)3 CallbackMediaItem (androidx.media2.common.CallbackMediaItem)3 C (com.google.android.exoplayer2.C)3 ExoPlayer (com.google.android.exoplayer2.ExoPlayer)3