use of com.google.android.exoplayer2.MediaItem in project ExoPlayer by google.
the class DashMediaSource method processManifest.
private void processManifest(boolean scheduleRefresh) {
// Update any periods.
for (int i = 0; i < periodsById.size(); i++) {
int id = periodsById.keyAt(i);
if (id >= firstPeriodId) {
periodsById.valueAt(i).updateManifest(manifest, id - firstPeriodId);
} else {
// This period has been removed from the manifest so it doesn't need to be updated.
}
}
// Update the window.
Period firstPeriod = manifest.getPeriod(0);
int lastPeriodIndex = manifest.getPeriodCount() - 1;
Period lastPeriod = manifest.getPeriod(lastPeriodIndex);
long lastPeriodDurationUs = manifest.getPeriodDurationUs(lastPeriodIndex);
long nowUnixTimeUs = Util.msToUs(Util.getNowUnixTimeMs(elapsedRealtimeOffsetMs));
long windowStartTimeInManifestUs = getAvailableStartTimeInManifestUs(firstPeriod, manifest.getPeriodDurationUs(0), nowUnixTimeUs);
long windowEndTimeInManifestUs = getAvailableEndTimeInManifestUs(lastPeriod, lastPeriodDurationUs, nowUnixTimeUs);
boolean windowChangingImplicitly = manifest.dynamic && !isIndexExplicit(lastPeriod);
if (windowChangingImplicitly && manifest.timeShiftBufferDepthMs != C.TIME_UNSET) {
// Update the available start time to reflect the manifest's time shift buffer depth.
long timeShiftBufferStartTimeInManifestUs = windowEndTimeInManifestUs - Util.msToUs(manifest.timeShiftBufferDepthMs);
windowStartTimeInManifestUs = max(windowStartTimeInManifestUs, timeShiftBufferStartTimeInManifestUs);
}
long windowDurationUs = windowEndTimeInManifestUs - windowStartTimeInManifestUs;
long windowStartUnixTimeMs = C.TIME_UNSET;
long windowDefaultPositionUs = 0;
if (manifest.dynamic) {
checkState(manifest.availabilityStartTimeMs != C.TIME_UNSET);
long nowInWindowUs = nowUnixTimeUs - Util.msToUs(manifest.availabilityStartTimeMs) - windowStartTimeInManifestUs;
updateLiveConfiguration(nowInWindowUs, windowDurationUs);
windowStartUnixTimeMs = manifest.availabilityStartTimeMs + Util.usToMs(windowStartTimeInManifestUs);
windowDefaultPositionUs = nowInWindowUs - Util.msToUs(liveConfiguration.targetOffsetMs);
long minimumWindowDefaultPositionUs = min(MIN_LIVE_DEFAULT_START_POSITION_US, windowDurationUs / 2);
if (windowDefaultPositionUs < minimumWindowDefaultPositionUs) {
// The default position is too close to the start of the live window. Set it to the minimum
// default position provided the window is at least twice as big. Else set it to the middle
// of the window.
windowDefaultPositionUs = minimumWindowDefaultPositionUs;
}
}
long offsetInFirstPeriodUs = windowStartTimeInManifestUs - Util.msToUs(firstPeriod.startMs);
DashTimeline timeline = new DashTimeline(manifest.availabilityStartTimeMs, windowStartUnixTimeMs, elapsedRealtimeOffsetMs, firstPeriodId, offsetInFirstPeriodUs, windowDurationUs, windowDefaultPositionUs, manifest, mediaItem, manifest.dynamic ? liveConfiguration : null);
refreshSourceInfo(timeline);
if (!sideloadedManifest) {
// Remove any pending simulated refresh.
handler.removeCallbacks(simulateManifestRefreshRunnable);
// If the window is changing implicitly, post a simulated manifest refresh to update it.
if (windowChangingImplicitly) {
handler.postDelayed(simulateManifestRefreshRunnable, getIntervalUntilNextManifestRefreshMs(manifest, Util.getNowUnixTimeMs(elapsedRealtimeOffsetMs)));
}
if (manifestLoadPending) {
startLoadingManifest();
} else if (scheduleRefresh && manifest.dynamic && manifest.minUpdatePeriodMs != C.TIME_UNSET) {
// Schedule an explicit refresh if needed.
long minUpdatePeriodMs = manifest.minUpdatePeriodMs;
if (minUpdatePeriodMs == 0) {
// TODO: This is a temporary hack to avoid constantly refreshing the MPD in cases where
// minimumUpdatePeriod is set to 0. In such cases we shouldn't refresh unless there is
// explicit signaling in the stream, according to:
// http://azure.microsoft.com/blog/2014/09/13/dash-live-streaming-with-azure-media-service
minUpdatePeriodMs = 5000;
}
long nextLoadTimestampMs = manifestLoadStartTimestampMs + minUpdatePeriodMs;
long delayUntilNextLoadMs = max(0, nextLoadTimestampMs - SystemClock.elapsedRealtime());
scheduleManifestRefresh(delayUntilNextLoadMs);
}
}
}
use of com.google.android.exoplayer2.MediaItem in project ExoPlayer by google.
the class SsMediaSource method processManifest.
// Internal methods
private void processManifest() {
for (int i = 0; i < mediaPeriods.size(); i++) {
mediaPeriods.get(i).updateManifest(manifest);
}
long startTimeUs = Long.MAX_VALUE;
long endTimeUs = Long.MIN_VALUE;
for (StreamElement element : manifest.streamElements) {
if (element.chunkCount > 0) {
startTimeUs = min(startTimeUs, element.getStartTimeUs(0));
endTimeUs = max(endTimeUs, element.getStartTimeUs(element.chunkCount - 1) + element.getChunkDurationUs(element.chunkCount - 1));
}
}
Timeline timeline;
if (startTimeUs == Long.MAX_VALUE) {
long periodDurationUs = manifest.isLive ? C.TIME_UNSET : 0;
timeline = new SinglePeriodTimeline(periodDurationUs, /* windowDurationUs= */
0, /* windowPositionInPeriodUs= */
0, /* windowDefaultStartPositionUs= */
0, /* isSeekable= */
true, /* isDynamic= */
manifest.isLive, /* useLiveConfiguration= */
manifest.isLive, manifest, mediaItem);
} else if (manifest.isLive) {
if (manifest.dvrWindowLengthUs != C.TIME_UNSET && manifest.dvrWindowLengthUs > 0) {
startTimeUs = max(startTimeUs, endTimeUs - manifest.dvrWindowLengthUs);
}
long durationUs = endTimeUs - startTimeUs;
long defaultStartPositionUs = durationUs - Util.msToUs(livePresentationDelayMs);
if (defaultStartPositionUs < MIN_LIVE_DEFAULT_START_POSITION_US) {
// The default start position is too close to the start of the live window. Set it to the
// minimum default start position provided the window is at least twice as big. Else set
// it to the middle of the window.
defaultStartPositionUs = min(MIN_LIVE_DEFAULT_START_POSITION_US, durationUs / 2);
}
timeline = new SinglePeriodTimeline(/* periodDurationUs= */
C.TIME_UNSET, durationUs, startTimeUs, defaultStartPositionUs, /* isSeekable= */
true, /* isDynamic= */
true, /* useLiveConfiguration= */
true, manifest, mediaItem);
} else {
long durationUs = manifest.durationUs != C.TIME_UNSET ? manifest.durationUs : endTimeUs - startTimeUs;
timeline = new SinglePeriodTimeline(startTimeUs + durationUs, durationUs, startTimeUs, /* windowDefaultStartPositionUs= */
0, /* isSeekable= */
true, /* isDynamic= */
false, /* useLiveConfiguration= */
false, manifest, mediaItem);
}
refreshSourceInfo(timeline);
}
use of com.google.android.exoplayer2.MediaItem in project ExoPlayer by google.
the class TransformerEndToEndTest method startTransformation_audioOnlyTranscoding_completesSuccessfully.
@Test
public void startTransformation_audioOnlyTranscoding_completesSuccessfully() throws Exception {
Transformer transformer = createTransformerBuilder().setTransformationRequest(new TransformationRequest.Builder().setAudioMimeType(// supported by encoder and muxer
MimeTypes.AUDIO_AAC).build()).build();
MediaItem mediaItem = MediaItem.fromUri(URI_PREFIX + FILE_AUDIO_UNSUPPORTED_BY_ENCODER);
transformer.startTransformation(mediaItem, outputPath);
TransformerTestRunner.runUntilCompleted(transformer);
DumpFileAsserts.assertOutput(context, testMuxer, getDumpFileName(FILE_AUDIO_UNSUPPORTED_BY_ENCODER + ".aac"));
}
use of com.google.android.exoplayer2.MediaItem in project ExoPlayer by google.
the class TransformerEndToEndTest method startTransformation_fromWrongThread_throwsError.
@Test
public void startTransformation_fromWrongThread_throwsError() throws Exception {
Transformer transformer = createTransformerBuilder().build();
MediaItem mediaItem = MediaItem.fromUri(URI_PREFIX + FILE_AUDIO_VIDEO);
HandlerThread anotherThread = new HandlerThread("AnotherThread");
AtomicReference<IllegalStateException> illegalStateException = new AtomicReference<>();
CountDownLatch countDownLatch = new CountDownLatch(1);
anotherThread.start();
new Handler(anotherThread.getLooper()).post(() -> {
try {
transformer.startTransformation(mediaItem, outputPath);
} catch (IOException e) {
// Do nothing.
} catch (IllegalStateException e) {
illegalStateException.set(e);
} finally {
countDownLatch.countDown();
}
});
countDownLatch.await();
assertThat(illegalStateException.get()).isNotNull();
}
use of com.google.android.exoplayer2.MediaItem in project ExoPlayer by google.
the class TransformerEndToEndTest method startTransformation_concurrentTransformations_throwsError.
@Test
public void startTransformation_concurrentTransformations_throwsError() throws Exception {
Transformer transformer = createTransformerBuilder().build();
MediaItem mediaItem = MediaItem.fromUri(URI_PREFIX + FILE_VIDEO_ONLY);
transformer.startTransformation(mediaItem, outputPath);
assertThrows(IllegalStateException.class, () -> transformer.startTransformation(mediaItem, outputPath));
}
Aggregations