Compare commits

...

4 Commits

Author SHA1 Message Date
tonihei
68538029c9 Fix getChildPeriod logic if the child is a TimeOffsetMediaPeriod
The current instanceof check accidentally unpacks the child,
returning the inner period instead of the one passed to the source.

PiperOrigin-RevId: 746556825
2025-04-11 12:45:01 -07:00
bachinger
21faf85382 Load asset list 3 target durations before ad start time
This makes sure that the asset list is loaded about the
same duration before the ad start as on other platforms.

Further, interstitials in live streams are taken into
account when 3 target durations before the live window.
This enables the ads loader to preload such ads in a
future change. This may be indicated for live streams
that should play as close to the live edge as possible.
In such a case the buffered position may reach the start
of the ad only late. Preloading could help here to
decrease the performance requirements of ad servers.

PiperOrigin-RevId: 746521261
2025-04-11 11:00:56 -07:00
rohks
6f5982792a Derive average bitrate from stsz sample size and mdhd duration
Compute a precise average bitrate using total sample size (from `stsz`) and media duration (from `mdhd`), overriding any existing bitrate read from `btrt` or `esds` boxes.

PiperOrigin-RevId: 746497934
2025-04-11 09:58:18 -07:00
tianyifeng
344f249511 Fix issue where ProgressiveMediaPeriod fails assertPrepared
In `PreloadMediaSource` we accesses the `MediaPeriod.getBufferedPositionUs()` when we receive `onContinueLoadingRequested()` from the period. For `ProgressiveMediaPeriod` which requires loading a portion of media file to get it prepared, there is a chance that it needs more than one round of `onContinueLoadingRequested()` -> `continueLoading()` to complete preparation, for example, when the  `setContinueLoadingIntervalBytes()` is small enough to not include the full information for preparation. Thus we should avoid `MediaPeriod.getBufferedPositionUs()` being called before period is prepared, as it will fail at `assertPrepared`.

Issue: androidx/media#2315

#cherrypick

PiperOrigin-RevId: 746490375
2025-04-11 09:34:57 -07:00
452 changed files with 751 additions and 187 deletions

View File

@ -21,6 +21,10 @@
groups have been removed. The user still needs to pass in an array of
durations for removed ad groups which can be empty or null
([#2267](https://github.com/androidx/media/issues/2267)).
* Fix issue where `ProgressiveMediaPeriod` throws an
`IllegalStateException` as `PreloadMediaSource` attempts to call its
`getBufferedDurationUs()` before it is prepared
([#2315](https://github.com/androidx/media/issues/2315)).
* Transformer:
* Filling an initial gap (added via `addGap()`) with silent audio now
requires explicitly setting `experimentalSetForceAudioTrack(true)` in

View File

@ -41,6 +41,7 @@ import java.util.List;
/* package */ final class MergingMediaPeriod implements MediaPeriod, MediaPeriod.Callback {
private final MediaPeriod[] periods;
private final boolean[] periodsWithTimeOffsets;
private final IdentityHashMap<SampleStream, Integer> streamPeriodIndices;
private final CompositeSequenceableLoaderFactory compositeSequenceableLoaderFactory;
private final ArrayList<MediaPeriod> childrenPendingPreparation;
@ -62,8 +63,10 @@ import java.util.List;
compositeSequenceableLoader = compositeSequenceableLoaderFactory.empty();
streamPeriodIndices = new IdentityHashMap<>();
enabledPeriods = new MediaPeriod[0];
periodsWithTimeOffsets = new boolean[periods.length];
for (int i = 0; i < periods.length; i++) {
if (periodTimeOffsetsUs[i] != 0) {
periodsWithTimeOffsets[i] = true;
this.periods[i] = new TimeOffsetMediaPeriod(periods[i], periodTimeOffsetsUs[i]);
}
}
@ -75,7 +78,7 @@ import java.util.List;
* specified index.
*/
public MediaPeriod getChildPeriod(int index) {
return periods[index] instanceof TimeOffsetMediaPeriod
return periodsWithTimeOffsets[index]
? ((TimeOffsetMediaPeriod) periods[index]).getWrappedMediaPeriod()
: periods[index];
}

View File

@ -505,17 +505,18 @@ public final class PreloadMediaSource extends WrappingMediaSource {
return;
}
PreloadMediaPeriod preloadMediaPeriod = (PreloadMediaPeriod) mediaPeriod;
long bufferedPositionUs = mediaPeriod.getBufferedPositionUs();
if (prepared && bufferedPositionUs == C.TIME_END_OF_SOURCE) {
preloadControl.onLoadedToTheEndOfSource(PreloadMediaSource.this);
stopPreloading();
return;
}
if (prepared
&& !preloadControl.onContinueLoadingRequested(
PreloadMediaSource.this, bufferedPositionUs - periodStartPositionUs)) {
stopPreloading();
return;
if (prepared) {
long bufferedPositionUs = mediaPeriod.getBufferedPositionUs();
if (bufferedPositionUs == C.TIME_END_OF_SOURCE) {
preloadControl.onLoadedToTheEndOfSource(PreloadMediaSource.this);
stopPreloading();
return;
}
if (!preloadControl.onContinueLoadingRequested(
PreloadMediaSource.this, bufferedPositionUs - periodStartPositionUs)) {
stopPreloading();
return;
}
}
preloadMediaPeriod.continueLoading(
new LoadingInfo.Builder().setPlaybackPositionUs(periodStartPositionUs).build());

View File

@ -22,6 +22,7 @@ import static com.google.common.truth.Truth.assertThat;
import androidx.media3.common.C;
import androidx.media3.common.Format;
import androidx.media3.common.MimeTypes;
import androidx.media3.common.TrackGroup;
import androidx.media3.common.util.NullableType;
import androidx.media3.decoder.DecoderInputBuffer;
@ -33,6 +34,7 @@ import androidx.media3.exoplayer.source.MediaSource.MediaPeriodId;
import androidx.media3.exoplayer.source.MediaSourceEventListener.EventDispatcher;
import androidx.media3.exoplayer.trackselection.ExoTrackSelection;
import androidx.media3.exoplayer.trackselection.FixedTrackSelection;
import androidx.media3.exoplayer.upstream.Allocator;
import androidx.media3.exoplayer.upstream.DefaultAllocator;
import androidx.media3.test.utils.FakeMediaPeriod;
import androidx.test.ext.junit.runners.AndroidJUnit4;
@ -270,6 +272,39 @@ public final class MergingMediaPeriodTest {
assertThat(inputBuffer.timeUs).isEqualTo(456_000 - 3000);
}
@Test
public void
getChildPeriod_withTimeOffsetsAndTimeOffsetPeriodChildren_returnsCorrectChildPeriod() {
TrackGroupArray trackGroupArray =
new TrackGroupArray(
new TrackGroup(new Format.Builder().setSampleMimeType(MimeTypes.VIDEO_AV1).build()));
Allocator allocator =
new DefaultAllocator(/* trimOnReset= */ false, /* individualAllocationSize= */ 1024);
MediaPeriod childPeriod0 =
new FakeMediaPeriod(
trackGroupArray, allocator, /* singleSampleTimeUs= */ 0, new EventDispatcher());
MediaPeriod childPeriod1 =
new TimeOffsetMediaPeriod(
new FakeMediaPeriod(
trackGroupArray, allocator, /* singleSampleTimeUs= */ 300, new EventDispatcher()),
/* timeOffsetUs= */ -300);
MediaPeriod childPeriod2 =
new FakeMediaPeriod(
trackGroupArray, allocator, /* singleSampleTimeUs= */ -500, new EventDispatcher());
MergingMediaPeriod mergingMediaPeriod =
new MergingMediaPeriod(
new DefaultCompositeSequenceableLoaderFactory(),
/* periodTimeOffsetsUs= */ new long[] {0, 0, 500},
childPeriod0,
childPeriod1,
childPeriod2);
assertThat(mergingMediaPeriod.getChildPeriod(0)).isEqualTo(childPeriod0);
assertThat(mergingMediaPeriod.getChildPeriod(1)).isEqualTo(childPeriod1);
assertThat(mergingMediaPeriod.getChildPeriod(2)).isEqualTo(childPeriod2);
}
private MergingMediaPeriod prepareMergingPeriod(MergingPeriodDefinition... definitions)
throws Exception {
return prepareMergingPeriod(/* singleTrackGroup= */ false, definitions);

View File

@ -90,12 +90,13 @@ import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
public final class PreloadMediaSourceTest {
private static final int LOADING_CHECK_INTERVAL_BYTES = 10 * 1024;
private static final int LOADING_CHECK_INTERVAL_BYTES = 32;
private static final int TARGET_PRELOAD_DURATION_US = 10000;
private Allocator allocator;
private BandwidthMeter bandwidthMeter;
private RenderersFactory renderersFactory;
private MediaItem mediaItem;
@Before
public void setUp() {
@ -112,6 +113,10 @@ public final class PreloadMediaSourceTest {
SystemClock.DEFAULT.createHandler(handler.getLooper(), /* callback= */ null),
audioListener)
};
mediaItem =
new MediaItem.Builder()
.setUri(Uri.parse("asset://android_asset/media/mp4/long_1080p_lowbitrate.mp4"))
.build();
}
@Test
@ -146,11 +151,7 @@ public final class PreloadMediaSourceTest {
getRendererCapabilities(renderersFactory),
allocator,
Util.getCurrentOrMainLooper());
PreloadMediaSource preloadMediaSource =
preloadMediaSourceFactory.createMediaSource(
new MediaItem.Builder()
.setUri(Uri.parse("asset://android_asset/media/mp4/sample.mp4"))
.build());
PreloadMediaSource preloadMediaSource = preloadMediaSourceFactory.createMediaSource(mediaItem);
preloadMediaSource.preload(/* startPositionUs= */ 0L);
runMainLooperUntil(() -> preloadMediaSourceReference.get() != null);
@ -191,11 +192,7 @@ public final class PreloadMediaSourceTest {
getRendererCapabilities(renderersFactory),
allocator,
Util.getCurrentOrMainLooper());
PreloadMediaSource preloadMediaSource =
preloadMediaSourceFactory.createMediaSource(
new MediaItem.Builder()
.setUri(Uri.parse("asset://android_asset/media/mp4/sample.mp4"))
.build());
PreloadMediaSource preloadMediaSource = preloadMediaSourceFactory.createMediaSource(mediaItem);
preloadMediaSource.preload(/* startPositionUs= */ 0L);
runMainLooperUntil(() -> preloadMediaSourceReference.get() != null);
@ -235,11 +232,7 @@ public final class PreloadMediaSourceTest {
getRendererCapabilities(renderersFactory),
allocator,
Util.getCurrentOrMainLooper());
PreloadMediaSource preloadMediaSource =
preloadMediaSourceFactory.createMediaSource(
new MediaItem.Builder()
.setUri(Uri.parse("asset://android_asset/media/mp4/sample.mp4"))
.build());
PreloadMediaSource preloadMediaSource = preloadMediaSourceFactory.createMediaSource(mediaItem);
preloadMediaSource.preload(/* startPositionUs= */ 0L);
shadowOf(Looper.getMainLooper()).idle();
@ -266,11 +259,7 @@ public final class PreloadMediaSourceTest {
getRendererCapabilities(renderersFactory),
allocator,
Util.getCurrentOrMainLooper());
PreloadMediaSource preloadMediaSource =
preloadMediaSourceFactory.createMediaSource(
new MediaItem.Builder()
.setUri(Uri.parse("asset://android_asset/media/mp4/sample.mp4"))
.build());
PreloadMediaSource preloadMediaSource = preloadMediaSourceFactory.createMediaSource(mediaItem);
AtomicReference<MediaSource> externalCallerMediaSourceReference = new AtomicReference<>();
MediaSource.MediaSourceCaller externalCaller =
@ -315,11 +304,7 @@ public final class PreloadMediaSourceTest {
getRendererCapabilities(renderersFactory),
allocator,
Util.getCurrentOrMainLooper());
PreloadMediaSource preloadMediaSource =
preloadMediaSourceFactory.createMediaSource(
new MediaItem.Builder()
.setUri(Uri.parse("asset://android_asset/media/mp4/sample.mp4"))
.build());
PreloadMediaSource preloadMediaSource = preloadMediaSourceFactory.createMediaSource(mediaItem);
preloadMediaSource.preload(/* startPositionUs= */ 0L);
runMainLooperUntil(() -> preloadMediaSourceReference.get() != null);
@ -388,11 +373,7 @@ public final class PreloadMediaSourceTest {
getRendererCapabilities(renderersFactory),
allocator,
Util.getCurrentOrMainLooper());
PreloadMediaSource preloadMediaSource =
preloadMediaSourceFactory.createMediaSource(
new MediaItem.Builder()
.setUri(Uri.parse("asset://android_asset/media/mp4/sample.mp4"))
.build());
PreloadMediaSource preloadMediaSource = preloadMediaSourceFactory.createMediaSource(mediaItem);
preloadMediaSource.preload(/* startPositionUs= */ 0L);
runMainLooperUntil(() -> preloadExceptionReference.get() != null);
@ -472,11 +453,7 @@ public final class PreloadMediaSourceTest {
getRendererCapabilities(renderersFactory),
allocator,
Util.getCurrentOrMainLooper());
PreloadMediaSource preloadMediaSource =
preloadMediaSourceFactory.createMediaSource(
new MediaItem.Builder()
.setUri(Uri.parse("asset://android_asset/media/mp4/sample.mp4"))
.build());
PreloadMediaSource preloadMediaSource = preloadMediaSourceFactory.createMediaSource(mediaItem);
preloadMediaSource.preload(/* startPositionUs= */ 0L);
runMainLooperUntil(() -> preloadExceptionReference.get() != null);
@ -583,11 +560,7 @@ public final class PreloadMediaSourceTest {
getRendererCapabilities(renderersFactory),
allocator,
Util.getCurrentOrMainLooper());
PreloadMediaSource preloadMediaSource =
preloadMediaSourceFactory.createMediaSource(
new MediaItem.Builder()
.setUri(Uri.parse("asset://android_asset/media/mp4/sample.mp4"))
.build());
PreloadMediaSource preloadMediaSource = preloadMediaSourceFactory.createMediaSource(mediaItem);
preloadMediaSource.preload(/* startPositionUs= */ 0L);
runMainLooperUntil(() -> preloadExceptionReference.get() != null);
@ -615,11 +588,7 @@ public final class PreloadMediaSourceTest {
getRendererCapabilities(renderersFactory),
allocator,
Util.getCurrentOrMainLooper());
PreloadMediaSource preloadMediaSource =
preloadMediaSourceFactory.createMediaSource(
new MediaItem.Builder()
.setUri(Uri.parse("asset://android_asset/media/mp4/sample.mp4"))
.build());
PreloadMediaSource preloadMediaSource = preloadMediaSourceFactory.createMediaSource(mediaItem);
FakeMediaSource wrappedMediaSource = mediaSourceFactory.getLastCreatedSource();
wrappedMediaSource.setAllowPreparation(false);
preloadMediaSource.preload(/* startPositionUs= */ 0L);
@ -653,11 +622,7 @@ public final class PreloadMediaSourceTest {
getRendererCapabilities(renderersFactory),
allocator,
Util.getCurrentOrMainLooper());
PreloadMediaSource preloadMediaSource =
preloadMediaSourceFactory.createMediaSource(
new MediaItem.Builder()
.setUri(Uri.parse("asset://android_asset/media/mp4/sample.mp4"))
.build());
PreloadMediaSource preloadMediaSource = preloadMediaSourceFactory.createMediaSource(mediaItem);
preloadMediaSource.preload(/* startPositionUs= */ 0L);
shadowOf(Looper.getMainLooper()).idle();
@ -727,11 +692,7 @@ public final class PreloadMediaSourceTest {
getRendererCapabilities(renderersFactory),
allocator,
Util.getCurrentOrMainLooper());
PreloadMediaSource preloadMediaSource =
preloadMediaSourceFactory.createMediaSource(
new MediaItem.Builder()
.setUri(Uri.parse("asset://android_asset/media/mp4/sample.mp4"))
.build());
PreloadMediaSource preloadMediaSource = preloadMediaSourceFactory.createMediaSource(mediaItem);
preloadMediaSource.preload(/* startPositionUs= */ 0L);
shadowOf(Looper.getMainLooper()).idle();
@ -808,11 +769,7 @@ public final class PreloadMediaSourceTest {
getRendererCapabilities(renderersFactory),
allocator,
Util.getCurrentOrMainLooper());
PreloadMediaSource preloadMediaSource =
preloadMediaSourceFactory.createMediaSource(
new MediaItem.Builder()
.setUri(Uri.parse("asset://android_asset/media/mp4/sample.mp4"))
.build());
PreloadMediaSource preloadMediaSource = preloadMediaSourceFactory.createMediaSource(mediaItem);
preloadMediaSource.preload(/* startPositionUs= */ 0L);
shadowOf(Looper.getMainLooper()).idle();
@ -876,11 +833,7 @@ public final class PreloadMediaSourceTest {
getRendererCapabilities(renderersFactory),
allocator,
Util.getCurrentOrMainLooper());
PreloadMediaSource preloadMediaSource =
preloadMediaSourceFactory.createMediaSource(
new MediaItem.Builder()
.setUri(Uri.parse("asset://android_asset/media/mp4/sample.mp4"))
.build());
PreloadMediaSource preloadMediaSource = preloadMediaSourceFactory.createMediaSource(mediaItem);
preloadMediaSource.preload(/* startPositionUs= */ 0L);
shadowOf(Looper.getMainLooper()).idle();
@ -923,11 +876,7 @@ public final class PreloadMediaSourceTest {
getRendererCapabilities(renderersFactory),
allocator,
Util.getCurrentOrMainLooper());
PreloadMediaSource preloadMediaSource =
preloadMediaSourceFactory.createMediaSource(
new MediaItem.Builder()
.setUri(Uri.parse("asset://android_asset/media/mp4/sample.mp4"))
.build());
PreloadMediaSource preloadMediaSource = preloadMediaSourceFactory.createMediaSource(mediaItem);
AtomicBoolean externalCallerSourceInfoRefreshedCalled = new AtomicBoolean();
MediaSource.MediaSourceCaller externalCaller =
(source, timeline) -> externalCallerSourceInfoRefreshedCalled.set(true);
@ -976,11 +925,7 @@ public final class PreloadMediaSourceTest {
getRendererCapabilities(renderersFactory),
allocator,
Util.getCurrentOrMainLooper());
PreloadMediaSource preloadMediaSource =
preloadMediaSourceFactory.createMediaSource(
new MediaItem.Builder()
.setUri(Uri.parse("asset://android_asset/media/mp4/sample.mp4"))
.build());
PreloadMediaSource preloadMediaSource = preloadMediaSourceFactory.createMediaSource(mediaItem);
AtomicBoolean externalCallerSourceInfoRefreshedCalled = new AtomicBoolean();
MediaSource.MediaSourceCaller externalCaller =
(source, timeline) -> externalCallerSourceInfoRefreshedCalled.set(true);
@ -1031,11 +976,7 @@ public final class PreloadMediaSourceTest {
getRendererCapabilities(renderersFactory),
allocator,
Util.getCurrentOrMainLooper());
PreloadMediaSource preloadMediaSource =
preloadMediaSourceFactory.createMediaSource(
new MediaItem.Builder()
.setUri(Uri.parse("asset://android_asset/media/mp4/sample.mp4"))
.build());
PreloadMediaSource preloadMediaSource = preloadMediaSourceFactory.createMediaSource(mediaItem);
AtomicBoolean externalCaller1SourceInfoRefreshedCalled = new AtomicBoolean();
AtomicBoolean externalCaller2SourceInfoRefreshedCalled = new AtomicBoolean();
MediaSource.MediaSourceCaller externalCaller1 =
@ -1090,11 +1031,7 @@ public final class PreloadMediaSourceTest {
getRendererCapabilities(renderersFactory),
allocator,
Util.getCurrentOrMainLooper());
PreloadMediaSource preloadMediaSource =
preloadMediaSourceFactory.createMediaSource(
new MediaItem.Builder()
.setUri(Uri.parse("asset://android_asset/media/mp4/sample.mp4"))
.build());
PreloadMediaSource preloadMediaSource = preloadMediaSourceFactory.createMediaSource(mediaItem);
preloadMediaSource.preload(/* startPositionUs= */ 0L);
shadowOf(Looper.getMainLooper()).idle();
preloadMediaSource.releasePreloadMediaSource();
@ -1140,11 +1077,7 @@ public final class PreloadMediaSourceTest {
getRendererCapabilities(renderersFactory),
allocator,
Util.getCurrentOrMainLooper());
PreloadMediaSource preloadMediaSource =
preloadMediaSourceFactory.createMediaSource(
new MediaItem.Builder()
.setUri(Uri.parse("asset://android_asset/media/mp4/sample.mp4"))
.build());
PreloadMediaSource preloadMediaSource = preloadMediaSourceFactory.createMediaSource(mediaItem);
AtomicBoolean externalCallerSourceInfoRefreshedCalled = new AtomicBoolean();
MediaSource.MediaSourceCaller externalCaller =
(source, timeline) -> externalCallerSourceInfoRefreshedCalled.set(true);

View File

@ -786,11 +786,11 @@ public final class HlsInterstitialsAdsLoader implements AdsLoader {
nextAssetResolution.adStartTimeUs != Long.MAX_VALUE
? nextAssetResolution.adStartTimeUs
: window.durationUs;
// Load 2 times the target duration before the ad starts.
// Load 3 times the target duration before the ad starts.
resolutionStartTimeUs =
max(
currentPeriodPositionUs,
resolutionStartTimeUs - (2 * nextAssetResolution.targetDurationUs));
resolutionStartTimeUs - (3 * nextAssetResolution.targetDurationUs));
if (resolutionStartTimeUs - currentPeriodPositionUs < 200_000L) {
// Start loading immediately.
nextAssetResolution.run();
@ -923,9 +923,11 @@ public final class HlsInterstitialsAdsLoader implements AdsLoader {
}
long positionInPlaylistWindowUs =
resolveInterstitialStartTimeUs(interstitial, mediaPlaylist) - mediaPlaylist.startTimeUs;
if (positionInPlaylistWindowUs < 0 || mediaPlaylist.durationUs < positionInPlaylistWindowUs) {
if (positionInPlaylistWindowUs < 0
|| mediaPlaylist.durationUs + (3 * mediaPlaylist.targetDurationUs)
< positionInPlaylistWindowUs) {
// Ignore when behind the window including C.TIME_UNSET and C.TIME_END_OF_SOURCE.
// When not yet in the window we wait until the window advances.
// When far in the future before the window, we wait until the window advances.
continue;
}
long timeUs = windowPositionInPeriodUs + positionInPlaylistWindowUs;

View File

@ -2195,7 +2195,7 @@ public class HlsInterstitialsAdsLoaderTest {
runMainLooperUntil(assetListLoadingListener::completed, TIMEOUT_MS, Clock.DEFAULT);
verify(mockAdsLoaderListener)
.onAssetListLoadCompleted(eq(contentMediaItem), eq("adsId"), eq(0), eq(0), any());
assertThat(midRollPlayerMessage.getPositionMs()).isEqualTo(12_000L);
assertThat(midRollPlayerMessage.getPositionMs()).isEqualTo(3_000L);
assertThat(midRollPlayerMessage.getPayload()).isEqualTo(contentMediaItem);
assertThat(midRollPlayerMessage.getLooper()).isEqualTo(Looper.myLooper());
InOrder inOrder = inOrder(mockPlayer);
@ -2289,8 +2289,12 @@ public class HlsInterstitialsAdsLoaderTest {
+ "#EXT-X-PROGRAM-DATE-TIME:2020-01-02T21:00:00.000Z\n"
+ "#EXTINF:9,\n"
+ "main0.0.ts\n"
+ "#EXTINF:16.001,\n"
+ "main0.0.ts\n"
+ "#EXTINF:9,\n"
+ "main1.0.ts\n"
+ "#EXTINF:9,\n"
+ "main2.0.ts\n"
+ "#EXTINF:7.001,\n"
+ "main3.0.ts\n"
+ "#EXT-X-ENDLIST"
+ "\n"
+ "#EXT-X-DATERANGE:"
@ -2303,7 +2307,7 @@ public class HlsInterstitialsAdsLoaderTest {
+ "#EXT-X-DATERANGE:"
+ "ID=\"ad1-0\","
+ "CLASS=\"com.apple.hls.interstitial\","
+ "START-DATE=\"2020-01-02T21:00:25.000Z\","
+ "START-DATE=\"2020-01-02T21:00:34.000Z\","
+ "X-ASSET-LIST=\"http://example.com/assetlist-1-0.json\""
+ "\n";
when(mockPlayer.getContentPosition()).thenReturn(0L);
@ -2317,7 +2321,7 @@ public class HlsInterstitialsAdsLoaderTest {
/* Looper ignored */ null);
when(mockPlayer.createMessage(any())).thenReturn(midRollPlayerMessage);
AdPlaybackState expectedAdPlaybackStateAtTimelineChange =
new AdPlaybackState("adsId", 0L, 25_000_000L)
new AdPlaybackState("adsId", 0L, 34_000_000L)
.withAdCount(/* adGroupIndex= */ 0, 1)
.withAdCount(/* adGroupIndex= */ 1, 1)
.withAdId(/* adGroupIndex= */ 0, /* adIndexInAdGroup= */ 0, "ad0-0")
@ -2419,7 +2423,7 @@ public class HlsInterstitialsAdsLoaderTest {
expectedAdPlaybackStateAtTimelineChange.withAdLoadError(
/* adGroupIndex= */ 1, /* adIndexInAdGroup= */ 0))
.inOrder();
assertThat(midRollPlayerMessage.getPositionMs()).isEqualTo(33_000L);
assertThat(midRollPlayerMessage.getPositionMs()).isEqualTo(24_000L);
InOrder inOrder = inOrder(mockPlayer);
inOrder.verify(mockPlayer).addListener(any());
verifyTimelineUpdate(inOrder, mockPlayer, /* verifyMessageScheduled= */ false);
@ -2590,15 +2594,17 @@ public class HlsInterstitialsAdsLoaderTest {
+ "#EXTINF:9,\n"
+ "main0.0.ts\n"
+ "#EXTINF:9,\n"
+ "main0.0.ts\n"
+ "main1.0.ts\n"
+ "#EXTINF:9,\n"
+ "main0.0.ts\n"
+ "main2.0.ts\n"
+ "#EXTINF:9,\n"
+ "main3.0.ts\n"
+ "#EXT-X-ENDLIST"
+ "\n"
+ "#EXT-X-DATERANGE:"
+ "ID=\"ad0-0\","
+ "CLASS=\"com.apple.hls.interstitial\","
+ "START-DATE=\"2020-01-02T21:00:21.000Z\","
+ "START-DATE=\"2020-01-02T21:00:30.000Z\","
+ "X-ASSET-LIST=\"http://example.com/assetlist-0-0.json\""
+ "\n";
when(mockPlayer.getContentPosition()).thenReturn(0L);
@ -2691,7 +2697,7 @@ public class HlsInterstitialsAdsLoaderTest {
runMainLooperUntil(assetListLoadingListener::completed, TIMEOUT_MS, Clock.DEFAULT);
assertThat(midRoll2PlayerMessage.isCanceled()).isFalse();
assertThat(midRoll2PlayerMessage.getPositionMs()).isEqualTo(36_000L);
assertThat(midRoll2PlayerMessage.getPositionMs()).isEqualTo(27_000L);
assertThat(midRoll2PlayerMessage.getPayload()).isEqualTo(contentMediaItem);
assertThat(midRoll2PlayerMessage.getLooper()).isEqualTo(Looper.myLooper());
}
@ -2848,15 +2854,15 @@ public class HlsInterstitialsAdsLoaderTest {
TIMEOUT_MS,
Clock.DEFAULT);
assertThat(midRoll1PlayerMessage.isCanceled()).isTrue();
assertThat(midRoll1PlayerMessage.getPositionMs()).isEqualTo(12_000L);
assertThat(midRoll1PlayerMessage.getPositionMs()).isEqualTo(3_000L);
assertThat(midRoll1PlayerMessage.getPayload()).isEqualTo(contentMediaItem);
assertThat(midRoll1PlayerMessage.getLooper()).isEqualTo(Looper.myLooper());
assertThat(midRoll2PlayerMessage.isCanceled()).isTrue();
assertThat(midRoll2PlayerMessage.getPositionMs()).isEqualTo(36_000L);
assertThat(midRoll2PlayerMessage.getPositionMs()).isEqualTo(27_000L);
assertThat(midRoll2PlayerMessage.getPayload()).isEqualTo(contentMediaItem);
assertThat(midRoll1PlayerMessage.getLooper()).isEqualTo(Looper.myLooper());
assertThat(postRollPlayerMessage.isCanceled()).isFalse();
assertThat(postRollPlayerMessage.getPositionMs()).isEqualTo(72_000L);
assertThat(postRollPlayerMessage.getPositionMs()).isEqualTo(63_000L);
assertThat(postRollPlayerMessage.getPayload()).isEqualTo(contentMediaItem);
assertThat(midRoll1PlayerMessage.getLooper()).isEqualTo(Looper.myLooper());
ArgumentCaptor<AssetList> argumentCaptor = ArgumentCaptor.forClass(AssetList.class);
@ -2907,7 +2913,7 @@ public class HlsInterstitialsAdsLoaderTest {
+ "#EXT-X-DATERANGE:"
+ "ID=\"ad0-0\","
+ "CLASS=\"com.apple.hls.interstitial\","
+ "START-DATE=\"2020-01-02T21:00:21.000Z\","
+ "START-DATE=\"2020-01-02T21:00:30.000Z\","
+ "X-ASSET-LIST=\"http://example.com/assetlist-0-0.json\""
+ "\n"
+ "#EXT-X-DATERANGE:"
@ -2920,7 +2926,7 @@ public class HlsInterstitialsAdsLoaderTest {
Object periodUid = new Object();
when(mockPlayer.getContentPosition()).thenReturn(0L);
AdPlaybackState expectedAdPlaybackStateAtTimelineChange =
new AdPlaybackState("adsId", 21_000_000L, 51_000_000L)
new AdPlaybackState("adsId", 30_000_000L, 51_000_000L)
.withAdCount(/* adGroupIndex= */ 0, 1)
.withAdCount(/* adGroupIndex= */ 1, 1)
.withAdId(/* adGroupIndex= */ 0, /* adIndexInAdGroup= */ 0, "ad0-0")
@ -2983,7 +2989,7 @@ public class HlsInterstitialsAdsLoaderTest {
assertThat(midRoll1PlayerMessage.getPositionMs()).isEqualTo(3_000L);
assertThat(midRoll1PlayerMessage.getPayload()).isEqualTo(contentMediaItem);
assertThat(midRoll2PlayerMessage.isCanceled()).isFalse();
assertThat(midRoll2PlayerMessage.getPositionMs()).isEqualTo(33_000L);
assertThat(midRoll2PlayerMessage.getPositionMs()).isEqualTo(24_000L);
assertThat(midRoll2PlayerMessage.getPayload()).isEqualTo(contentMediaItem);
ArgumentCaptor<AdPlaybackState> adPlaybackStateCaptor =
ArgumentCaptor.forClass(AdPlaybackState.class);
@ -3015,15 +3021,17 @@ public class HlsInterstitialsAdsLoaderTest {
+ "#EXTINF:9,\n"
+ "main0.0.ts\n"
+ "#EXTINF:9,\n"
+ "main0.0.ts\n"
+ "main1.0.ts\n"
+ "#EXTINF:9,\n"
+ "main0.0.ts\n"
+ "main2.0.ts\n"
+ "#EXTINF:9,\n"
+ "main3.0.ts\n"
+ "#EXT-X-ENDLIST"
+ "\n"
+ "#EXT-X-DATERANGE:"
+ "ID=\"ad0-0\","
+ "CLASS=\"com.apple.hls.interstitial\","
+ "START-DATE=\"2020-01-02T21:00:21.000Z\","
+ "START-DATE=\"2020-01-02T21:00:30.000Z\","
+ "X-ASSET-LIST=\"http://example.com/assetlist-0-0.json\""
+ "\n";
when(mockPlayer.getContentPosition()).thenReturn(0L);

View File

@ -55,6 +55,7 @@ import androidx.media3.extractor.VorbisUtil;
import com.google.common.base.Function;
import com.google.common.collect.ImmutableList;
import com.google.common.primitives.Ints;
import java.math.RoundingMode;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.ArrayList;
@ -527,6 +528,7 @@ public final class BoxParser {
int[] flags;
long timestampTimeUnits = 0;
long duration;
long totalSize = 0;
if (rechunkFixedSizeSamples) {
long[] chunkOffsetsBytes = new long[chunkIterator.length];
@ -544,6 +546,7 @@ public final class BoxParser {
timestamps = rechunkedResults.timestamps;
flags = rechunkedResults.flags;
duration = rechunkedResults.duration;
totalSize = rechunkedResults.totalSize;
} else {
offsets = new long[sampleCount];
sizes = new int[sampleCount];
@ -586,6 +589,7 @@ public final class BoxParser {
offsets[i] = offset;
sizes[i] = sampleSizeBox.readNextSampleSize();
totalSize += sizes[i];
if (sizes[i] > maximumSize) {
maximumSize = sizes[i];
}
@ -657,6 +661,20 @@ public final class BoxParser {
+ (!isCttsValid ? ", ctts invalid" : ""));
}
}
if (track.mediaDurationUs > 0) {
long averageBitrate =
Util.scaleLargeValue(
totalSize * C.BITS_PER_BYTE,
C.MICROS_PER_SECOND,
track.mediaDurationUs,
RoundingMode.HALF_DOWN);
if (averageBitrate > 0 && averageBitrate < Integer.MAX_VALUE) {
Format format = track.format.buildUpon().setAverageBitrate((int) averageBitrate).build();
track = track.copyWithFormat(format);
}
}
long durationUs = Util.scaleLargeTimestamp(duration, C.MICROS_PER_SECOND, track.timescale);
if (track.editListDurations == null) {

View File

@ -35,6 +35,7 @@ import androidx.media3.common.util.Util;
public final long[] timestamps;
public final int[] flags;
public final long duration;
public final long totalSize;
private Results(
long[] offsets,
@ -42,13 +43,15 @@ import androidx.media3.common.util.Util;
int maximumSize,
long[] timestamps,
int[] flags,
long duration) {
long duration,
long totalSize) {
this.offsets = offsets;
this.sizes = sizes;
this.maximumSize = maximumSize;
this.timestamps = timestamps;
this.flags = flags;
this.duration = duration;
this.totalSize = totalSize;
}
}
@ -81,6 +84,7 @@ import androidx.media3.common.util.Util;
int maximumSize = 0;
long[] timestamps = new long[rechunkedSampleCount];
int[] flags = new int[rechunkedSampleCount];
int totalSize = 0;
int originalSampleIndex = 0;
int newSampleIndex = 0;
@ -93,6 +97,7 @@ import androidx.media3.common.util.Util;
offsets[newSampleIndex] = sampleOffset;
sizes[newSampleIndex] = fixedSampleSize * bufferSampleCount;
totalSize += sizes[newSampleIndex];
maximumSize = max(maximumSize, sizes[newSampleIndex]);
timestamps[newSampleIndex] = (timestampDeltaInTimeUnits * originalSampleIndex);
flags[newSampleIndex] = C.BUFFER_FLAG_KEY_FRAME;
@ -106,7 +111,7 @@ import androidx.media3.common.util.Util;
}
long duration = timestampDeltaInTimeUnits * originalSampleIndex;
return new Results(offsets, sizes, maximumSize, timestamps, flags, duration);
return new Results(offsets, sizes, maximumSize, timestamps, flags, duration, totalSize);
}
private FixedSampleSizeRechunker() {

View File

@ -11,6 +11,7 @@ track 0:
sample count = 58
track duration = 2100700
format 0:
averageBitrate = 12593505
id = 1
containerMimeType = video/mp4
sampleMimeType = video/hevc
@ -269,6 +270,7 @@ track 1:
sample count = 1
track duration = 466800
format 0:
averageBitrate = 2593047
id = 2
containerMimeType = video/mp4
sampleMimeType = video/hevc
@ -299,6 +301,7 @@ track 2:
sample count = 58
track duration = 2100700
format 0:
averageBitrate = 99395
id = 3
containerMimeType = video/mp4
sampleMimeType = application/microvideo-meta-stream
@ -541,6 +544,7 @@ track 3:
sample count = 1
track duration = 1133700
format 0:
averageBitrate = 416
id = 4
containerMimeType = video/mp4
sampleMimeType = application/motionphoto-image-meta

View File

@ -11,6 +11,7 @@ track 0:
sample count = 44
track duration = 2100700
format 0:
averageBitrate = 12593505
id = 1
containerMimeType = video/mp4
sampleMimeType = video/hevc
@ -213,6 +214,7 @@ track 1:
sample count = 1
track duration = 466800
format 0:
averageBitrate = 2593047
id = 2
containerMimeType = video/mp4
sampleMimeType = video/hevc
@ -243,6 +245,7 @@ track 2:
sample count = 38
track duration = 2100700
format 0:
averageBitrate = 99395
id = 3
containerMimeType = video/mp4
sampleMimeType = application/microvideo-meta-stream
@ -405,6 +408,7 @@ track 3:
sample count = 1
track duration = 1133700
format 0:
averageBitrate = 416
id = 4
containerMimeType = video/mp4
sampleMimeType = application/motionphoto-image-meta

View File

@ -11,6 +11,7 @@ track 0:
sample count = 23
track duration = 2100700
format 0:
averageBitrate = 12593505
id = 1
containerMimeType = video/mp4
sampleMimeType = video/hevc
@ -129,6 +130,7 @@ track 1:
sample count = 1
track duration = 466800
format 0:
averageBitrate = 2593047
id = 2
containerMimeType = video/mp4
sampleMimeType = video/hevc
@ -159,6 +161,7 @@ track 2:
sample count = 17
track duration = 2100700
format 0:
averageBitrate = 99395
id = 3
containerMimeType = video/mp4
sampleMimeType = application/microvideo-meta-stream
@ -237,6 +240,7 @@ track 3:
sample count = 1
track duration = 1133700
format 0:
averageBitrate = 416
id = 4
containerMimeType = video/mp4
sampleMimeType = application/motionphoto-image-meta

View File

@ -11,6 +11,7 @@ track 0:
sample count = 2
track duration = 2100700
format 0:
averageBitrate = 12593505
id = 1
containerMimeType = video/mp4
sampleMimeType = video/hevc
@ -45,6 +46,7 @@ track 1:
sample count = 1
track duration = 466800
format 0:
averageBitrate = 2593047
id = 2
containerMimeType = video/mp4
sampleMimeType = video/hevc
@ -75,6 +77,7 @@ track 2:
sample count = 1
track duration = 2100700
format 0:
averageBitrate = 99395
id = 3
containerMimeType = video/mp4
sampleMimeType = application/microvideo-meta-stream
@ -89,6 +92,7 @@ track 3:
sample count = 1
track duration = 1133700
format 0:
averageBitrate = 416
id = 4
containerMimeType = video/mp4
sampleMimeType = application/motionphoto-image-meta

View File

@ -11,6 +11,7 @@ track 0:
sample count = 1
track duration = 867000
format 0:
averageBitrate = 35692
id = 1
containerMimeType = video/mp4
sampleMimeType = video/avc

View File

@ -11,6 +11,7 @@ track 0:
sample count = 1
track duration = 867000
format 0:
averageBitrate = 35692
id = 1
containerMimeType = video/mp4
sampleMimeType = video/avc

View File

@ -11,6 +11,7 @@ track 0:
sample count = 1
track duration = 867000
format 0:
averageBitrate = 35692
id = 1
containerMimeType = video/mp4
sampleMimeType = video/avc

View File

@ -11,6 +11,7 @@ track 0:
sample count = 1
track duration = 867000
format 0:
averageBitrate = 35692
id = 1
containerMimeType = video/mp4
sampleMimeType = video/avc

View File

@ -11,6 +11,7 @@ track 0:
sample count = 43
track duration = 1019300
format 0:
averageBitrate = 74502
peakBitrate = 200000
id = 1
containerMimeType = video/mp4
@ -200,6 +201,7 @@ track 1:
sample count = 30
track duration = 1020100
format 0:
averageBitrate = 1026770
id = 2
containerMimeType = video/mp4
sampleMimeType = video/avc

View File

@ -11,6 +11,7 @@ track 0:
sample count = 31
track duration = 1019300
format 0:
averageBitrate = 74502
peakBitrate = 200000
id = 1
containerMimeType = video/mp4
@ -152,6 +153,7 @@ track 1:
sample count = 30
track duration = 1020100
format 0:
averageBitrate = 1026770
id = 2
containerMimeType = video/mp4
sampleMimeType = video/avc

View File

@ -11,6 +11,7 @@ track 0:
sample count = 16
track duration = 1019300
format 0:
averageBitrate = 74502
peakBitrate = 200000
id = 1
containerMimeType = video/mp4
@ -92,6 +93,7 @@ track 1:
sample count = 30
track duration = 1020100
format 0:
averageBitrate = 1026770
id = 2
containerMimeType = video/mp4
sampleMimeType = video/avc

View File

@ -11,6 +11,7 @@ track 0:
sample count = 1
track duration = 1019300
format 0:
averageBitrate = 74502
peakBitrate = 200000
id = 1
containerMimeType = video/mp4
@ -32,6 +33,7 @@ track 1:
sample count = 30
track duration = 1020100
format 0:
averageBitrate = 1026770
id = 2
containerMimeType = video/mp4
sampleMimeType = video/avc

View File

@ -11,6 +11,7 @@ track 0:
sample count = 43
track duration = 1019300
format 0:
averageBitrate = 74502
peakBitrate = 200000
id = 1
containerMimeType = video/mp4
@ -200,6 +201,7 @@ track 1:
sample count = 30
track duration = 1020100
format 0:
averageBitrate = 1026770
id = 2
containerMimeType = video/mp4
sampleMimeType = video/avc

View File

@ -11,6 +11,7 @@ track 0:
sample count = 31
track duration = 1019300
format 0:
averageBitrate = 74502
peakBitrate = 200000
id = 1
containerMimeType = video/mp4
@ -152,6 +153,7 @@ track 1:
sample count = 30
track duration = 1020100
format 0:
averageBitrate = 1026770
id = 2
containerMimeType = video/mp4
sampleMimeType = video/avc

View File

@ -11,6 +11,7 @@ track 0:
sample count = 16
track duration = 1019300
format 0:
averageBitrate = 74502
peakBitrate = 200000
id = 1
containerMimeType = video/mp4
@ -92,6 +93,7 @@ track 1:
sample count = 30
track duration = 1020100
format 0:
averageBitrate = 1026770
id = 2
containerMimeType = video/mp4
sampleMimeType = video/avc

View File

@ -11,6 +11,7 @@ track 0:
sample count = 1
track duration = 1019300
format 0:
averageBitrate = 74502
peakBitrate = 200000
id = 1
containerMimeType = video/mp4
@ -32,6 +33,7 @@ track 1:
sample count = 30
track duration = 1020100
format 0:
averageBitrate = 1026770
id = 2
containerMimeType = video/mp4
sampleMimeType = video/avc

View File

@ -11,6 +11,7 @@ track 0:
sample count = 43
track duration = 1019300
format 0:
averageBitrate = 74502
peakBitrate = 200000
id = 1
containerMimeType = video/mp4
@ -200,6 +201,7 @@ track 1:
sample count = 30
track duration = 1020100
format 0:
averageBitrate = 1026770
id = 2
containerMimeType = video/mp4
sampleMimeType = video/avc

View File

@ -11,6 +11,7 @@ track 0:
sample count = 43
track duration = 1019300
format 0:
averageBitrate = 74502
peakBitrate = 200000
id = 1
containerMimeType = video/mp4
@ -200,6 +201,7 @@ track 1:
sample count = 30
track duration = 1020100
format 0:
averageBitrate = 1026770
id = 2
containerMimeType = video/mp4
sampleMimeType = video/avc

View File

@ -11,6 +11,7 @@ track 0:
sample count = 58
track duration = 2100700
format 0:
averageBitrate = 12593505
id = 1
containerMimeType = video/mp4
sampleMimeType = video/hevc
@ -268,6 +269,7 @@ track 1:
sample count = 1
track duration = 466800
format 0:
averageBitrate = 2593047
id = 2
containerMimeType = video/mp4
sampleMimeType = video/hevc
@ -297,6 +299,7 @@ track 2:
sample count = 58
track duration = 2100700
format 0:
averageBitrate = 99395
id = 3
containerMimeType = video/mp4
sampleMimeType = application/microvideo-meta-stream
@ -539,6 +542,7 @@ track 3:
sample count = 1
track duration = 1133700
format 0:
averageBitrate = 416
id = 4
containerMimeType = video/mp4
sampleMimeType = application/motionphoto-image-meta

View File

@ -11,6 +11,7 @@ track 0:
sample count = 44
track duration = 2100700
format 0:
averageBitrate = 12593505
id = 1
containerMimeType = video/mp4
sampleMimeType = video/hevc
@ -212,6 +213,7 @@ track 1:
sample count = 1
track duration = 466800
format 0:
averageBitrate = 2593047
id = 2
containerMimeType = video/mp4
sampleMimeType = video/hevc
@ -241,6 +243,7 @@ track 2:
sample count = 38
track duration = 2100700
format 0:
averageBitrate = 99395
id = 3
containerMimeType = video/mp4
sampleMimeType = application/microvideo-meta-stream
@ -403,6 +406,7 @@ track 3:
sample count = 1
track duration = 1133700
format 0:
averageBitrate = 416
id = 4
containerMimeType = video/mp4
sampleMimeType = application/motionphoto-image-meta

View File

@ -11,6 +11,7 @@ track 0:
sample count = 23
track duration = 2100700
format 0:
averageBitrate = 12593505
id = 1
containerMimeType = video/mp4
sampleMimeType = video/hevc
@ -128,6 +129,7 @@ track 1:
sample count = 1
track duration = 466800
format 0:
averageBitrate = 2593047
id = 2
containerMimeType = video/mp4
sampleMimeType = video/hevc
@ -157,6 +159,7 @@ track 2:
sample count = 17
track duration = 2100700
format 0:
averageBitrate = 99395
id = 3
containerMimeType = video/mp4
sampleMimeType = application/microvideo-meta-stream
@ -235,6 +238,7 @@ track 3:
sample count = 1
track duration = 1133700
format 0:
averageBitrate = 416
id = 4
containerMimeType = video/mp4
sampleMimeType = application/motionphoto-image-meta

View File

@ -11,6 +11,7 @@ track 0:
sample count = 2
track duration = 2100700
format 0:
averageBitrate = 12593505
id = 1
containerMimeType = video/mp4
sampleMimeType = video/hevc
@ -44,6 +45,7 @@ track 1:
sample count = 1
track duration = 466800
format 0:
averageBitrate = 2593047
id = 2
containerMimeType = video/mp4
sampleMimeType = video/hevc
@ -73,6 +75,7 @@ track 2:
sample count = 1
track duration = 2100700
format 0:
averageBitrate = 99395
id = 3
containerMimeType = video/mp4
sampleMimeType = application/microvideo-meta-stream
@ -87,6 +90,7 @@ track 3:
sample count = 1
track duration = 1133700
format 0:
averageBitrate = 416
id = 4
containerMimeType = video/mp4
sampleMimeType = application/motionphoto-image-meta

View File

@ -11,6 +11,7 @@ track 0:
sample count = 58
track duration = 2100700
format 0:
averageBitrate = 12593505
id = 1
containerMimeType = video/mp4
sampleMimeType = video/hevc
@ -268,6 +269,7 @@ track 1:
sample count = 1
track duration = 466800
format 0:
averageBitrate = 2593047
id = 2
containerMimeType = video/mp4
sampleMimeType = video/hevc
@ -297,6 +299,7 @@ track 2:
sample count = 58
track duration = 2100700
format 0:
averageBitrate = 99395
id = 3
containerMimeType = video/mp4
sampleMimeType = application/microvideo-meta-stream
@ -539,6 +542,7 @@ track 3:
sample count = 1
track duration = 1133700
format 0:
averageBitrate = 416
id = 4
containerMimeType = video/mp4
sampleMimeType = application/motionphoto-image-meta

View File

@ -11,6 +11,7 @@ track 0:
sample count = 44
track duration = 2100700
format 0:
averageBitrate = 12593505
id = 1
containerMimeType = video/mp4
sampleMimeType = video/hevc
@ -212,6 +213,7 @@ track 1:
sample count = 1
track duration = 466800
format 0:
averageBitrate = 2593047
id = 2
containerMimeType = video/mp4
sampleMimeType = video/hevc
@ -241,6 +243,7 @@ track 2:
sample count = 38
track duration = 2100700
format 0:
averageBitrate = 99395
id = 3
containerMimeType = video/mp4
sampleMimeType = application/microvideo-meta-stream
@ -403,6 +406,7 @@ track 3:
sample count = 1
track duration = 1133700
format 0:
averageBitrate = 416
id = 4
containerMimeType = video/mp4
sampleMimeType = application/motionphoto-image-meta

View File

@ -11,6 +11,7 @@ track 0:
sample count = 23
track duration = 2100700
format 0:
averageBitrate = 12593505
id = 1
containerMimeType = video/mp4
sampleMimeType = video/hevc
@ -128,6 +129,7 @@ track 1:
sample count = 1
track duration = 466800
format 0:
averageBitrate = 2593047
id = 2
containerMimeType = video/mp4
sampleMimeType = video/hevc
@ -157,6 +159,7 @@ track 2:
sample count = 17
track duration = 2100700
format 0:
averageBitrate = 99395
id = 3
containerMimeType = video/mp4
sampleMimeType = application/microvideo-meta-stream
@ -235,6 +238,7 @@ track 3:
sample count = 1
track duration = 1133700
format 0:
averageBitrate = 416
id = 4
containerMimeType = video/mp4
sampleMimeType = application/motionphoto-image-meta

View File

@ -11,6 +11,7 @@ track 0:
sample count = 2
track duration = 2100700
format 0:
averageBitrate = 12593505
id = 1
containerMimeType = video/mp4
sampleMimeType = video/hevc
@ -44,6 +45,7 @@ track 1:
sample count = 1
track duration = 466800
format 0:
averageBitrate = 2593047
id = 2
containerMimeType = video/mp4
sampleMimeType = video/hevc
@ -73,6 +75,7 @@ track 2:
sample count = 1
track duration = 2100700
format 0:
averageBitrate = 99395
id = 3
containerMimeType = video/mp4
sampleMimeType = application/microvideo-meta-stream
@ -87,6 +90,7 @@ track 3:
sample count = 1
track duration = 1133700
format 0:
averageBitrate = 416
id = 4
containerMimeType = video/mp4
sampleMimeType = application/motionphoto-image-meta

View File

@ -11,6 +11,7 @@ track 0:
sample count = 58
track duration = 2100700
format 0:
averageBitrate = 12593505
id = 1
containerMimeType = video/mp4
sampleMimeType = video/hevc
@ -268,6 +269,7 @@ track 1:
sample count = 1
track duration = 466800
format 0:
averageBitrate = 2593047
id = 2
containerMimeType = video/mp4
sampleMimeType = video/hevc
@ -297,6 +299,7 @@ track 2:
sample count = 58
track duration = 2100700
format 0:
averageBitrate = 99395
id = 3
containerMimeType = video/mp4
sampleMimeType = application/microvideo-meta-stream
@ -539,6 +542,7 @@ track 3:
sample count = 1
track duration = 1133700
format 0:
averageBitrate = 416
id = 4
containerMimeType = video/mp4
sampleMimeType = application/motionphoto-image-meta

View File

@ -11,6 +11,7 @@ track 0:
sample count = 58
track duration = 2100700
format 0:
averageBitrate = 12593505
id = 1
containerMimeType = video/mp4
sampleMimeType = video/hevc
@ -268,6 +269,7 @@ track 1:
sample count = 1
track duration = 466800
format 0:
averageBitrate = 2593047
id = 2
containerMimeType = video/mp4
sampleMimeType = video/hevc
@ -297,6 +299,7 @@ track 2:
sample count = 58
track duration = 2100700
format 0:
averageBitrate = 99395
id = 3
containerMimeType = video/mp4
sampleMimeType = application/microvideo-meta-stream
@ -539,6 +542,7 @@ track 3:
sample count = 1
track duration = 1133700
format 0:
averageBitrate = 416
id = 4
containerMimeType = video/mp4
sampleMimeType = application/motionphoto-image-meta

View File

@ -11,6 +11,7 @@ track 0:
sample count = 30
track duration = 1001000
format 0:
averageBitrate = 718290
id = 1
containerMimeType = video/mp4
sampleMimeType = video/avc
@ -153,6 +154,7 @@ track 1:
sample count = 45
track duration = 1024000
format 0:
averageBitrate = 74502
peakBitrate = 200000
id = 2
containerMimeType = video/mp4

View File

@ -11,6 +11,7 @@ track 0:
sample count = 30
track duration = 1001000
format 0:
averageBitrate = 718290
id = 1
containerMimeType = video/mp4
sampleMimeType = video/avc
@ -153,6 +154,7 @@ track 1:
sample count = 33
track duration = 1024000
format 0:
averageBitrate = 74502
peakBitrate = 200000
id = 2
containerMimeType = video/mp4

View File

@ -11,6 +11,7 @@ track 0:
sample count = 30
track duration = 1001000
format 0:
averageBitrate = 718290
id = 1
containerMimeType = video/mp4
sampleMimeType = video/avc
@ -153,6 +154,7 @@ track 1:
sample count = 18
track duration = 1024000
format 0:
averageBitrate = 74502
peakBitrate = 200000
id = 2
containerMimeType = video/mp4

View File

@ -11,6 +11,7 @@ track 0:
sample count = 30
track duration = 1001000
format 0:
averageBitrate = 718290
id = 1
containerMimeType = video/mp4
sampleMimeType = video/avc
@ -153,6 +154,7 @@ track 1:
sample count = 3
track duration = 1024000
format 0:
averageBitrate = 74502
peakBitrate = 200000
id = 2
containerMimeType = video/mp4

View File

@ -11,6 +11,7 @@ track 0:
sample count = 30
track duration = 1001000
format 0:
averageBitrate = 718290
id = 1
containerMimeType = video/mp4
sampleMimeType = video/avc
@ -153,6 +154,7 @@ track 1:
sample count = 45
track duration = 1024000
format 0:
averageBitrate = 74502
peakBitrate = 200000
id = 2
containerMimeType = video/mp4

View File

@ -11,6 +11,7 @@ track 0:
sample count = 30
track duration = 1001000
format 0:
averageBitrate = 718290
id = 1
containerMimeType = video/mp4
sampleMimeType = video/avc
@ -153,6 +154,7 @@ track 1:
sample count = 33
track duration = 1024000
format 0:
averageBitrate = 74502
peakBitrate = 200000
id = 2
containerMimeType = video/mp4

View File

@ -11,6 +11,7 @@ track 0:
sample count = 30
track duration = 1001000
format 0:
averageBitrate = 718290
id = 1
containerMimeType = video/mp4
sampleMimeType = video/avc
@ -153,6 +154,7 @@ track 1:
sample count = 18
track duration = 1024000
format 0:
averageBitrate = 74502
peakBitrate = 200000
id = 2
containerMimeType = video/mp4

View File

@ -11,6 +11,7 @@ track 0:
sample count = 30
track duration = 1001000
format 0:
averageBitrate = 718290
id = 1
containerMimeType = video/mp4
sampleMimeType = video/avc
@ -153,6 +154,7 @@ track 1:
sample count = 3
track duration = 1024000
format 0:
averageBitrate = 74502
peakBitrate = 200000
id = 2
containerMimeType = video/mp4

View File

@ -11,6 +11,7 @@ track 0:
sample count = 30
track duration = 1001000
format 0:
averageBitrate = 718290
id = 1
containerMimeType = video/mp4
sampleMimeType = video/avc
@ -153,6 +154,7 @@ track 1:
sample count = 45
track duration = 1024000
format 0:
averageBitrate = 74502
peakBitrate = 200000
id = 2
containerMimeType = video/mp4

View File

@ -11,6 +11,7 @@ track 0:
sample count = 30
track duration = 1001000
format 0:
averageBitrate = 718290
id = 1
containerMimeType = video/mp4
sampleMimeType = video/avc
@ -153,6 +154,7 @@ track 1:
sample count = 45
track duration = 1024000
format 0:
averageBitrate = 74502
peakBitrate = 200000
id = 2
containerMimeType = video/mp4

View File

@ -11,6 +11,7 @@ track 0:
sample count = 30
track duration = 1001000
format 0:
averageBitrate = 718290
id = 1
containerMimeType = video/mp4
sampleMimeType = video/avc
@ -153,6 +154,7 @@ track 1:
sample count = 45
track duration = 1024000
format 0:
averageBitrate = 74502
peakBitrate = 200000
id = 2
containerMimeType = video/mp4

View File

@ -11,7 +11,7 @@ track 0:
sample count = 30
track duration = 1001000
format 0:
averageBitrate = 718288
averageBitrate = 718290
peakBitrate = 718288
id = 1
containerMimeType = video/mp4

View File

@ -11,7 +11,7 @@ track 0:
sample count = 30
track duration = 1001000
format 0:
averageBitrate = 718288
averageBitrate = 718290
peakBitrate = 718288
id = 1
containerMimeType = video/mp4

View File

@ -11,7 +11,7 @@ track 0:
sample count = 30
track duration = 1001000
format 0:
averageBitrate = 718288
averageBitrate = 718290
peakBitrate = 718288
id = 1
containerMimeType = video/mp4

View File

@ -11,7 +11,7 @@ track 0:
sample count = 30
track duration = 1001000
format 0:
averageBitrate = 718288
averageBitrate = 718290
peakBitrate = 718288
id = 1
containerMimeType = video/mp4

View File

@ -11,7 +11,7 @@ track 0:
sample count = 30
track duration = 1001000
format 0:
averageBitrate = 718288
averageBitrate = 718290
peakBitrate = 718288
id = 1
containerMimeType = video/mp4

View File

@ -11,7 +11,7 @@ track 0:
sample count = 30
track duration = 1001000
format 0:
averageBitrate = 718288
averageBitrate = 718290
peakBitrate = 718288
id = 1
containerMimeType = video/mp4

View File

@ -11,7 +11,7 @@ track 0:
sample count = 30
track duration = 1001000
format 0:
averageBitrate = 718288
averageBitrate = 718290
peakBitrate = 718288
id = 1
containerMimeType = video/mp4

View File

@ -11,7 +11,7 @@ track 0:
sample count = 30
track duration = 1001000
format 0:
averageBitrate = 718288
averageBitrate = 718290
peakBitrate = 718288
id = 1
containerMimeType = video/mp4

View File

@ -11,7 +11,7 @@ track 0:
sample count = 30
track duration = 1001000
format 0:
averageBitrate = 718288
averageBitrate = 718290
peakBitrate = 718288
id = 1
containerMimeType = video/mp4

View File

@ -11,7 +11,7 @@ track 0:
sample count = 30
track duration = 1001000
format 0:
averageBitrate = 718288
averageBitrate = 718290
peakBitrate = 718288
id = 1
containerMimeType = video/mp4

View File

@ -11,6 +11,7 @@ track 0:
sample count = 30
track duration = 1001000
format 0:
averageBitrate = 717794
id = 1
containerMimeType = video/mp4
sampleMimeType = video/avc
@ -155,6 +156,7 @@ track 1:
sample count = 45
track duration = 1045300
format 0:
averageBitrate = 72928
peakBitrate = 200000
id = 2
containerMimeType = video/mp4

View File

@ -11,6 +11,7 @@ track 0:
sample count = 30
track duration = 1001000
format 0:
averageBitrate = 717794
id = 1
containerMimeType = video/mp4
sampleMimeType = video/avc
@ -155,6 +156,7 @@ track 1:
sample count = 32
track duration = 1045300
format 0:
averageBitrate = 72928
peakBitrate = 200000
id = 2
containerMimeType = video/mp4

View File

@ -11,6 +11,7 @@ track 0:
sample count = 30
track duration = 1001000
format 0:
averageBitrate = 717794
id = 1
containerMimeType = video/mp4
sampleMimeType = video/avc
@ -155,6 +156,7 @@ track 1:
sample count = 17
track duration = 1045300
format 0:
averageBitrate = 72928
peakBitrate = 200000
id = 2
containerMimeType = video/mp4

View File

@ -11,6 +11,7 @@ track 0:
sample count = 30
track duration = 1001000
format 0:
averageBitrate = 717794
id = 1
containerMimeType = video/mp4
sampleMimeType = video/avc
@ -155,6 +156,7 @@ track 1:
sample count = 2
track duration = 1045300
format 0:
averageBitrate = 72928
peakBitrate = 200000
id = 2
containerMimeType = video/mp4

View File

@ -11,6 +11,7 @@ track 0:
sample count = 30
track duration = 1001000
format 0:
averageBitrate = 717794
id = 1
containerMimeType = video/mp4
sampleMimeType = video/avc
@ -155,6 +156,7 @@ track 1:
sample count = 45
track duration = 1045300
format 0:
averageBitrate = 72928
peakBitrate = 200000
id = 2
containerMimeType = video/mp4

View File

@ -11,6 +11,7 @@ track 0:
sample count = 30
track duration = 1001000
format 0:
averageBitrate = 717794
id = 1
containerMimeType = video/mp4
sampleMimeType = video/avc
@ -155,6 +156,7 @@ track 1:
sample count = 32
track duration = 1045300
format 0:
averageBitrate = 72928
peakBitrate = 200000
id = 2
containerMimeType = video/mp4

View File

@ -11,6 +11,7 @@ track 0:
sample count = 30
track duration = 1001000
format 0:
averageBitrate = 717794
id = 1
containerMimeType = video/mp4
sampleMimeType = video/avc
@ -155,6 +156,7 @@ track 1:
sample count = 17
track duration = 1045300
format 0:
averageBitrate = 72928
peakBitrate = 200000
id = 2
containerMimeType = video/mp4

View File

@ -11,6 +11,7 @@ track 0:
sample count = 30
track duration = 1001000
format 0:
averageBitrate = 717794
id = 1
containerMimeType = video/mp4
sampleMimeType = video/avc
@ -155,6 +156,7 @@ track 1:
sample count = 2
track duration = 1045300
format 0:
averageBitrate = 72928
peakBitrate = 200000
id = 2
containerMimeType = video/mp4

View File

@ -11,6 +11,7 @@ track 0:
sample count = 30
track duration = 1001000
format 0:
averageBitrate = 717794
id = 1
containerMimeType = video/mp4
sampleMimeType = video/avc
@ -155,6 +156,7 @@ track 1:
sample count = 45
track duration = 1045300
format 0:
averageBitrate = 72928
peakBitrate = 200000
id = 2
containerMimeType = video/mp4

View File

@ -11,6 +11,7 @@ track 0:
sample count = 30
track duration = 1001000
format 0:
averageBitrate = 717794
id = 1
containerMimeType = video/mp4
sampleMimeType = video/avc
@ -155,6 +156,7 @@ track 1:
sample count = 45
track duration = 1045300
format 0:
averageBitrate = 72928
peakBitrate = 200000
id = 2
containerMimeType = video/mp4

View File

@ -11,6 +11,7 @@ track 0:
sample count = 19
track duration = 760000
format 0:
averageBitrate = 78737
id = 1
containerMimeType = audio/mp4
sampleMimeType = audio/ac4

View File

@ -11,6 +11,7 @@ track 0:
sample count = 19
track duration = 760000
format 0:
averageBitrate = 78737
id = 1
containerMimeType = audio/mp4
sampleMimeType = audio/ac4

View File

@ -11,6 +11,7 @@ track 0:
sample count = 19
track duration = 760000
format 0:
averageBitrate = 78737
id = 1
containerMimeType = audio/mp4
sampleMimeType = audio/ac4

View File

@ -11,6 +11,7 @@ track 0:
sample count = 19
track duration = 760000
format 0:
averageBitrate = 78737
id = 1
containerMimeType = audio/mp4
sampleMimeType = audio/ac4

View File

@ -11,6 +11,7 @@ track 0:
sample count = 19
track duration = 760000
format 0:
averageBitrate = 78737
id = 1
containerMimeType = audio/mp4
sampleMimeType = audio/ac4

View File

@ -11,6 +11,7 @@ track 0:
sample count = 19
track duration = 760000
format 0:
averageBitrate = 78737
id = 1
containerMimeType = audio/mp4
sampleMimeType = audio/ac4

View File

@ -11,6 +11,7 @@ track 0:
sample count = 19
track duration = 760000
format 0:
averageBitrate = 78737
id = 1
containerMimeType = audio/mp4
sampleMimeType = audio/ac4

View File

@ -11,6 +11,7 @@ track 0:
sample count = 19
track duration = 760000
format 0:
averageBitrate = 78737
id = 1
containerMimeType = audio/mp4
sampleMimeType = audio/ac4

View File

@ -11,6 +11,7 @@ track 0:
sample count = 19
track duration = 760000
format 0:
averageBitrate = 78737
id = 1
containerMimeType = audio/mp4
sampleMimeType = audio/ac4

View File

@ -11,6 +11,7 @@ track 0:
sample count = 19
track duration = 760000
format 0:
averageBitrate = 78737
id = 1
containerMimeType = audio/mp4
sampleMimeType = audio/ac4

View File

@ -11,6 +11,7 @@ track 0:
sample count = 20
track duration = 853333
format 0:
averageBitrate = 1524001
id = 1
containerMimeType = audio/mp4
sampleMimeType = audio/ac4

View File

@ -11,6 +11,7 @@ track 0:
sample count = 20
track duration = 853333
format 0:
averageBitrate = 1524001
id = 1
containerMimeType = audio/mp4
sampleMimeType = audio/ac4

View File

@ -11,6 +11,7 @@ track 0:
sample count = 10
track duration = 853333
format 0:
averageBitrate = 1524001
id = 1
containerMimeType = audio/mp4
sampleMimeType = audio/ac4

View File

@ -11,6 +11,7 @@ track 0:
sample count = 10
track duration = 853333
format 0:
averageBitrate = 1524001
id = 1
containerMimeType = audio/mp4
sampleMimeType = audio/ac4

View File

@ -11,6 +11,7 @@ track 0:
sample count = 20
track duration = 853333
format 0:
averageBitrate = 1524001
id = 1
containerMimeType = audio/mp4
sampleMimeType = audio/ac4

View File

@ -11,6 +11,7 @@ track 0:
sample count = 20
track duration = 853333
format 0:
averageBitrate = 1524001
id = 1
containerMimeType = audio/mp4
sampleMimeType = audio/ac4

View File

@ -11,6 +11,7 @@ track 0:
sample count = 10
track duration = 853333
format 0:
averageBitrate = 1524001
id = 1
containerMimeType = audio/mp4
sampleMimeType = audio/ac4

View File

@ -11,6 +11,7 @@ track 0:
sample count = 10
track duration = 853333
format 0:
averageBitrate = 1524001
id = 1
containerMimeType = audio/mp4
sampleMimeType = audio/ac4

View File

@ -11,6 +11,7 @@ track 0:
sample count = 20
track duration = 853333
format 0:
averageBitrate = 1524001
id = 1
containerMimeType = audio/mp4
sampleMimeType = audio/ac4

View File

@ -11,6 +11,7 @@ track 0:
sample count = 20
track duration = 853333
format 0:
averageBitrate = 1524001
id = 1
containerMimeType = audio/mp4
sampleMimeType = audio/ac4

View File

@ -11,6 +11,7 @@ track 0:
sample count = 7
track duration = 526000
format 0:
averageBitrate = 644454
id = 1
containerMimeType = video/mp4
sampleMimeType = video/avc

View File

@ -11,6 +11,7 @@ track 0:
sample count = 7
track duration = 526000
format 0:
averageBitrate = 644454
id = 1
containerMimeType = video/mp4
sampleMimeType = video/avc

View File

@ -11,6 +11,7 @@ track 0:
sample count = 7
track duration = 526000
format 0:
averageBitrate = 644454
id = 1
containerMimeType = video/mp4
sampleMimeType = video/avc

View File

@ -11,6 +11,7 @@ track 0:
sample count = 7
track duration = 526000
format 0:
averageBitrate = 644454
id = 1
containerMimeType = video/mp4
sampleMimeType = video/avc

View File

@ -11,6 +11,7 @@ track 0:
sample count = 7
track duration = 526000
format 0:
averageBitrate = 644454
id = 1
containerMimeType = video/mp4
sampleMimeType = video/avc

View File

@ -11,6 +11,7 @@ track 0:
sample count = 7
track duration = 526000
format 0:
averageBitrate = 644454
id = 1
containerMimeType = video/mp4
sampleMimeType = video/avc

View File

@ -11,6 +11,7 @@ track 0:
sample count = 7
track duration = 526000
format 0:
averageBitrate = 644454
id = 1
containerMimeType = video/mp4
sampleMimeType = video/avc

View File

@ -11,6 +11,7 @@ track 0:
sample count = 7
track duration = 526000
format 0:
averageBitrate = 644454
id = 1
containerMimeType = video/mp4
sampleMimeType = video/avc

View File

@ -11,6 +11,7 @@ track 0:
sample count = 7
track duration = 526000
format 0:
averageBitrate = 644454
id = 1
containerMimeType = video/mp4
sampleMimeType = video/avc

View File

@ -11,6 +11,7 @@ track 0:
sample count = 7
track duration = 526000
format 0:
averageBitrate = 644454
id = 1
containerMimeType = video/mp4
sampleMimeType = video/avc

View File

@ -11,6 +11,7 @@ track 0:
sample count = 32
track duration = 418333
format 0:
averageBitrate = 1810156
id = 1
containerMimeType = audio/mp4
sampleMimeType = audio/true-hd

View File

@ -11,6 +11,7 @@ track 0:
sample count = 24
track duration = 418333
format 0:
averageBitrate = 1810156
id = 1
containerMimeType = audio/mp4
sampleMimeType = audio/true-hd

Some files were not shown because too many files have changed in this diff Show More