Compare commits

..

No commits in common. "release" and "1.5.0" have entirely different histories.

51 changed files with 333 additions and 8280 deletions

View file

@ -19,7 +19,6 @@ body:
options: options:
- Media3 main branch - Media3 main branch
- Media3 pre-release (alpha, beta or RC not in this list) - Media3 pre-release (alpha, beta or RC not in this list)
- Media3 1.5.1
- Media3 1.5.0 - Media3 1.5.0
- Media3 1.4.1 - Media3 1.4.1
- Media3 1.4.0 - Media3 1.4.0

1
.gitignore vendored
View file

@ -52,7 +52,6 @@ tmp
# External native builds # External native builds
.externalNativeBuild .externalNativeBuild
.cxx
# VP9 decoder extension # VP9 decoder extension
libraries/decoder_vp9/src/main/jni/libvpx libraries/decoder_vp9/src/main/jni/libvpx

View file

@ -2,32 +2,6 @@
## 1.5 ## 1.5
### 1.5.1 (2024-12-19)
This release includes the following changes since the
[1.5.0 release](#150-2024-11-27):
* ExoPlayer:
* Disable use of asynchronous decryption in MediaCodec to avoid reported
codec timeout issues with this platform API
([#1641](https://github.com/androidx/media/issues/1641)).
* Extractors:
* MP3: Don't stop playback early when a `VBRI` frame's table of contents
doesn't cover all the MP3 data in a file
([#1904](https://github.com/androidx/media/issues/1904)).
* Video:
* Rollback of using `MediaCodecAdapter` supplied pixel aspect ratio values
when provided while processing `onOutputFormatChanged`
([#1371](https://github.com/androidx/media/pull/1371)).
* Text:
* Fix bug in `ReplacingCuesResolver.discardCuesBeforeTimeUs` where the cue
active at `timeUs` (started before but not yet ended) was incorrectly
discarded ([#1939](https://github.com/androidx/media/issues/1939)).
* Metadata:
* Extract disc/track numbering and genre from Vorbis comments into
`MediaMetadata`
([#1958](https://github.com/androidx/media/issues/1958)).
### 1.5.0 (2024-11-27) ### 1.5.0 (2024-11-27)
This release includes the following changes since the This release includes the following changes since the

View file

@ -12,8 +12,8 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
project.ext { project.ext {
releaseVersion = '1.5.1' releaseVersion = '1.5.0'
releaseVersionCode = 1_005_001_3_00 releaseVersionCode = 1_005_000_3_00
minSdkVersion = 21 minSdkVersion = 21
// See https://developer.android.com/training/cars/media/automotive-os#automotive-module // See https://developer.android.com/training/cars/media/automotive-os#automotive-module
automotiveMinSdkVersion = 28 automotiveMinSdkVersion = 28

View file

@ -203,7 +203,7 @@ public final class ColorInfo {
/** /**
* Returns the {@link C.ColorSpace} corresponding to the given ISO color primary code, as per * Returns the {@link C.ColorSpace} corresponding to the given ISO color primary code, as per
* table A.7.21.1 in Rec. ITU-T T.832 (06/2019), or {@link Format#NO_VALUE} if no mapping can be * table A.7.21.1 in Rec. ITU-T T.832 (03/2009), or {@link Format#NO_VALUE} if no mapping can be
* made. * made.
*/ */
@Pure @Pure
@ -219,52 +219,13 @@ public final class ColorInfo {
case 9: case 9:
return C.COLOR_SPACE_BT2020; return C.COLOR_SPACE_BT2020;
default: default:
// Remaining color primaries are either reserved or unspecified.
return Format.NO_VALUE; return Format.NO_VALUE;
} }
} }
/**
* Returns the ISO color primary code corresponding to the given {@link C.ColorSpace}, as per
* table A.7.21.1 in Rec. ITU-T T.832 (06/2019). made.
*/
public static int colorSpaceToIsoColorPrimaries(@C.ColorSpace int colorSpace) {
switch (colorSpace) {
// Default to BT.709 SDR as per the <a
// href="https://www.webmproject.org/vp9/mp4/#optional-fields">recommendation</a>.
case Format.NO_VALUE:
case C.COLOR_SPACE_BT709:
return 1;
case C.COLOR_SPACE_BT601:
return 5;
case C.COLOR_SPACE_BT2020:
return 9;
}
return 1;
}
/**
* Returns the ISO matrix coefficients code corresponding to the given {@link C.ColorSpace}, as
* per table A.7.21.3 in Rec. ITU-T T.832 (06/2019).
*/
public static int colorSpaceToIsoMatrixCoefficients(@C.ColorSpace int colorSpace) {
switch (colorSpace) {
// Default to BT.709 SDR as per the <a
// href="https://www.webmproject.org/vp9/mp4/#optional-fields">recommendation</a>.
case Format.NO_VALUE:
case C.COLOR_SPACE_BT709:
return 1;
case C.COLOR_SPACE_BT601:
return 6;
case C.COLOR_SPACE_BT2020:
return 9;
}
return 1;
}
/** /**
* Returns the {@link C.ColorTransfer} corresponding to the given ISO transfer characteristics * Returns the {@link C.ColorTransfer} corresponding to the given ISO transfer characteristics
* code, as per table A.7.21.2 in Rec. ITU-T T.832 (06/2019), or {@link Format#NO_VALUE} if no * code, as per table A.7.21.2 in Rec. ITU-T T.832 (03/2009), or {@link Format#NO_VALUE} if no
* mapping can be made. * mapping can be made.
*/ */
@Pure @Pure
@ -288,31 +249,6 @@ public final class ColorInfo {
} }
} }
/**
* Returns the ISO transfer characteristics code corresponding to the given {@link
* C.ColorTransfer}, as per table A.7.21.2 in Rec. ITU-T T.832 (06/2019).
*/
public static int colorTransferToIsoTransferCharacteristics(@C.ColorTransfer int colorTransfer) {
switch (colorTransfer) {
// Default to BT.709 SDR as per the <a
// href="https://www.webmproject.org/vp9/mp4/#optional-fields">recommendation</a>.
case C.COLOR_TRANSFER_LINEAR:
return 8;
case C.COLOR_TRANSFER_SRGB:
return 13;
case Format.NO_VALUE:
case C.COLOR_TRANSFER_SDR:
return 1;
case C.COLOR_TRANSFER_ST2084:
return 16;
case C.COLOR_TRANSFER_HLG:
return 18;
case C.COLOR_TRANSFER_GAMMA_2_2:
return 4;
}
return 1;
}
/** /**
* Returns whether the {@code ColorInfo} uses an HDR {@link C.ColorTransfer}. * Returns whether the {@code ColorInfo} uses an HDR {@link C.ColorTransfer}.
* *

View file

@ -16,7 +16,6 @@
package androidx.media3.common; package androidx.media3.common;
import static androidx.media3.common.util.Assertions.checkState; import static androidx.media3.common.util.Assertions.checkState;
import static com.google.common.math.DoubleMath.fuzzyEquals;
import static java.lang.annotation.ElementType.TYPE_USE; import static java.lang.annotation.ElementType.TYPE_USE;
import android.os.Bundle; import android.os.Bundle;
@ -750,7 +749,7 @@ public final class Format {
/** /**
* Sets {@link Format#tileCountHorizontal}. The default value is {@link #NO_VALUE}. * Sets {@link Format#tileCountHorizontal}. The default value is {@link #NO_VALUE}.
* *
* @param tileCountHorizontal The {@link Format#tileCountHorizontal}. * @param tileCountHorizontal The {@link Format#accessibilityChannel}.
* @return The builder. * @return The builder.
*/ */
@CanIgnoreReturnValue @CanIgnoreReturnValue
@ -762,7 +761,7 @@ public final class Format {
/** /**
* Sets {@link Format#tileCountVertical}. The default value is {@link #NO_VALUE}. * Sets {@link Format#tileCountVertical}. The default value is {@link #NO_VALUE}.
* *
* @param tileCountVertical The {@link Format#tileCountVertical}. * @param tileCountVertical The {@link Format#accessibilityChannel}.
* @return The builder. * @return The builder.
*/ */
@CanIgnoreReturnValue @CanIgnoreReturnValue
@ -1443,9 +1442,6 @@ public final class Format {
if (format.width != NO_VALUE && format.height != NO_VALUE) { if (format.width != NO_VALUE && format.height != NO_VALUE) {
builder.append(", res=").append(format.width).append("x").append(format.height); builder.append(", res=").append(format.width).append("x").append(format.height);
} }
if (!fuzzyEquals(format.pixelWidthHeightRatio, 1, 0.001)) {
builder.append(", par=").append(Util.formatInvariant("%.3f", format.pixelWidthHeightRatio));
}
if (format.colorInfo != null && format.colorInfo.isValid()) { if (format.colorInfo != null && format.colorInfo.isValid()) {
builder.append(", color=").append(format.colorInfo.toLogString()); builder.append(", color=").append(format.colorInfo.toLogString());
} }

View file

@ -30,25 +30,6 @@ import java.util.List;
/** /**
* A {@link Player} that forwards method calls to another {@link Player}. Applications can use this * A {@link Player} that forwards method calls to another {@link Player}. Applications can use this
* class to suppress or modify specific operations, by overriding the respective methods. * class to suppress or modify specific operations, by overriding the respective methods.
*
* <p>Subclasses must ensure they maintain consistency with the {@link Player} interface, including
* interactions with {@link Player.Listener}, which can be quite fiddly. For example, if removing an
* available {@link Player.Command} and disabling the corresponding method, subclasses need to:
*
* <ul>
* <li>Override {@link #isCommandAvailable(int)} and {@link #getAvailableCommands()}
* <li>Override and no-op the method itself
* <li>Override {@link #addListener(Listener)} and wrap the provided {@link Player.Listener} with
* an implementation that drops calls to {@link
* Player.Listener#onAvailableCommandsChanged(Commands)} and {@link
* Player.Listener#onEvents(Player, Events)} if they were only triggered by a change in
* command availability that is 'invisible' after the command removal.
* </ul>
*
* <p>Many customization use-cases are instead better served by {@link ForwardingSimpleBasePlayer},
* which allows subclasses to more concisely modify the behavior of an operation, or disallow a
* {@link Player.Command}. In many cases {@link ForwardingSimpleBasePlayer} should be used in
* preference to {@code ForwardingPlayer}.
*/ */
@UnstableApi @UnstableApi
public class ForwardingPlayer implements Player { public class ForwardingPlayer implements Player {

View file

@ -29,11 +29,11 @@ public final class MediaLibraryInfo {
/** The version of the library expressed as a string, for example "1.2.3" or "1.2.0-beta01". */ /** The version of the library expressed as a string, for example "1.2.3" or "1.2.0-beta01". */
// Intentionally hardcoded. Do not derive from other constants (e.g. VERSION_INT) or vice versa. // Intentionally hardcoded. Do not derive from other constants (e.g. VERSION_INT) or vice versa.
public static final String VERSION = "1.5.1"; public static final String VERSION = "1.5.0";
/** The version of the library expressed as {@code TAG + "/" + VERSION}. */ /** The version of the library expressed as {@code TAG + "/" + VERSION}. */
// Intentionally hardcoded. Do not derive from other constants (e.g. VERSION) or vice versa. // Intentionally hardcoded. Do not derive from other constants (e.g. VERSION) or vice versa.
public static final String VERSION_SLASHY = "AndroidXMedia3/1.5.1"; public static final String VERSION_SLASHY = "AndroidXMedia3/1.5.0";
/** /**
* The version of the library expressed as an integer, for example 1002003300. * The version of the library expressed as an integer, for example 1002003300.
@ -47,7 +47,7 @@ public final class MediaLibraryInfo {
* (123-045-006-3-00). * (123-045-006-3-00).
*/ */
// Intentionally hardcoded. Do not derive from other constants (e.g. VERSION) or vice versa. // Intentionally hardcoded. Do not derive from other constants (e.g. VERSION) or vice versa.
public static final int VERSION_INT = 1_005_001_3_00; public static final int VERSION_INT = 1_005_000_3_00;
/** Whether the library was compiled with {@link Assertions} checks enabled. */ /** Whether the library was compiled with {@link Assertions} checks enabled. */
public static final boolean ASSERTIONS_ENABLED = true; public static final boolean ASSERTIONS_ENABLED = true;

View file

@ -685,9 +685,6 @@ public final class MimeTypes {
} }
mimeType = Ascii.toLowerCase(mimeType); mimeType = Ascii.toLowerCase(mimeType);
switch (mimeType) { switch (mimeType) {
// Normalize uncommon versions of some video MIME types to their standard equivalent.
case BASE_TYPE_VIDEO + "/x-mvhevc":
return VIDEO_MV_HEVC;
// Normalize uncommon versions of some audio MIME types to their standard equivalent. // Normalize uncommon versions of some audio MIME types to their standard equivalent.
case BASE_TYPE_AUDIO + "/x-flac": case BASE_TYPE_AUDIO + "/x-flac":
return AUDIO_FLAC; return AUDIO_FLAC;

View file

@ -96,7 +96,8 @@ public final class MediaFormatUtil {
/* defaultValue= */ Format.NO_VALUE)) /* defaultValue= */ Format.NO_VALUE))
.setRotationDegrees( .setRotationDegrees(
getInteger(mediaFormat, MediaFormat.KEY_ROTATION, /* defaultValue= */ 0)) getInteger(mediaFormat, MediaFormat.KEY_ROTATION, /* defaultValue= */ 0))
.setColorInfo(getColorInfo(mediaFormat)) // TODO(b/278101856): Disallow invalid values after confirming.
.setColorInfo(getColorInfo(mediaFormat, /* allowInvalidValues= */ true))
.setSampleRate( .setSampleRate(
getInteger( getInteger(
mediaFormat, MediaFormat.KEY_SAMPLE_RATE, /* defaultValue= */ Format.NO_VALUE)) mediaFormat, MediaFormat.KEY_SAMPLE_RATE, /* defaultValue= */ Format.NO_VALUE))
@ -269,6 +270,13 @@ public final class MediaFormatUtil {
*/ */
@Nullable @Nullable
public static ColorInfo getColorInfo(MediaFormat mediaFormat) { public static ColorInfo getColorInfo(MediaFormat mediaFormat) {
return getColorInfo(mediaFormat, /* allowInvalidValues= */ false);
}
// Internal methods.
@Nullable
private static ColorInfo getColorInfo(MediaFormat mediaFormat, boolean allowInvalidValues) {
if (SDK_INT < 24) { if (SDK_INT < 24) {
// MediaFormat KEY_COLOR_TRANSFER and other KEY_COLOR values available from API 24. // MediaFormat KEY_COLOR_TRANSFER and other KEY_COLOR values available from API 24.
return null; return null;
@ -286,17 +294,21 @@ public final class MediaFormatUtil {
@Nullable @Nullable
byte[] hdrStaticInfo = byte[] hdrStaticInfo =
hdrStaticInfoByteBuffer != null ? getArray(hdrStaticInfoByteBuffer) : null; hdrStaticInfoByteBuffer != null ? getArray(hdrStaticInfoByteBuffer) : null;
// Some devices may produce invalid values from MediaFormat#getInteger.
// See b/239435670 for more information. if (!allowInvalidValues) {
if (!isValidColorSpace(colorSpace)) { // Some devices may produce invalid values from MediaFormat#getInteger.
colorSpace = Format.NO_VALUE; // See b/239435670 for more information.
} if (!isValidColorSpace(colorSpace)) {
if (!isValidColorRange(colorRange)) { colorSpace = Format.NO_VALUE;
colorRange = Format.NO_VALUE; }
} if (!isValidColorRange(colorRange)) {
if (!isValidColorTransfer(colorTransfer)) { colorRange = Format.NO_VALUE;
colorTransfer = Format.NO_VALUE; }
if (!isValidColorTransfer(colorTransfer)) {
colorTransfer = Format.NO_VALUE;
}
} }
if (colorSpace != Format.NO_VALUE if (colorSpace != Format.NO_VALUE
|| colorRange != Format.NO_VALUE || colorRange != Format.NO_VALUE
|| colorTransfer != Format.NO_VALUE || colorTransfer != Format.NO_VALUE

View file

@ -80,7 +80,7 @@ import java.nio.ByteBuffer;
Supplier<HandlerThread> queueingThreadSupplier) { Supplier<HandlerThread> queueingThreadSupplier) {
this.callbackThreadSupplier = callbackThreadSupplier; this.callbackThreadSupplier = callbackThreadSupplier;
this.queueingThreadSupplier = queueingThreadSupplier; this.queueingThreadSupplier = queueingThreadSupplier;
enableSynchronousBufferQueueingWithAsyncCryptoFlag = false; enableSynchronousBufferQueueingWithAsyncCryptoFlag = true;
} }
/** /**

View file

@ -67,7 +67,7 @@ public final class DefaultMediaCodecAdapterFactory implements MediaCodecAdapter.
@Deprecated @Deprecated
public DefaultMediaCodecAdapterFactory() { public DefaultMediaCodecAdapterFactory() {
asynchronousMode = MODE_DEFAULT; asynchronousMode = MODE_DEFAULT;
asyncCryptoFlagEnabled = false; asyncCryptoFlagEnabled = true;
context = null; context = null;
} }
@ -79,7 +79,7 @@ public final class DefaultMediaCodecAdapterFactory implements MediaCodecAdapter.
public DefaultMediaCodecAdapterFactory(Context context) { public DefaultMediaCodecAdapterFactory(Context context) {
this.context = context; this.context = context;
asynchronousMode = MODE_DEFAULT; asynchronousMode = MODE_DEFAULT;
asyncCryptoFlagEnabled = false; asyncCryptoFlagEnabled = true;
} }
/** /**

View file

@ -297,19 +297,12 @@ public final class MediaCodecInfo {
private boolean isCodecProfileAndLevelSupported( private boolean isCodecProfileAndLevelSupported(
Format format, boolean checkPerformanceCapabilities) { Format format, boolean checkPerformanceCapabilities) {
Pair<Integer, Integer> codecProfileAndLevel = MediaCodecUtil.getCodecProfileAndLevel(format); Pair<Integer, Integer> codecProfileAndLevel = MediaCodecUtil.getCodecProfileAndLevel(format);
if (format.sampleMimeType != null && format.sampleMimeType.equals(MimeTypes.VIDEO_MV_HEVC)) { if (format.sampleMimeType != null
String normalizedCodecMimeType = MimeTypes.normalizeMimeType(codecMimeType); && format.sampleMimeType.equals(MimeTypes.VIDEO_MV_HEVC)
if (normalizedCodecMimeType.equals(MimeTypes.VIDEO_MV_HEVC)) { && codecMimeType.equals(MimeTypes.VIDEO_H265)) {
// Currently as there is no formal support for MV-HEVC within Android framework, the profile // Falling back to single-layer HEVC from MV-HEVC. Get base layer profile and level.
// is not correctly specified by the underlying codec; just assume the profile obtained from codecProfileAndLevel = MediaCodecUtil.getHevcBaseLayerCodecProfileAndLevel(format);
// the MV-HEVC sample is supported.
return true;
} else if (normalizedCodecMimeType.equals(MimeTypes.VIDEO_H265)) {
// Falling back to single-layer HEVC from MV-HEVC. Get base layer profile and level.
codecProfileAndLevel = MediaCodecUtil.getHevcBaseLayerCodecProfileAndLevel(format);
}
} }
if (codecProfileAndLevel == null) { if (codecProfileAndLevel == null) {
// If we don't know any better, we assume that the profile and level are supported. // If we don't know any better, we assume that the profile and level are supported.
return true; return true;

View file

@ -80,15 +80,9 @@ import java.util.ArrayList;
@Override @Override
public void discardCuesBeforeTimeUs(long timeUs) { public void discardCuesBeforeTimeUs(long timeUs) {
int indexToDiscardTo = getIndexOfCuesStartingAfter(timeUs); int indexToDiscardTo = getIndexOfCuesStartingAfter(timeUs);
if (indexToDiscardTo == 0) { if (indexToDiscardTo > 0) {
// Either the first cue starts after timeUs, or the cues list is empty. cuesWithTimingList.subList(0, indexToDiscardTo).clear();
return;
} }
CuesWithTiming lastCueToDiscard = cuesWithTimingList.get(indexToDiscardTo - 1);
if (lastCueToDiscard.endTimeUs == C.TIME_UNSET || lastCueToDiscard.endTimeUs >= timeUs) {
indexToDiscardTo--;
}
cuesWithTimingList.subList(0, indexToDiscardTo).clear();
} }
@Override @Override
@ -148,7 +142,7 @@ import java.util.ArrayList;
/** /**
* Returns the index of the first {@link CuesWithTiming} in {@link #cuesWithTimingList} where * Returns the index of the first {@link CuesWithTiming} in {@link #cuesWithTimingList} where
* {@link CuesWithTiming#startTimeUs} is strictly greater than {@code timeUs}. * {@link CuesWithTiming#startTimeUs} is strictly less than {@code timeUs}.
* *
* <p>Returns the size of {@link #cuesWithTimingList} if all cues are before timeUs * <p>Returns the size of {@link #cuesWithTimingList} if all cues are before timeUs
*/ */

View file

@ -1362,7 +1362,17 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer
? mediaFormat.getInteger(KEY_CROP_BOTTOM) - mediaFormat.getInteger(KEY_CROP_TOP) + 1 ? mediaFormat.getInteger(KEY_CROP_BOTTOM) - mediaFormat.getInteger(KEY_CROP_TOP) + 1
: mediaFormat.getInteger(MediaFormat.KEY_HEIGHT); : mediaFormat.getInteger(MediaFormat.KEY_HEIGHT);
} }
pixelWidthHeightRatio = format.pixelWidthHeightRatio; pixelWidthHeightRatio = format.pixelWidthHeightRatio;
if (Util.SDK_INT >= 30
&& mediaFormat != null
&& mediaFormat.containsKey(MediaFormat.KEY_PIXEL_ASPECT_RATIO_WIDTH)
&& mediaFormat.containsKey(MediaFormat.KEY_PIXEL_ASPECT_RATIO_HEIGHT)) {
pixelWidthHeightRatio =
(float) mediaFormat.getInteger(MediaFormat.KEY_PIXEL_ASPECT_RATIO_WIDTH)
/ mediaFormat.getInteger(MediaFormat.KEY_PIXEL_ASPECT_RATIO_HEIGHT);
}
// The decoder applies the rotation when rendering to the surface. For 90 and 270 degree // The decoder applies the rotation when rendering to the surface. For 90 and 270 degree
// rotations, we need to flip the width, height and pixel aspect ratio to reflect the rotation // rotations, we need to flip the width, height and pixel aspect ratio to reflect the rotation
// that was applied. // that was applied.

View file

@ -44,7 +44,6 @@ public final class Mp3PlaybackTest {
"bear-id3.mp3", "bear-id3.mp3",
"bear-id3-numeric-genre.mp3", "bear-id3-numeric-genre.mp3",
"bear-vbr-no-seek-table.mp3", "bear-vbr-no-seek-table.mp3",
"bear-vbr-vbri-header-truncated-toc.mp3",
"bear-vbr-xing-header.mp3", "bear-vbr-xing-header.mp3",
"play-trimmed.mp3", "play-trimmed.mp3",
"test-cbr-info-header.mp3"); "test-cbr-info-header.mp3");

View file

@ -217,47 +217,6 @@ public final class ReplacingCuesResolverTest {
assertThat(replacingCuesResolver.getNextCueChangeTimeUs(4_999_990)).isEqualTo(6_000_000); assertThat(replacingCuesResolver.getNextCueChangeTimeUs(4_999_990)).isEqualTo(6_000_000);
} }
@Test
public void discardCuesBeforeTimeUs_retainsActiveCueWithSetDuration() {
ReplacingCuesResolver replacingCuesResolver = new ReplacingCuesResolver();
CuesWithTiming activeCue =
new CuesWithTiming(FIRST_CUES, /* startTimeUs= */ 3_000_000, /* durationUs= */ 4_000_000);
CuesWithTiming laterCue =
new CuesWithTiming(SECOND_CUES, /* startTimeUs= */ 8_000_000, /* durationUs= */ 2_000_000);
replacingCuesResolver.addCues(activeCue, /* currentPositionUs= */ 5_000_000);
replacingCuesResolver.addCues(laterCue, /* currentPositionUs= */ 5_000_000);
// Discard cues before 5_000_000. activeCue should remain active because it ends at 7_000_000.
replacingCuesResolver.discardCuesBeforeTimeUs(5_000_000);
// Query at a time within activeCue's range to verify it's still there.
assertThat(replacingCuesResolver.getCuesAtTimeUs(6_000_000)).isEqualTo(FIRST_CUES);
// Ensure that laterCue is unaffected.
assertThat(replacingCuesResolver.getCuesAtTimeUs(9_000_000)).isEqualTo(SECOND_CUES);
}
@Test
public void discardCuesBeforeTimeUs_retainsActiveCueWithUnsetDuration() {
ReplacingCuesResolver replacingCuesResolver = new ReplacingCuesResolver();
CuesWithTiming activeCue =
new CuesWithTiming(
FIRST_CUES, /* startTimeUs= */ 3_000_000, /* durationUs= */ C.TIME_UNSET);
CuesWithTiming laterCue =
new CuesWithTiming(SECOND_CUES, /* startTimeUs= */ 8_000_000, /* durationUs= */ 2_000_000);
replacingCuesResolver.addCues(activeCue, /* currentPositionUs= */ 5_000_000);
replacingCuesResolver.addCues(laterCue, /* currentPositionUs= */ 5_000_000);
// Discard cues before 5_000_000. activeCue should remain active because its
// duration is unset, meaning it should remain visible until replaced by a subsequent cue
// starting at 8_000_000.
replacingCuesResolver.discardCuesBeforeTimeUs(5_000_000);
// Query at a time within activeCue's range to verify it's still there.
assertThat(replacingCuesResolver.getCuesAtTimeUs(6_000_000)).isEqualTo(FIRST_CUES);
// Ensure that laterCue is unaffected.
assertThat(replacingCuesResolver.getCuesAtTimeUs(9_000_000)).isEqualTo(SECOND_CUES);
}
@Test @Test
public void clear_clearsAllCues() { public void clear_clearsAllCues() {
ReplacingCuesResolver replacingCuesResolver = new ReplacingCuesResolver(); ReplacingCuesResolver replacingCuesResolver = new ReplacingCuesResolver();

View file

@ -50,6 +50,7 @@ import androidx.media3.common.MimeTypes;
import androidx.media3.common.TrackGroup; import androidx.media3.common.TrackGroup;
import androidx.media3.common.VideoSize; import androidx.media3.common.VideoSize;
import androidx.media3.common.util.Clock; import androidx.media3.common.util.Clock;
import androidx.media3.common.util.Util;
import androidx.media3.decoder.CryptoInfo; import androidx.media3.decoder.CryptoInfo;
import androidx.media3.exoplayer.DecoderCounters; import androidx.media3.exoplayer.DecoderCounters;
import androidx.media3.exoplayer.ExoPlaybackException; import androidx.media3.exoplayer.ExoPlaybackException;
@ -100,6 +101,7 @@ import org.mockito.Mock;
import org.mockito.junit.MockitoJUnit; import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule; import org.mockito.junit.MockitoRule;
import org.robolectric.Shadows; import org.robolectric.Shadows;
import org.robolectric.annotation.Config;
import org.robolectric.shadows.ShadowDisplay; import org.robolectric.shadows.ShadowDisplay;
import org.robolectric.shadows.ShadowLooper; import org.robolectric.shadows.ShadowLooper;
import org.robolectric.shadows.ShadowSystemClock; import org.robolectric.shadows.ShadowSystemClock;
@ -114,6 +116,7 @@ public class MediaCodecVideoRendererTest {
.setSampleMimeType(MimeTypes.VIDEO_H264) .setSampleMimeType(MimeTypes.VIDEO_H264)
.setWidth(1920) .setWidth(1920)
.setHeight(1080) .setHeight(1080)
.setPixelWidthHeightRatio(1.0f)
.build(); .build();
private static final TrackGroup TRACK_GROUP_H264 = new TrackGroup(VIDEO_H264); private static final TrackGroup TRACK_GROUP_H264 = new TrackGroup(VIDEO_H264);
@ -747,6 +750,84 @@ public class MediaCodecVideoRendererTest {
new VideoSize(VIDEO_H264.width, VIDEO_H264.height, VIDEO_H264.pixelWidthHeightRatio)); new VideoSize(VIDEO_H264.width, VIDEO_H264.height, VIDEO_H264.pixelWidthHeightRatio));
} }
@Config(minSdk = 30)
@Test
public void
render_withMediaCodecModifyingPixelAspectRatioWidthHeight_sendsVideoSizeChangeWithMediaFormatValues()
throws Exception {
MediaCodecAdapter.Factory codecAdapterFactory =
configuration ->
new ForwardingSynchronousMediaCodecAdapter(
new SynchronousMediaCodecAdapter.Factory().createAdapter(configuration)) {
@Override
public MediaFormat getOutputFormat() {
MediaFormat mediaFormat = adapter.getOutputFormat();
if (Util.SDK_INT >= 30) {
// Change to 9:16 Ratio
mediaFormat.setInteger(MediaFormat.KEY_PIXEL_ASPECT_RATIO_WIDTH, 9);
mediaFormat.setInteger(MediaFormat.KEY_PIXEL_ASPECT_RATIO_HEIGHT, 16);
}
return mediaFormat;
}
};
MediaCodecVideoRenderer mediaCodecVideoRendererWithCustomAdapter =
new MediaCodecVideoRenderer(
ApplicationProvider.getApplicationContext(),
codecAdapterFactory,
mediaCodecSelector,
/* allowedJoiningTimeMs= */ 0,
/* enableDecoderFallback= */ false,
/* eventHandler= */ new Handler(testMainLooper),
/* eventListener= */ eventListener,
/* maxDroppedFramesToNotify= */ 1) {
@Override
protected @Capabilities int supportsFormat(
MediaCodecSelector mediaCodecSelector, Format format) {
return RendererCapabilities.create(C.FORMAT_HANDLED);
}
};
mediaCodecVideoRendererWithCustomAdapter.init(/* index= */ 0, PlayerId.UNSET, Clock.DEFAULT);
mediaCodecVideoRendererWithCustomAdapter.handleMessage(
Renderer.MSG_SET_VIDEO_OUTPUT, new Surface(new SurfaceTexture(/* texName= */ 0)));
FakeSampleStream fakeSampleStream =
new FakeSampleStream(
new DefaultAllocator(/* trimOnReset= */ true, /* individualAllocationSize= */ 1024),
/* mediaSourceEventDispatcher= */ null,
DrmSessionManager.DRM_UNSUPPORTED,
new DrmSessionEventListener.EventDispatcher(),
/* initialFormat= */ VIDEO_H264,
ImmutableList.of(
oneByteSample(/* timeUs= */ 0, C.BUFFER_FLAG_KEY_FRAME), END_OF_STREAM_ITEM));
fakeSampleStream.writeData(/* startPositionUs= */ 0);
mediaCodecVideoRendererWithCustomAdapter.enable(
RendererConfiguration.DEFAULT,
new Format[] {VIDEO_H264},
fakeSampleStream,
/* positionUs= */ 0,
/* joining= */ false,
/* mayRenderStartOfStream= */ true,
/* startPositionUs= */ 0,
/* offsetUs= */ 0,
new MediaSource.MediaPeriodId(new Object()));
mediaCodecVideoRendererWithCustomAdapter.setCurrentStreamFinal();
mediaCodecVideoRendererWithCustomAdapter.start();
int positionUs = 0;
do {
mediaCodecVideoRendererWithCustomAdapter.render(
positionUs, SystemClock.elapsedRealtime() * 1000);
positionUs += 10;
} while (!mediaCodecVideoRendererWithCustomAdapter.isEnded());
shadowOf(testMainLooper).idle();
verify(eventListener)
.onVideoSizeChanged(
new VideoSize(
VIDEO_H264.width,
VIDEO_H264.height,
/* pixelWidthHeightRatio= */ VIDEO_H264.pixelWidthHeightRatio * (9.0f / 16.0f)));
}
@Test @Test
public void public void
render_withMultipleQueued_sendsVideoSizeChangedWithCorrectPixelAspectRatioWhenMultipleQueued() render_withMultipleQueued_sendsVideoSizeChangedWithCorrectPixelAspectRatioWhenMultipleQueued()
@ -1903,7 +1984,7 @@ public class MediaCodecVideoRendererTest {
private abstract static class ForwardingSynchronousMediaCodecAdapter private abstract static class ForwardingSynchronousMediaCodecAdapter
implements MediaCodecAdapter { implements MediaCodecAdapter {
private final MediaCodecAdapter adapter; protected final MediaCodecAdapter adapter;
ForwardingSynchronousMediaCodecAdapter(MediaCodecAdapter adapter) { ForwardingSynchronousMediaCodecAdapter(MediaCodecAdapter adapter) {
this.adapter = adapter; this.adapter = adapter;

View file

@ -28,7 +28,7 @@ android {
} }
dependencies { dependencies {
api 'com.google.ads.interactivemedia.v3:interactivemedia:3.35.1' api 'com.google.ads.interactivemedia.v3:interactivemedia:3.33.0'
implementation project(modulePrefix + 'lib-exoplayer') implementation project(modulePrefix + 'lib-exoplayer')
implementation 'androidx.annotation:annotation:' + androidxAnnotationVersion implementation 'androidx.annotation:annotation:' + androidxAnnotationVersion
compileOnly 'com.google.errorprone:error_prone_annotations:' + errorProneVersion compileOnly 'com.google.errorprone:error_prone_annotations:' + errorProneVersion

View file

@ -410,22 +410,13 @@ public final class Ac4Util {
ac4Presentation.hasBackChannels, ac4Presentation.hasBackChannels,
ac4Presentation.topChannelPairs); ac4Presentation.topChannelPairs);
} else { } else {
// The ETSI TS 103 190-2 V1.2.1 (2018-02) specification defines the parameter channelCount = ac4Presentation.numOfUmxObjects;
// n_umx_objects_minus1 in Annex E (E.11.11) to specify the number of fullband objects. While
// the elementary stream specification (section 6.3.2.8.1 and 6.3.2.10.4) provides information
// about the presence of an LFE channel within the set of dynamic objects, this detail is not
// explicitly stated in the ISO Base Media File Format (Annex E). However, current
// implementation practices consistently include the LFE channel when creating an object-based
// substream. As a result, it has been decided that when interpreting the ISO Base Media File
// Format, the LFE channel should always be counted as part of the total channel count.
int lfeChannelCount = 1;
channelCount = ac4Presentation.numOfUmxObjects + lfeChannelCount;
// TODO: There is a bug in ETSI TS 103 190-2 V1.2.1 (2018-02), E.11.11 // TODO: There is a bug in ETSI TS 103 190-2 V1.2.1 (2018-02), E.11.11
// For AC-4 level 4 stream, the intention is to set 19 to n_umx_objects_minus1 but it is // For AC-4 level 4 stream, the intention is to set 19 to n_umx_objects_minus1 but it is
// equal to 15 based on current specification. Dolby has filed a bug report to ETSI. // equal to 15 based on current specification. Dolby has filed a bug report to ETSI.
// The following sentence should be deleted after ETSI specification error is fixed. // The following sentence should be deleted after ETSI specification error is fixed.
if (ac4Presentation.level == 4) { if (ac4Presentation.level == 4) {
channelCount = channelCount == 17 ? 21 : channelCount; channelCount = channelCount == 16 ? 21 : channelCount;
} }
} }

View file

@ -24,7 +24,6 @@ import androidx.media3.common.MediaMetadata;
import androidx.media3.common.Metadata; import androidx.media3.common.Metadata;
import androidx.media3.common.util.UnstableApi; import androidx.media3.common.util.UnstableApi;
import com.google.common.base.Ascii; import com.google.common.base.Ascii;
import com.google.common.primitives.Ints;
/** /**
* @deprecated Use {@link androidx.media3.extractor.metadata.vorbis.VorbisComment} instead. * @deprecated Use {@link androidx.media3.extractor.metadata.vorbis.VorbisComment} instead.
@ -59,9 +58,6 @@ public class VorbisComment implements Metadata.Entry {
@Override @Override
public void populateMediaMetadata(MediaMetadata.Builder builder) { public void populateMediaMetadata(MediaMetadata.Builder builder) {
// Vorbis comments can have duplicate keys, but all these fields are singular on MediaMetadata,
// so we naively overwrite whatever any previously set value (which results in 'keep last'
// semantics).
switch (key) { switch (key) {
case "TITLE": case "TITLE":
builder.setTitle(value); builder.setTitle(value);
@ -75,33 +71,6 @@ public class VorbisComment implements Metadata.Entry {
case "ALBUMARTIST": case "ALBUMARTIST":
builder.setAlbumArtist(value); builder.setAlbumArtist(value);
break; break;
case "TRACKNUMBER":
@Nullable Integer trackNumber = Ints.tryParse(value);
if (trackNumber != null) {
builder.setTrackNumber(trackNumber);
}
break;
case "TOTALTRACKS":
@Nullable Integer totalTracks = Ints.tryParse(value);
if (totalTracks != null) {
builder.setTotalTrackCount(totalTracks);
}
break;
case "DISCNUMBER":
@Nullable Integer discNumber = Ints.tryParse(value);
if (discNumber != null) {
builder.setDiscNumber(discNumber);
}
break;
case "TOTALDISCS":
@Nullable Integer totalDiscs = Ints.tryParse(value);
if (totalDiscs != null) {
builder.setTotalDiscCount(totalDiscs);
}
break;
case "GENRE":
builder.setGenre(value);
break;
case "DESCRIPTION": case "DESCRIPTION":
builder.setDescription(value); builder.setDescription(value);
break; break;

View file

@ -49,9 +49,7 @@ import androidx.media3.extractor.SeekPoint;
long position, long position,
MpegAudioUtil.Header mpegAudioHeader, MpegAudioUtil.Header mpegAudioHeader,
ParsableByteArray frame) { ParsableByteArray frame) {
frame.skipBytes(6); frame.skipBytes(10);
int bytes = frame.readInt();
long endOfMp3Data = position + mpegAudioHeader.frameSize + bytes;
int numFrames = frame.readInt(); int numFrames = frame.readInt();
if (numFrames <= 0) { if (numFrames <= 0) {
return null; return null;
@ -65,13 +63,15 @@ import androidx.media3.extractor.SeekPoint;
int entrySize = frame.readUnsignedShort(); int entrySize = frame.readUnsignedShort();
frame.skipBytes(2); frame.skipBytes(2);
position += mpegAudioHeader.frameSize; long minPosition = position + mpegAudioHeader.frameSize;
// Read table of contents entries. // Read table of contents entries.
long[] timesUs = new long[entryCount]; long[] timesUs = new long[entryCount];
long[] positions = new long[entryCount]; long[] positions = new long[entryCount];
for (int index = 0; index < entryCount; index++) { for (int index = 0; index < entryCount; index++) {
timesUs[index] = (index * durationUs) / entryCount; timesUs[index] = (index * durationUs) / entryCount;
positions[index] = position; // Ensure positions do not fall within the frame containing the VBRI header. This constraint
// will normally only apply to the first entry in the table.
positions[index] = max(position, minPosition);
int segmentSize; int segmentSize;
switch (entrySize) { switch (entrySize) {
case 1: case 1:
@ -91,21 +91,11 @@ import androidx.media3.extractor.SeekPoint;
} }
position += segmentSize * ((long) scale); position += segmentSize * ((long) scale);
} }
if (inputLength != C.LENGTH_UNSET && inputLength != endOfMp3Data) { if (inputLength != C.LENGTH_UNSET && inputLength != position) {
Log.w(TAG, "VBRI data size mismatch: " + inputLength + ", " + endOfMp3Data); Log.w(TAG, "VBRI data size mismatch: " + inputLength + ", " + position);
} }
if (endOfMp3Data != position) { return new VbriSeeker(
Log.w( timesUs, positions, durationUs, /* dataEndPosition= */ position, mpegAudioHeader.bitrate);
TAG,
"VBRI bytes and ToC mismatch (using max): "
+ endOfMp3Data
+ ", "
+ position
+ "\nSeeking will be inaccurate.");
endOfMp3Data = max(endOfMp3Data, position);
}
return new VbriSeeker(timesUs, positions, durationUs, endOfMp3Data, mpegAudioHeader.bitrate);
} }
private final long[] timesUs; private final long[] timesUs;

View file

@ -50,11 +50,6 @@ public final class VorbisCommentTest {
String artist = "artist"; String artist = "artist";
String albumTitle = "album title"; String albumTitle = "album title";
String albumArtist = "album Artist"; String albumArtist = "album Artist";
int trackNumber = 3;
int totalTracks = 12;
int discNumber = 1;
int totalDiscs = 3;
String genre = "Metal";
String description = "a description about the audio."; String description = "a description about the audio.";
List<Metadata.Entry> entries = List<Metadata.Entry> entries =
ImmutableList.of( ImmutableList.of(
@ -62,11 +57,6 @@ public final class VorbisCommentTest {
new VorbisComment("ArTisT", artist), new VorbisComment("ArTisT", artist),
new VorbisComment("ALBUM", albumTitle), new VorbisComment("ALBUM", albumTitle),
new VorbisComment("albumartist", albumArtist), new VorbisComment("albumartist", albumArtist),
new VorbisComment("TRACKNUMBER", String.valueOf(trackNumber)),
new VorbisComment("TOTALTRACKS", String.valueOf(totalTracks)),
new VorbisComment("DISCNUMBER", String.valueOf(discNumber)),
new VorbisComment("TOTALDISCS", String.valueOf(totalDiscs)),
new VorbisComment("GENRE", genre),
new VorbisComment("DESCRIPTION", description)); new VorbisComment("DESCRIPTION", description));
MediaMetadata.Builder builder = MediaMetadata.EMPTY.buildUpon(); MediaMetadata.Builder builder = MediaMetadata.EMPTY.buildUpon();
@ -79,11 +69,6 @@ public final class VorbisCommentTest {
assertThat(mediaMetadata.artist.toString()).isEqualTo(artist); assertThat(mediaMetadata.artist.toString()).isEqualTo(artist);
assertThat(mediaMetadata.albumTitle.toString()).isEqualTo(albumTitle); assertThat(mediaMetadata.albumTitle.toString()).isEqualTo(albumTitle);
assertThat(mediaMetadata.albumArtist.toString()).isEqualTo(albumArtist); assertThat(mediaMetadata.albumArtist.toString()).isEqualTo(albumArtist);
assertThat(mediaMetadata.trackNumber).isEqualTo(trackNumber);
assertThat(mediaMetadata.totalTrackCount).isEqualTo(totalTracks);
assertThat(mediaMetadata.discNumber).isEqualTo(discNumber);
assertThat(mediaMetadata.totalDiscCount).isEqualTo(totalDiscs);
assertThat(mediaMetadata.genre.toString()).isEqualTo(genre);
assertThat(mediaMetadata.description.toString()).isEqualTo(description); assertThat(mediaMetadata.description.toString()).isEqualTo(description);
} }
} }

View file

@ -71,19 +71,6 @@ public final class Mp3ExtractorTest {
simulationConfig); simulationConfig);
} }
@Test
public void mp3SampleWithVbriHeader() throws Exception {
ExtractorAsserts.assertBehavior(
Mp3Extractor::new, "media/mp3/bear-vbr-vbri-header.mp3", simulationConfig);
}
// https://github.com/androidx/media/issues/1904
@Test
public void mp3SampleWithVbriHeaderWithTruncatedToC() throws Exception {
ExtractorAsserts.assertBehavior(
Mp3Extractor::new, "media/mp3/bear-vbr-vbri-header-truncated-toc.mp3", simulationConfig);
}
@Test @Test
public void mp3SampleWithCbrSeeker() throws Exception { public void mp3SampleWithCbrSeeker() throws Exception {
ExtractorAsserts.assertBehavior( ExtractorAsserts.assertBehavior(

View file

@ -113,63 +113,4 @@ public class Mp4MuxerEndToEndNonParameterizedAndroidTest {
/*DumpFileAsserts.assertOutput( /*DumpFileAsserts.assertOutput(
context, fakeExtractorOutput, AndroidMuxerTestUtil.getExpectedDumpFilePath(vp9Mp4));*/ context, fakeExtractorOutput, AndroidMuxerTestUtil.getExpectedDumpFilePath(vp9Mp4));*/
} }
@Test
public void createMp4File_withSampleBatchingDisabled_matchesExpected() throws Exception {
@Nullable Mp4Muxer mp4Muxer = null;
try {
mp4Muxer =
new Mp4Muxer.Builder(checkNotNull(outputStream)).setSampleBatchingEnabled(false).build();
mp4Muxer.addMetadataEntry(
new Mp4TimestampData(
/* creationTimestampSeconds= */ 100_000_000L,
/* modificationTimestampSeconds= */ 500_000_000L));
feedInputDataToMuxer(context, mp4Muxer, checkNotNull(H265_HDR10_MP4));
} finally {
if (mp4Muxer != null) {
mp4Muxer.close();
}
}
FakeExtractorOutput fakeExtractorOutput =
TestUtil.extractAllSamplesFromFilePath(
new Mp4Extractor(new DefaultSubtitleParserFactory()), checkNotNull(outputPath));
DumpFileAsserts.assertOutput(
context,
fakeExtractorOutput,
AndroidMuxerTestUtil.getExpectedDumpFilePath("sample_batching_disabled_" + H265_HDR10_MP4));
}
@Test
public void createMp4File_withSampleBatchingAndAttemptStreamableOutputDisabled_matchesExpected()
throws Exception {
@Nullable Mp4Muxer mp4Muxer = null;
try {
mp4Muxer =
new Mp4Muxer.Builder(checkNotNull(outputStream))
.setSampleBatchingEnabled(false)
.setAttemptStreamableOutputEnabled(false)
.build();
mp4Muxer.addMetadataEntry(
new Mp4TimestampData(
/* creationTimestampSeconds= */ 100_000_000L,
/* modificationTimestampSeconds= */ 500_000_000L));
feedInputDataToMuxer(context, mp4Muxer, checkNotNull(H265_HDR10_MP4));
} finally {
if (mp4Muxer != null) {
mp4Muxer.close();
}
}
FakeExtractorOutput fakeExtractorOutput =
TestUtil.extractAllSamplesFromFilePath(
new Mp4Extractor(new DefaultSubtitleParserFactory()), checkNotNull(outputPath));
DumpFileAsserts.assertOutput(
context,
fakeExtractorOutput,
AndroidMuxerTestUtil.getExpectedDumpFilePath(
"sample_batching_and_attempt_streamable_output_disabled_" + H265_HDR10_MP4));
}
} }

View file

@ -18,6 +18,8 @@ package androidx.media3.muxer;
import static androidx.media3.common.util.Assertions.checkArgument; import static androidx.media3.common.util.Assertions.checkArgument;
import static androidx.media3.common.util.Assertions.checkNotNull; import static androidx.media3.common.util.Assertions.checkNotNull;
import static androidx.media3.common.util.Assertions.checkState; import static androidx.media3.common.util.Assertions.checkState;
import static androidx.media3.muxer.ColorUtils.MEDIAFORMAT_STANDARD_TO_PRIMARIES_AND_MATRIX;
import static androidx.media3.muxer.ColorUtils.MEDIAFORMAT_TRANSFER_TO_MP4_TRANSFER;
import static androidx.media3.muxer.MuxerUtil.UNSIGNED_INT_MAX_VALUE; import static androidx.media3.muxer.MuxerUtil.UNSIGNED_INT_MAX_VALUE;
import static java.lang.Math.abs; import static java.lang.Math.abs;
import static java.lang.Math.max; import static java.lang.Math.max;
@ -765,7 +767,12 @@ import org.checkerframework.checker.nullness.qual.PolyNull;
contents.put(paspBox()); contents.put(paspBox());
if (format.colorInfo != null) { // Put in a "colr" box if any of the three color format parameters has a non-default (0) value.
// TODO: b/278101856 - Only null check should be enough once we disallow invalid values.
if (format.colorInfo != null
&& (format.colorInfo.colorSpace != 0
|| format.colorInfo.colorTransfer != 0
|| format.colorInfo.colorRange != 0)) {
contents.put(colrBox(format.colorInfo)); contents.put(colrBox(format.colorInfo));
} }
@ -1353,14 +1360,13 @@ import org.checkerframework.checker.nullness.qual.PolyNull;
/** Returns the avcC box as per ISO/IEC 14496-15: 5.3.3.1.2. */ /** Returns the avcC box as per ISO/IEC 14496-15: 5.3.3.1.2. */
private static ByteBuffer avcCBox(Format format) { private static ByteBuffer avcCBox(Format format) {
checkArgument( checkArgument(
format.initializationData.size() >= 2, format.initializationData.size() >= 2, "csd-0 and/or csd-1 not found in the format.");
"csd-0 and/or csd-1 not found in the format for avcC box.");
byte[] csd0 = format.initializationData.get(0); byte[] csd0 = format.initializationData.get(0);
checkArgument(csd0.length > 0, "csd-0 is empty for avcC box."); checkArgument(csd0.length > 0, "csd-0 is empty.");
byte[] csd1 = format.initializationData.get(1); byte[] csd1 = format.initializationData.get(1);
checkArgument(csd1.length > 0, "csd-1 is empty for avcC box."); checkArgument(csd1.length > 0, "csd-1 is empty.");
ByteBuffer csd0ByteBuffer = ByteBuffer.wrap(csd0); ByteBuffer csd0ByteBuffer = ByteBuffer.wrap(csd0);
ByteBuffer csd1ByteBuffer = ByteBuffer.wrap(csd1); ByteBuffer csd1ByteBuffer = ByteBuffer.wrap(csd1);
@ -1372,7 +1378,7 @@ import org.checkerframework.checker.nullness.qual.PolyNull;
contents.put((byte) 0x01); // configurationVersion contents.put((byte) 0x01); // configurationVersion
ImmutableList<ByteBuffer> csd0NalUnits = AnnexBUtils.findNalUnits(csd0ByteBuffer); ImmutableList<ByteBuffer> csd0NalUnits = AnnexBUtils.findNalUnits(csd0ByteBuffer);
checkArgument(csd0NalUnits.size() == 1, "SPS data not found in csd0 for avcC box."); checkArgument(csd0NalUnits.size() == 1, "SPS data not found in csd0.");
ByteBuffer sps = csd0NalUnits.get(0); ByteBuffer sps = csd0NalUnits.get(0);
byte[] spsData = new byte[sps.remaining()]; byte[] spsData = new byte[sps.remaining()];
@ -1408,11 +1414,10 @@ import org.checkerframework.checker.nullness.qual.PolyNull;
/** Returns the hvcC box as per ISO/IEC 14496-15: 8.3.3.1.2. */ /** Returns the hvcC box as per ISO/IEC 14496-15: 8.3.3.1.2. */
private static ByteBuffer hvcCBox(Format format) { private static ByteBuffer hvcCBox(Format format) {
// For H.265, all three codec-specific NALUs (VPS, SPS, PPS) are packed into csd-0. // For H.265, all three codec-specific NALUs (VPS, SPS, PPS) are packed into csd-0.
checkArgument( checkArgument(!format.initializationData.isEmpty(), "csd-0 not found in the format.");
!format.initializationData.isEmpty(), "csd-0 not found in the format for hvcC box.");
byte[] csd0 = format.initializationData.get(0); byte[] csd0 = format.initializationData.get(0);
checkArgument(csd0.length > 0, "csd-0 is empty for hvcC box."); checkArgument(csd0.length > 0, "csd-0 is empty.");
ByteBuffer csd0ByteBuffer = ByteBuffer.wrap(csd0); ByteBuffer csd0ByteBuffer = ByteBuffer.wrap(csd0);
@ -1502,11 +1507,10 @@ import org.checkerframework.checker.nullness.qual.PolyNull;
/** Returns the av1C box. */ /** Returns the av1C box. */
private static ByteBuffer av1CBox(Format format) { private static ByteBuffer av1CBox(Format format) {
// For AV1, the entire codec-specific box is packed into csd-0. // For AV1, the entire codec-specific box is packed into csd-0.
checkArgument( checkArgument(!format.initializationData.isEmpty(), "csd-0 is not found in the format");
!format.initializationData.isEmpty(), "csd-0 is not found in the format for av1C box");
byte[] csd0 = format.initializationData.get(0); byte[] csd0 = format.initializationData.get(0);
checkArgument(csd0.length > 0, "csd-0 is empty for av1C box."); checkArgument(csd0.length > 0, "csd-0 is empty.");
return BoxUtils.wrapIntoBox("av1C", ByteBuffer.wrap(csd0)); return BoxUtils.wrapIntoBox("av1C", ByteBuffer.wrap(csd0));
} }
@ -1514,8 +1518,7 @@ import org.checkerframework.checker.nullness.qual.PolyNull;
/** Returns the vpcC box as per VP Codec ISO Media File Format Binding v1.0. */ /** Returns the vpcC box as per VP Codec ISO Media File Format Binding v1.0. */
private static ByteBuffer vpcCBox(Format format) { private static ByteBuffer vpcCBox(Format format) {
// For VP9, the CodecPrivate or vpcCBox data is packed into csd-0. // For VP9, the CodecPrivate or vpcCBox data is packed into csd-0.
checkArgument( checkArgument(!format.initializationData.isEmpty(), "csd-0 is not found in the format");
!format.initializationData.isEmpty(), "csd-0 is not found in the format for vpcC box");
byte[] csd0 = format.initializationData.get(0); byte[] csd0 = format.initializationData.get(0);
checkArgument(csd0.length > 3, "csd-0 for vp9 is invalid."); checkArgument(csd0.length > 3, "csd-0 for vp9 is invalid.");
int versionAndFlags = 1 << 24; // version (value 1, 8 bits) + flag (value 0, 24 bits) int versionAndFlags = 1 << 24; // version (value 1, 8 bits) + flag (value 0, 24 bits)
@ -1537,18 +1540,24 @@ import org.checkerframework.checker.nullness.qual.PolyNull;
// The default values for optional fields as per the : <a // The default values for optional fields as per the : <a
// href="https://www.webmproject.org/vp9/mp4/#optional-fields">Vp9 webm spec</a> // href="https://www.webmproject.org/vp9/mp4/#optional-fields">Vp9 webm spec</a>
int colorPrimaries = 1; int colourPrimaries = 1;
int transferCharacteristics = 1; int transferCharacteristics = 1;
int matrixCoefficients = 1; int matrixCoefficients = 1;
if (format.colorInfo != null) { if (format.colorInfo != null) {
colorPrimaries = ColorInfo.colorSpaceToIsoColorPrimaries(format.colorInfo.colorSpace); ColorInfo colorInfo = format.colorInfo;
transferCharacteristics = if (colorInfo.colorSpace != Format.NO_VALUE) {
ColorInfo.colorTransferToIsoTransferCharacteristics(format.colorInfo.colorTransfer); colourPrimaries =
matrixCoefficients = ColorInfo.colorSpaceToIsoMatrixCoefficients(format.colorInfo.colorSpace); MEDIAFORMAT_STANDARD_TO_PRIMARIES_AND_MATRIX.get(colorInfo.colorSpace).get(0);
matrixCoefficients =
MEDIAFORMAT_STANDARD_TO_PRIMARIES_AND_MATRIX.get(colorInfo.colorSpace).get(1);
}
if (colorInfo.colorTransfer != Format.NO_VALUE) {
transferCharacteristics = MEDIAFORMAT_TRANSFER_TO_MP4_TRANSFER.get(colorInfo.colorTransfer);
}
} }
contents.put((byte) colorPrimaries); contents.put((byte) colourPrimaries);
contents.put((byte) transferCharacteristics); contents.put((byte) transferCharacteristics);
contents.put((byte) matrixCoefficients); contents.put((byte) matrixCoefficients);
contents.putShort((short) 0); // codecInitializationDataSize must be 0 for VP9 contents.putShort((short) 0); // codecInitializationDataSize must be 0 for VP9
@ -1639,11 +1648,40 @@ import org.checkerframework.checker.nullness.qual.PolyNull;
contents.put((byte) 'l'); contents.put((byte) 'l');
contents.put((byte) 'x'); contents.put((byte) 'x');
short primaries = (short) ColorInfo.colorSpaceToIsoColorPrimaries(colorInfo.colorSpace); short primaries = 0;
short transfer = short transfer = 0;
(short) ColorInfo.colorTransferToIsoTransferCharacteristics(colorInfo.colorTransfer); short matrix = 0;
short matrix = (short) ColorInfo.colorSpaceToIsoMatrixCoefficients(colorInfo.colorSpace); byte range = 0;
byte range = colorInfo.colorRange == C.COLOR_RANGE_FULL ? (byte) 0x80 : 0;
if (colorInfo.colorSpace != Format.NO_VALUE) {
int standard = colorInfo.colorSpace;
if (standard < 0 || standard >= MEDIAFORMAT_STANDARD_TO_PRIMARIES_AND_MATRIX.size()) {
throw new IllegalArgumentException("Color standard not implemented: " + standard);
}
primaries = MEDIAFORMAT_STANDARD_TO_PRIMARIES_AND_MATRIX.get(standard).get(0);
matrix = MEDIAFORMAT_STANDARD_TO_PRIMARIES_AND_MATRIX.get(standard).get(1);
}
if (colorInfo.colorTransfer != Format.NO_VALUE) {
int transferInFormat = colorInfo.colorTransfer;
if (transferInFormat < 0 || transferInFormat >= MEDIAFORMAT_TRANSFER_TO_MP4_TRANSFER.size()) {
throw new IllegalArgumentException("Color transfer not implemented: " + transferInFormat);
}
transfer = MEDIAFORMAT_TRANSFER_TO_MP4_TRANSFER.get(transferInFormat);
}
if (colorInfo.colorRange != Format.NO_VALUE) {
int rangeInFormat = colorInfo.colorRange;
// Handled values are 0 (unknown), 1 (full) and 2 (limited).
if (rangeInFormat < 0 || rangeInFormat > 2) {
throw new IllegalArgumentException("Color range not implemented: " + rangeInFormat);
}
// Set this to 0x80 only for full range, 0 otherwise.
range = rangeInFormat == C.COLOR_RANGE_FULL ? (byte) 0x80 : 0;
}
contents.putShort(primaries); contents.putShort(primaries);
contents.putShort(transfer); contents.putShort(transfer);
@ -1686,11 +1724,10 @@ import org.checkerframework.checker.nullness.qual.PolyNull;
/** Returns the esds box. */ /** Returns the esds box. */
private static ByteBuffer esdsBox(Format format) { private static ByteBuffer esdsBox(Format format) {
checkArgument( checkArgument(!format.initializationData.isEmpty(), "csd-0 not found in the format.");
!format.initializationData.isEmpty(), "csd-0 not found in the format for esds box.");
byte[] csd0 = format.initializationData.get(0); byte[] csd0 = format.initializationData.get(0);
checkArgument(csd0.length > 0, "csd-0 is empty for esds box."); checkArgument(csd0.length > 0, "csd-0 is empty.");
String mimeType = checkNotNull(format.sampleMimeType); String mimeType = checkNotNull(format.sampleMimeType);
boolean isVorbis = mimeType.equals(MimeTypes.AUDIO_VORBIS); boolean isVorbis = mimeType.equals(MimeTypes.AUDIO_VORBIS);
@ -1810,8 +1847,7 @@ import org.checkerframework.checker.nullness.qual.PolyNull;
/** Returns the audio dOps box for Opus codec as per RFC-7845: 5.1. */ /** Returns the audio dOps box for Opus codec as per RFC-7845: 5.1. */
private static ByteBuffer dOpsBox(Format format) { private static ByteBuffer dOpsBox(Format format) {
checkArgument( checkArgument(!format.initializationData.isEmpty());
!format.initializationData.isEmpty(), "csd-0 not found in the format for dOps box.");
int opusHeaderLength = 8; int opusHeaderLength = 8;
byte[] csd0 = format.initializationData.get(0); byte[] csd0 = format.initializationData.get(0);

View file

@ -0,0 +1,97 @@
/*
* Copyright 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package androidx.media3.muxer;
import android.media.MediaFormat;
import com.google.common.collect.ImmutableList;
/** Utilities for color information. */
/* package */ final class ColorUtils {
// The constants are defined as per ISO/IEC 29199-2 (mentioned in MP4 spec ISO/IEC 14496-12:
// 8.5.2.3).
private static final short TRANSFER_SMPTE170_M = 1; // Main; also 6, 14 and 15
private static final short TRANSFER_UNSPECIFIED = 2;
private static final short TRANSFER_GAMMA22 = 4;
private static final short TRANSFER_GAMMA28 = 5;
private static final short TRANSFER_SMPTE240_M = 7;
private static final short TRANSFER_LINEAR = 8;
private static final short TRANSFER_OTHER = 9; // Also 10
private static final short TRANSFER_XV_YCC = 11;
private static final short TRANSFER_BT1361 = 12;
private static final short TRANSFER_SRGB = 13;
private static final short TRANSFER_ST2084 = 16;
private static final short TRANSFER_ST428 = 17;
private static final short TRANSFER_HLG = 18;
// MediaFormat contains three color-related fields: "standard", "transfer" and "range". The color
// standard maps to "primaries" and "matrix" in the "colr" box, while "transfer" and "range" are
// mapped to a single value each (although for "transfer", it's still not the same enum values).
private static final short PRIMARIES_BT709_5 = 1;
private static final short PRIMARIES_UNSPECIFIED = 2;
private static final short PRIMARIES_BT601_6_625 = 5;
private static final short PRIMARIES_BT601_6_525 = 6; // It's also 7?
private static final short PRIMARIES_GENERIC_FILM = 8;
private static final short PRIMARIES_BT2020 = 9;
private static final short PRIMARIES_BT470_6_M = 4;
private static final short MATRIX_UNSPECIFIED = 2;
private static final short MATRIX_BT709_5 = 1;
private static final short MATRIX_BT601_6 = 6;
private static final short MATRIX_SMPTE240_M = 7;
private static final short MATRIX_BT2020 = 9;
private static final short MATRIX_BT2020_CONSTANT = 10;
private static final short MATRIX_BT470_6_M = 4;
/**
* Map from {@link MediaFormat} standards to MP4 primaries and matrix indices.
*
* <p>The i-th element corresponds to a {@link MediaFormat} value of i.
*/
public static final ImmutableList<ImmutableList<Short>>
MEDIAFORMAT_STANDARD_TO_PRIMARIES_AND_MATRIX =
ImmutableList.of(
ImmutableList.of(PRIMARIES_UNSPECIFIED, MATRIX_UNSPECIFIED), // Unspecified
ImmutableList.of(PRIMARIES_BT709_5, MATRIX_BT709_5), // BT709
ImmutableList.of(PRIMARIES_BT601_6_625, MATRIX_BT601_6), // BT601_625
ImmutableList.of(PRIMARIES_BT601_6_625, MATRIX_BT709_5), // BT601_625_Unadjusted
ImmutableList.of(PRIMARIES_BT601_6_525, MATRIX_BT601_6), // BT601_525
ImmutableList.of(PRIMARIES_BT601_6_525, MATRIX_SMPTE240_M), // BT601_525_Unadjusted
ImmutableList.of(PRIMARIES_BT2020, MATRIX_BT2020), // BT2020
ImmutableList.of(PRIMARIES_BT2020, MATRIX_BT2020_CONSTANT), // BT2020Constant
ImmutableList.of(PRIMARIES_BT470_6_M, MATRIX_BT470_6_M), // BT470M
ImmutableList.of(PRIMARIES_GENERIC_FILM, MATRIX_BT2020) // Film
);
/**
* Map from {@link MediaFormat} standards to MP4 transfer indices.
*
* <p>The i-th element corresponds to a {@link MediaFormat} value of i.
*/
public static final ImmutableList<Short> MEDIAFORMAT_TRANSFER_TO_MP4_TRANSFER =
ImmutableList.of(
TRANSFER_UNSPECIFIED, // Unspecified
TRANSFER_LINEAR, // Linear
TRANSFER_SRGB, // SRGB
TRANSFER_SMPTE170_M, // SMPTE_170M
TRANSFER_GAMMA22, // Gamma22
TRANSFER_GAMMA28, // Gamma28
TRANSFER_ST2084, // ST2084
TRANSFER_HLG // HLG
);
private ColorUtils() {}
}

View file

@ -200,7 +200,6 @@ public final class Mp4Muxer implements Muxer {
private @LastSampleDurationBehavior int lastSampleDurationBehavior; private @LastSampleDurationBehavior int lastSampleDurationBehavior;
@Nullable private AnnexBToAvccConverter annexBToAvccConverter; @Nullable private AnnexBToAvccConverter annexBToAvccConverter;
private boolean sampleCopyEnabled; private boolean sampleCopyEnabled;
private boolean sampleBatchingEnabled;
private boolean attemptStreamableOutputEnabled; private boolean attemptStreamableOutputEnabled;
private @FileFormat int outputFileFormat; private @FileFormat int outputFileFormat;
@Nullable private EditableVideoParameters editableVideoParameters; @Nullable private EditableVideoParameters editableVideoParameters;
@ -215,7 +214,6 @@ public final class Mp4Muxer implements Muxer {
lastSampleDurationBehavior = lastSampleDurationBehavior =
LAST_SAMPLE_DURATION_BEHAVIOR_SET_FROM_END_OF_STREAM_BUFFER_OR_DUPLICATE_PREVIOUS; LAST_SAMPLE_DURATION_BEHAVIOR_SET_FROM_END_OF_STREAM_BUFFER_OR_DUPLICATE_PREVIOUS;
sampleCopyEnabled = true; sampleCopyEnabled = true;
sampleBatchingEnabled = true;
attemptStreamableOutputEnabled = true; attemptStreamableOutputEnabled = true;
outputFileFormat = FILE_FORMAT_DEFAULT; outputFileFormat = FILE_FORMAT_DEFAULT;
} }
@ -262,21 +260,6 @@ public final class Mp4Muxer implements Muxer {
return this; return this;
} }
/**
* Sets whether to enable sample batching.
*
* <p>If sample batching is enabled, samples are {@linkplain #writeSampleData(TrackToken,
* ByteBuffer, BufferInfo) written} in batches for each track, otherwise samples are written as
* they arrive.
*
* <p>The default value is {@code true}.
*/
@CanIgnoreReturnValue
public Mp4Muxer.Builder setSampleBatchingEnabled(boolean enabled) {
this.sampleBatchingEnabled = enabled;
return this;
}
/** /**
* Sets whether to attempt to write a file where the metadata is stored at the start, which can * Sets whether to attempt to write a file where the metadata is stored at the start, which can
* make the file more efficient to read sequentially. * make the file more efficient to read sequentially.
@ -326,7 +309,6 @@ public final class Mp4Muxer implements Muxer {
lastSampleDurationBehavior, lastSampleDurationBehavior,
annexBToAvccConverter == null ? AnnexBToAvccConverter.DEFAULT : annexBToAvccConverter, annexBToAvccConverter == null ? AnnexBToAvccConverter.DEFAULT : annexBToAvccConverter,
sampleCopyEnabled, sampleCopyEnabled,
sampleBatchingEnabled,
attemptStreamableOutputEnabled, attemptStreamableOutputEnabled,
outputFileFormat, outputFileFormat,
editableVideoParameters); editableVideoParameters);
@ -340,7 +322,6 @@ public final class Mp4Muxer implements Muxer {
private final @LastSampleDurationBehavior int lastSampleDurationBehavior; private final @LastSampleDurationBehavior int lastSampleDurationBehavior;
private final AnnexBToAvccConverter annexBToAvccConverter; private final AnnexBToAvccConverter annexBToAvccConverter;
private final boolean sampleCopyEnabled; private final boolean sampleCopyEnabled;
private final boolean sampleBatchingEnabled;
private final boolean attemptStreamableOutputEnabled; private final boolean attemptStreamableOutputEnabled;
private final @FileFormat int outputFileFormat; private final @FileFormat int outputFileFormat;
@Nullable private final EditableVideoParameters editableVideoParameters; @Nullable private final EditableVideoParameters editableVideoParameters;
@ -358,7 +339,6 @@ public final class Mp4Muxer implements Muxer {
@LastSampleDurationBehavior int lastFrameDurationBehavior, @LastSampleDurationBehavior int lastFrameDurationBehavior,
AnnexBToAvccConverter annexBToAvccConverter, AnnexBToAvccConverter annexBToAvccConverter,
boolean sampleCopyEnabled, boolean sampleCopyEnabled,
boolean sampleBatchingEnabled,
boolean attemptStreamableOutputEnabled, boolean attemptStreamableOutputEnabled,
@FileFormat int outputFileFormat, @FileFormat int outputFileFormat,
@Nullable EditableVideoParameters editableVideoParameters) { @Nullable EditableVideoParameters editableVideoParameters) {
@ -367,7 +347,6 @@ public final class Mp4Muxer implements Muxer {
this.lastSampleDurationBehavior = lastFrameDurationBehavior; this.lastSampleDurationBehavior = lastFrameDurationBehavior;
this.annexBToAvccConverter = annexBToAvccConverter; this.annexBToAvccConverter = annexBToAvccConverter;
this.sampleCopyEnabled = sampleCopyEnabled; this.sampleCopyEnabled = sampleCopyEnabled;
this.sampleBatchingEnabled = sampleBatchingEnabled;
this.attemptStreamableOutputEnabled = attemptStreamableOutputEnabled; this.attemptStreamableOutputEnabled = attemptStreamableOutputEnabled;
this.outputFileFormat = outputFileFormat; this.outputFileFormat = outputFileFormat;
this.editableVideoParameters = editableVideoParameters; this.editableVideoParameters = editableVideoParameters;
@ -379,7 +358,6 @@ public final class Mp4Muxer implements Muxer {
annexBToAvccConverter, annexBToAvccConverter,
lastFrameDurationBehavior, lastFrameDurationBehavior,
sampleCopyEnabled, sampleCopyEnabled,
sampleBatchingEnabled,
attemptStreamableOutputEnabled); attemptStreamableOutputEnabled);
editableVideoTracks = new ArrayList<>(); editableVideoTracks = new ArrayList<>();
} }
@ -437,13 +415,10 @@ public final class Mp4Muxer implements Muxer {
/** /**
* {@inheritDoc} * {@inheritDoc}
* *
* <p>When sample batching is {@linkplain Mp4Muxer.Builder#setSampleBatchingEnabled(boolean) * <p>Samples are written to the file in batches. If {@link Builder#setSampleCopyEnabled(boolean)
* enabled}, provide sample data ({@link ByteBuffer}, {@link BufferInfo}) that won't be modified * sample copying} is disabled, the {@code byteBuffer} and the {@code bufferInfo} must not be
* after calling the {@link #writeSampleData(TrackToken, ByteBuffer, BufferInfo)} method, unless * modified after calling this method. Otherwise, they are copied and it is safe to modify them
* sample copying is also {@linkplain Mp4Muxer.Builder#setSampleCopyEnabled(boolean) enabled}. * after this method returns.
* This ensures data integrity within the batch. If sample copying is {@linkplain
* Mp4Muxer.Builder#setSampleCopyEnabled(boolean) enabled}, it's safe to modify the data after the
* method returns, as the muxer internally creates a sample copy.
* *
* @param trackToken The {@link TrackToken} for which this sample is being written. * @param trackToken The {@link TrackToken} for which this sample is being written.
* @param byteBuffer The encoded sample. The muxer takes ownership of the buffer if {@link * @param byteBuffer The encoded sample. The muxer takes ownership of the buffer if {@link
@ -547,7 +522,6 @@ public final class Mp4Muxer implements Muxer {
annexBToAvccConverter, annexBToAvccConverter,
lastSampleDurationBehavior, lastSampleDurationBehavior,
sampleCopyEnabled, sampleCopyEnabled,
sampleBatchingEnabled,
attemptStreamableOutputEnabled); attemptStreamableOutputEnabled);
} }
} }

View file

@ -43,8 +43,6 @@ import java.util.concurrent.atomic.AtomicBoolean;
/** Writes all media samples into a single mdat box. */ /** Writes all media samples into a single mdat box. */
/* package */ final class Mp4Writer { /* package */ final class Mp4Writer {
private static final long INTERLEAVE_DURATION_US = 1_000_000L; private static final long INTERLEAVE_DURATION_US = 1_000_000L;
// Used for updating the moov box periodically when sample batching is disabled.
private static final long MOOV_BOX_UPDATE_INTERVAL_US = 1_000_000L;
private static final int DEFAULT_MOOV_BOX_SIZE_BYTES = 400_000; private static final int DEFAULT_MOOV_BOX_SIZE_BYTES = 400_000;
private static final String FREE_BOX_TYPE = "free"; private static final String FREE_BOX_TYPE = "free";
@ -53,7 +51,6 @@ import java.util.concurrent.atomic.AtomicBoolean;
private final AnnexBToAvccConverter annexBToAvccConverter; private final AnnexBToAvccConverter annexBToAvccConverter;
private final @Mp4Muxer.LastSampleDurationBehavior int lastSampleDurationBehavior; private final @Mp4Muxer.LastSampleDurationBehavior int lastSampleDurationBehavior;
private final boolean sampleCopyEnabled; private final boolean sampleCopyEnabled;
private final boolean sampleBatchingEnabled;
private final List<Track> tracks; private final List<Track> tracks;
private final List<Track> editableVideoTracks; private final List<Track> editableVideoTracks;
private final AtomicBoolean hasWrittenSamples; private final AtomicBoolean hasWrittenSamples;
@ -66,10 +63,9 @@ import java.util.concurrent.atomic.AtomicBoolean;
private long mdatStart; private long mdatStart;
private long mdatEnd; private long mdatEnd;
private long mdatDataEnd; // Always <= mdatEnd private long mdatDataEnd; // Always <= mdatEnd
// Typically written from the end of the mdat box to the end of the file. // Typically written from the end of the mdat box to the end of the file.
private Range<Long> lastMoovWritten; private Range<Long> lastMoovWritten;
// Used for writing moov box periodically when sample batching is disabled.
private long lastMoovWrittenAtSampleTimestampUs;
/** /**
* Creates an instance. * Creates an instance.
@ -83,7 +79,6 @@ import java.util.concurrent.atomic.AtomicBoolean;
* AVCC format (which uses length prefixes). * AVCC format (which uses length prefixes).
* @param lastSampleDurationBehavior The {@link Mp4Muxer.LastSampleDurationBehavior}. * @param lastSampleDurationBehavior The {@link Mp4Muxer.LastSampleDurationBehavior}.
* @param sampleCopyEnabled Whether sample copying is enabled. * @param sampleCopyEnabled Whether sample copying is enabled.
* @param sampleBatchingEnabled Whether sample batching is enabled.
* @param attemptStreamableOutputEnabled Whether to attempt to write a streamable output. * @param attemptStreamableOutputEnabled Whether to attempt to write a streamable output.
*/ */
public Mp4Writer( public Mp4Writer(
@ -92,20 +87,17 @@ import java.util.concurrent.atomic.AtomicBoolean;
AnnexBToAvccConverter annexBToAvccConverter, AnnexBToAvccConverter annexBToAvccConverter,
@Mp4Muxer.LastSampleDurationBehavior int lastSampleDurationBehavior, @Mp4Muxer.LastSampleDurationBehavior int lastSampleDurationBehavior,
boolean sampleCopyEnabled, boolean sampleCopyEnabled,
boolean sampleBatchingEnabled,
boolean attemptStreamableOutputEnabled) { boolean attemptStreamableOutputEnabled) {
this.outputFileChannel = fileChannel; this.outputFileChannel = fileChannel;
this.metadataCollector = metadataCollector; this.metadataCollector = metadataCollector;
this.annexBToAvccConverter = annexBToAvccConverter; this.annexBToAvccConverter = annexBToAvccConverter;
this.lastSampleDurationBehavior = lastSampleDurationBehavior; this.lastSampleDurationBehavior = lastSampleDurationBehavior;
this.sampleCopyEnabled = sampleCopyEnabled; this.sampleCopyEnabled = sampleCopyEnabled;
this.sampleBatchingEnabled = sampleBatchingEnabled;
tracks = new ArrayList<>(); tracks = new ArrayList<>();
editableVideoTracks = new ArrayList<>(); editableVideoTracks = new ArrayList<>();
hasWrittenSamples = new AtomicBoolean(false); hasWrittenSamples = new AtomicBoolean(false);
canWriteMoovAtStart = attemptStreamableOutputEnabled; canWriteMoovAtStart = attemptStreamableOutputEnabled;
lastMoovWritten = Range.closed(0L, 0L); lastMoovWritten = Range.closed(0L, 0L);
lastMoovWrittenAtSampleTimestampUs = 0L;
} }
/** /**
@ -149,20 +141,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
public void writeSampleData(Track track, ByteBuffer byteBuffer, BufferInfo bufferInfo) public void writeSampleData(Track track, ByteBuffer byteBuffer, BufferInfo bufferInfo)
throws IOException { throws IOException {
track.writeSampleData(byteBuffer, bufferInfo); track.writeSampleData(byteBuffer, bufferInfo);
if (sampleBatchingEnabled) { doInterleave();
doInterleave();
} else {
writePendingTrackSamples(track);
boolean primaryTrackSampleWritten = tracks.contains(track);
long currentSampleTimestampUs = bufferInfo.presentationTimeUs;
if (primaryTrackSampleWritten
&& canWriteMoovAtStart
&& (currentSampleTimestampUs - lastMoovWrittenAtSampleTimestampUs
>= MOOV_BOX_UPDATE_INTERVAL_US)) {
maybeWriteMoovAtStart();
lastMoovWrittenAtSampleTimestampUs = currentSampleTimestampUs;
}
}
} }
/** /**

View file

@ -548,11 +548,8 @@ public final class CommandButton {
/** /**
* [will be deprecated] The icon should be defined with the constructor {@link Icon} parameter * [will be deprecated] The icon should be defined with the constructor {@link Icon} parameter
* in {@link #Builder(int)} instead. * in {@link #Builder(int)} instead. Only in case the existing list of icons is not sufficient,
* * use {@link #ICON_UNDEFINED} and set a separate resource id with {@link #setCustomIconResId}.
* <p>If the existing list of icons is not sufficient, use {@link #ICON_UNDEFINED} for the
* constructor {@link Icon} parameter, and set a separate resource id with {@link
* #setCustomIconResId}.
*/ */
@CanIgnoreReturnValue @CanIgnoreReturnValue
public Builder setIconResId(@DrawableRes int resId) { public Builder setIconResId(@DrawableRes int resId) {
@ -560,10 +557,8 @@ public final class CommandButton {
} }
/** /**
* Sets the fallback resource ID of an icon. * Sets the resource id of an icon that is used when the predefined {@link Icon} is not
* * available or set to {@link #ICON_UNDEFINED}.
* <p>This is used when either the predefined {@link #icon} is not available, or it's set to
* {@link #ICON_UNDEFINED}.
* *
* @param resId The resource id of a custom icon. * @param resId The resource id of a custom icon.
* @return This builder for chaining. * @return This builder for chaining.
@ -576,13 +571,12 @@ public final class CommandButton {
} }
/** /**
* Sets a fallback {@linkplain ContentResolver#SCHEME_CONTENT content} or {@linkplain * Sets a {@linkplain ContentResolver#SCHEME_CONTENT content} or {@linkplain
* ContentResolver#SCHEME_ANDROID_RESOURCE resource} {@link Uri} for the icon of this button. * ContentResolver#SCHEME_ANDROID_RESOURCE resource} {@link Uri} for the icon of this button.
* *
* <p>Note that this {@link Uri} may be used when either the predefined {@link * <p>Note that this {@link Uri} may be used when the predefined {@link Icon} is not available
* CommandButton#icon} is not available, or it's set to {@link #ICON_UNDEFINED}. It can be used * or set to {@link #ICON_UNDEFINED}. It can be used in addition to {@link #setCustomIconResId}
* in addition to {@link #setCustomIconResId} for consumers that are capable of loading the * for consumers that are capable of loading the content or resource {@link Uri}.
* content or resource {@link Uri}.
* *
* @param uri The uri to an icon. * @param uri The uri to an icon.
* @return This builder for chaining. * @return This builder for chaining.
@ -713,23 +707,16 @@ public final class CommandButton {
@UnstableApi public final @Icon int icon; @UnstableApi public final @Icon int icon;
/** /**
* The fallback icon resource ID of the button. * The icon resource id of the button that is used when the predefined {@link #icon} is not
* * available or set to {@link #ICON_UNDEFINED}. Can be {@code 0} if not needed.
* <p>This is used when either the predefined {@link #icon} is not available, or it's set to
* {@link #ICON_UNDEFINED}.
*
* <p>Can be {@code 0} if not needed.
*/ */
@DrawableRes public final int iconResId; @DrawableRes public final int iconResId;
/** /**
* The fallback {@linkplain ContentResolver#SCHEME_CONTENT content} or {@linkplain * The {@linkplain ContentResolver#SCHEME_CONTENT content} or {@linkplain
* ContentResolver#SCHEME_ANDROID_RESOURCE resource} {@link Uri} for the icon of the button. * ContentResolver#SCHEME_ANDROID_RESOURCE resource} {@link Uri} for the icon of the button that
* * is used when the predefined {@link #icon} is not available or set to {@link #ICON_UNDEFINED}.
* <p>This is used when either the predefined {@link #icon} is not available, or it's set to * Can be {@code null}.
* {@link #ICON_UNDEFINED}.
*
* <p>Can be {@code null}.
* *
* <p>Note that this value can be used in addition to {@link #iconResId} for consumers that are * <p>Note that this value can be used in addition to {@link #iconResId} for consumers that are
* capable of loading the content or resource {@link Uri}. * capable of loading the content or resource {@link Uri}.

View file

@ -416,9 +416,8 @@ import org.checkerframework.checker.nullness.qual.NonNull;
if (Util.SDK_INT >= 31 && platformController != null) { if (Util.SDK_INT >= 31 && platformController != null) {
// Ensure the platform session gets allow-listed to start a foreground service after receiving // Ensure the platform session gets allow-listed to start a foreground service after receiving
// the play command. // the play command.
platformController platformController.sendCommand(
.getTransportControls() MediaConstants.SESSION_COMMAND_MEDIA3_PLAY_REQUEST, /* args= */ null, /* cb= */ null);
.sendCustomAction(MediaConstants.SESSION_COMMAND_MEDIA3_PLAY_REQUEST, /* args= */ null);
} }
dispatchRemoteSessionTaskWithPlayerCommand( dispatchRemoteSessionTaskWithPlayerCommand(

View file

@ -281,8 +281,7 @@ import org.checkerframework.checker.initialization.qual.Initialized;
public void onCommand(String commandName, @Nullable Bundle args, @Nullable ResultReceiver cb) { public void onCommand(String commandName, @Nullable Bundle args, @Nullable ResultReceiver cb) {
checkStateNotNull(commandName); checkStateNotNull(commandName);
if (commandName.equals(MediaConstants.SESSION_COMMAND_MEDIA3_PLAY_REQUEST)) { if (commandName.equals(MediaConstants.SESSION_COMMAND_MEDIA3_PLAY_REQUEST)) {
// Only applicable to controllers on Media3 1.5, where this command was sent via sendCommand // Ignore, no need to handle this command here.
// instead of sendCustomAction. No need to handle this command here.
return; return;
} }
if (commandName.equals(MediaConstants.SESSION_COMMAND_REQUEST_SESSION3_TOKEN) && cb != null) { if (commandName.equals(MediaConstants.SESSION_COMMAND_REQUEST_SESSION3_TOKEN) && cb != null) {
@ -306,10 +305,6 @@ import org.checkerframework.checker.initialization.qual.Initialized;
@Override @Override
public void onCustomAction(String action, @Nullable Bundle args) { public void onCustomAction(String action, @Nullable Bundle args) {
if (action.equals(MediaConstants.SESSION_COMMAND_MEDIA3_PLAY_REQUEST)) {
// Ignore, no need to handle the custom action.
return;
}
SessionCommand command = new SessionCommand(action, /* extras= */ Bundle.EMPTY); SessionCommand command = new SessionCommand(action, /* extras= */ Bundle.EMPTY);
dispatchSessionTaskWithSessionCommand( dispatchSessionTaskWithSessionCommand(
command, command,

View file

@ -1,487 +0,0 @@
seekMap:
isSeekable = true
duration = 2808000
getPosition(0) = [[timeUs=0, position=141]]
getPosition(1) = [[timeUs=0, position=141], [timeUs=1404000, position=10413]]
getPosition(1404000) = [[timeUs=1404000, position=10413]]
getPosition(2808000) = [[timeUs=1404000, position=10413]]
numberOfTracks = 1
track 0:
total output bytes = 38160
sample count = 117
format 0:
averageBitrate = 32000
sampleMimeType = audio/mpeg
maxInputSize = 4096
channelCount = 2
sampleRate = 48000
metadata = entries=[TSSE: description=null: values=[Lavf58.29.100]]
sample 0:
time = 0
flags = 1
data = length 96, hash 1F161542
sample 1:
time = 24000
flags = 1
data = length 768, hash CD1DC50F
sample 2:
time = 48000
flags = 1
data = length 336, hash 3F64124B
sample 3:
time = 72000
flags = 1
data = length 336, hash 8FFED94E
sample 4:
time = 96000
flags = 1
data = length 288, hash 9CD77D47
sample 5:
time = 120000
flags = 1
data = length 384, hash 24607BB5
sample 6:
time = 144000
flags = 1
data = length 480, hash 4937EBAB
sample 7:
time = 168000
flags = 1
data = length 336, hash 546342B1
sample 8:
time = 192000
flags = 1
data = length 336, hash 79E0923F
sample 9:
time = 216000
flags = 1
data = length 336, hash AB1F3948
sample 10:
time = 240000
flags = 1
data = length 336, hash C3A4D888
sample 11:
time = 264000
flags = 1
data = length 288, hash 7867DA45
sample 12:
time = 288000
flags = 1
data = length 336, hash B1240B73
sample 13:
time = 312000
flags = 1
data = length 336, hash 94CFCD35
sample 14:
time = 336000
flags = 1
data = length 288, hash 94F412C
sample 15:
time = 360000
flags = 1
data = length 336, hash A1D9FF41
sample 16:
time = 384000
flags = 1
data = length 288, hash 2A8DA21B
sample 17:
time = 408000
flags = 1
data = length 336, hash 6A429CE
sample 18:
time = 432000
flags = 1
data = length 336, hash 68853982
sample 19:
time = 456000
flags = 1
data = length 384, hash 1D6F779C
sample 20:
time = 480000
flags = 1
data = length 480, hash 6B31EBEE
sample 21:
time = 504000
flags = 1
data = length 336, hash 888335BE
sample 22:
time = 528000
flags = 1
data = length 336, hash 6072AC8B
sample 23:
time = 552000
flags = 1
data = length 336, hash C9D24234
sample 24:
time = 576000
flags = 1
data = length 288, hash 52BF4D1E
sample 25:
time = 600000
flags = 1
data = length 336, hash F93F4F0
sample 26:
time = 624000
flags = 1
data = length 336, hash 8617688A
sample 27:
time = 648000
flags = 1
data = length 480, hash FAB0D31B
sample 28:
time = 672000
flags = 1
data = length 384, hash FA4B53E2
sample 29:
time = 696000
flags = 1
data = length 336, hash 8C435F6A
sample 30:
time = 720000
flags = 1
data = length 336, hash 60D3F80C
sample 31:
time = 744000
flags = 1
data = length 336, hash DC15B68B
sample 32:
time = 768000
flags = 1
data = length 288, hash FF3DF141
sample 33:
time = 792000
flags = 1
data = length 336, hash A64B3042
sample 34:
time = 816000
flags = 1
data = length 336, hash ACA622A1
sample 35:
time = 840000
flags = 1
data = length 288, hash 3E34B8D4
sample 36:
time = 864000
flags = 1
data = length 288, hash 9B96F72A
sample 37:
time = 888000
flags = 1
data = length 336, hash E917C122
sample 38:
time = 912000
flags = 1
data = length 336, hash 10ED1470
sample 39:
time = 936000
flags = 1
data = length 288, hash 706B8A7C
sample 40:
time = 960000
flags = 1
data = length 336, hash 71FFE4A0
sample 41:
time = 984000
flags = 1
data = length 336, hash D4160463
sample 42:
time = 1008000
flags = 1
data = length 336, hash EC557B14
sample 43:
time = 1032000
flags = 1
data = length 288, hash 5598CF8B
sample 44:
time = 1056000
flags = 1
data = length 336, hash 7E0AB41
sample 45:
time = 1080000
flags = 1
data = length 336, hash 1C585FEF
sample 46:
time = 1104000
flags = 1
data = length 336, hash A4A4855E
sample 47:
time = 1128000
flags = 1
data = length 336, hash CECA51D3
sample 48:
time = 1152000
flags = 1
data = length 288, hash 2D362DC5
sample 49:
time = 1176000
flags = 1
data = length 336, hash 9EB2609D
sample 50:
time = 1200000
flags = 1
data = length 336, hash 28FFB3FE
sample 51:
time = 1224000
flags = 1
data = length 288, hash 2AA2D216
sample 52:
time = 1248000
flags = 1
data = length 336, hash CDBC7032
sample 53:
time = 1272000
flags = 1
data = length 336, hash 25B13FE7
sample 54:
time = 1296000
flags = 1
data = length 336, hash DB6BB1E
sample 55:
time = 1320000
flags = 1
data = length 336, hash EBE951F4
sample 56:
time = 1344000
flags = 1
data = length 288, hash 9E2EBFF7
sample 57:
time = 1368000
flags = 1
data = length 336, hash 36A7D455
sample 58:
time = 1392000
flags = 1
data = length 336, hash 84545F8C
sample 59:
time = 1416000
flags = 1
data = length 336, hash F66F3045
sample 60:
time = 1440000
flags = 1
data = length 576, hash 5AB089EA
sample 61:
time = 1464000
flags = 1
data = length 336, hash 8868086
sample 62:
time = 1488000
flags = 1
data = length 336, hash D5EB6D63
sample 63:
time = 1512000
flags = 1
data = length 288, hash 7A5374B7
sample 64:
time = 1536000
flags = 1
data = length 336, hash BEB27A75
sample 65:
time = 1560000
flags = 1
data = length 336, hash E251E0FD
sample 66:
time = 1584000
flags = 1
data = length 288, hash D54C970
sample 67:
time = 1608000
flags = 1
data = length 336, hash 52C473B9
sample 68:
time = 1632000
flags = 1
data = length 336, hash F5F13334
sample 69:
time = 1656000
flags = 1
data = length 480, hash A5F1E987
sample 70:
time = 1680000
flags = 1
data = length 288, hash 453A1267
sample 71:
time = 1704000
flags = 1
data = length 288, hash 7C6C2EA9
sample 72:
time = 1728000
flags = 1
data = length 336, hash F4BFECA4
sample 73:
time = 1752000
flags = 1
data = length 336, hash 751A395A
sample 74:
time = 1776000
flags = 1
data = length 336, hash EE38DB02
sample 75:
time = 1800000
flags = 1
data = length 336, hash F18837E2
sample 76:
time = 1824000
flags = 1
data = length 336, hash ED36B78E
sample 77:
time = 1848000
flags = 1
data = length 336, hash B3D28289
sample 78:
time = 1872000
flags = 1
data = length 288, hash 8BDE28E1
sample 79:
time = 1896000
flags = 1
data = length 336, hash CFD5E966
sample 80:
time = 1920000
flags = 1
data = length 288, hash DC08E267
sample 81:
time = 1944000
flags = 1
data = length 336, hash 6530CB78
sample 82:
time = 1968000
flags = 1
data = length 336, hash 6CC6636E
sample 83:
time = 1992000
flags = 1
data = length 336, hash 613047C1
sample 84:
time = 2016000
flags = 1
data = length 288, hash CDC747BF
sample 85:
time = 2040000
flags = 1
data = length 336, hash AF22AA74
sample 86:
time = 2064000
flags = 1
data = length 384, hash 82F326AA
sample 87:
time = 2088000
flags = 1
data = length 384, hash EDA26C4D
sample 88:
time = 2112000
flags = 1
data = length 336, hash 94C643DC
sample 89:
time = 2136000
flags = 1
data = length 288, hash CB5D9C40
sample 90:
time = 2160000
flags = 1
data = length 336, hash 1E69DE3F
sample 91:
time = 2184000
flags = 1
data = length 336, hash 7E472219
sample 92:
time = 2208000
flags = 1
data = length 336, hash DA47B9FA
sample 93:
time = 2232000
flags = 1
data = length 336, hash DD0ABB7C
sample 94:
time = 2256000
flags = 1
data = length 288, hash DBF93FAC
sample 95:
time = 2280000
flags = 1
data = length 336, hash 243F4B2
sample 96:
time = 2304000
flags = 1
data = length 336, hash 2E881490
sample 97:
time = 2328000
flags = 1
data = length 288, hash 1C28C8BE
sample 98:
time = 2352000
flags = 1
data = length 336, hash C73E5D30
sample 99:
time = 2376000
flags = 1
data = length 288, hash 98B5BFF6
sample 100:
time = 2400000
flags = 1
data = length 336, hash E0135533
sample 101:
time = 2424000
flags = 1
data = length 336, hash D13C9DBC
sample 102:
time = 2448000
flags = 1
data = length 336, hash 63D524CA
sample 103:
time = 2472000
flags = 1
data = length 288, hash A28514C3
sample 104:
time = 2496000
flags = 1
data = length 336, hash 72B647FF
sample 105:
time = 2520000
flags = 1
data = length 336, hash 8F740AB1
sample 106:
time = 2544000
flags = 1
data = length 336, hash 5E3C7E93
sample 107:
time = 2568000
flags = 1
data = length 336, hash 121B913B
sample 108:
time = 2592000
flags = 1
data = length 336, hash 578FCCF2
sample 109:
time = 2616000
flags = 1
data = length 336, hash 5B5823DE
sample 110:
time = 2640000
flags = 1
data = length 384, hash D8B83F78
sample 111:
time = 2664000
flags = 1
data = length 240, hash E649682F
sample 112:
time = 2688000
flags = 1
data = length 96, hash C559A6F4
sample 113:
time = 2712000
flags = 1
data = length 96, hash 792796BC
sample 114:
time = 2736000
flags = 1
data = length 120, hash 8172CD0E
sample 115:
time = 2760000
flags = 1
data = length 120, hash F562B52F
sample 116:
time = 2784000
flags = 1
data = length 96, hash FF8D5B98
tracksEnded = true

View file

@ -1,487 +0,0 @@
seekMap:
isSeekable = true
duration = 2808000
getPosition(0) = [[timeUs=0, position=141]]
getPosition(1) = [[timeUs=0, position=141], [timeUs=1404000, position=10413]]
getPosition(1404000) = [[timeUs=1404000, position=10413]]
getPosition(2808000) = [[timeUs=1404000, position=10413]]
numberOfTracks = 1
track 0:
total output bytes = 38160
sample count = 117
format 0:
averageBitrate = 32000
sampleMimeType = audio/mpeg
maxInputSize = 4096
channelCount = 2
sampleRate = 48000
metadata = entries=[TSSE: description=null: values=[Lavf58.29.100]]
sample 0:
time = 0
flags = 1
data = length 96, hash 1F161542
sample 1:
time = 24000
flags = 1
data = length 768, hash CD1DC50F
sample 2:
time = 48000
flags = 1
data = length 336, hash 3F64124B
sample 3:
time = 72000
flags = 1
data = length 336, hash 8FFED94E
sample 4:
time = 96000
flags = 1
data = length 288, hash 9CD77D47
sample 5:
time = 120000
flags = 1
data = length 384, hash 24607BB5
sample 6:
time = 144000
flags = 1
data = length 480, hash 4937EBAB
sample 7:
time = 168000
flags = 1
data = length 336, hash 546342B1
sample 8:
time = 192000
flags = 1
data = length 336, hash 79E0923F
sample 9:
time = 216000
flags = 1
data = length 336, hash AB1F3948
sample 10:
time = 240000
flags = 1
data = length 336, hash C3A4D888
sample 11:
time = 264000
flags = 1
data = length 288, hash 7867DA45
sample 12:
time = 288000
flags = 1
data = length 336, hash B1240B73
sample 13:
time = 312000
flags = 1
data = length 336, hash 94CFCD35
sample 14:
time = 336000
flags = 1
data = length 288, hash 94F412C
sample 15:
time = 360000
flags = 1
data = length 336, hash A1D9FF41
sample 16:
time = 384000
flags = 1
data = length 288, hash 2A8DA21B
sample 17:
time = 408000
flags = 1
data = length 336, hash 6A429CE
sample 18:
time = 432000
flags = 1
data = length 336, hash 68853982
sample 19:
time = 456000
flags = 1
data = length 384, hash 1D6F779C
sample 20:
time = 480000
flags = 1
data = length 480, hash 6B31EBEE
sample 21:
time = 504000
flags = 1
data = length 336, hash 888335BE
sample 22:
time = 528000
flags = 1
data = length 336, hash 6072AC8B
sample 23:
time = 552000
flags = 1
data = length 336, hash C9D24234
sample 24:
time = 576000
flags = 1
data = length 288, hash 52BF4D1E
sample 25:
time = 600000
flags = 1
data = length 336, hash F93F4F0
sample 26:
time = 624000
flags = 1
data = length 336, hash 8617688A
sample 27:
time = 648000
flags = 1
data = length 480, hash FAB0D31B
sample 28:
time = 672000
flags = 1
data = length 384, hash FA4B53E2
sample 29:
time = 696000
flags = 1
data = length 336, hash 8C435F6A
sample 30:
time = 720000
flags = 1
data = length 336, hash 60D3F80C
sample 31:
time = 744000
flags = 1
data = length 336, hash DC15B68B
sample 32:
time = 768000
flags = 1
data = length 288, hash FF3DF141
sample 33:
time = 792000
flags = 1
data = length 336, hash A64B3042
sample 34:
time = 816000
flags = 1
data = length 336, hash ACA622A1
sample 35:
time = 840000
flags = 1
data = length 288, hash 3E34B8D4
sample 36:
time = 864000
flags = 1
data = length 288, hash 9B96F72A
sample 37:
time = 888000
flags = 1
data = length 336, hash E917C122
sample 38:
time = 912000
flags = 1
data = length 336, hash 10ED1470
sample 39:
time = 936000
flags = 1
data = length 288, hash 706B8A7C
sample 40:
time = 960000
flags = 1
data = length 336, hash 71FFE4A0
sample 41:
time = 984000
flags = 1
data = length 336, hash D4160463
sample 42:
time = 1008000
flags = 1
data = length 336, hash EC557B14
sample 43:
time = 1032000
flags = 1
data = length 288, hash 5598CF8B
sample 44:
time = 1056000
flags = 1
data = length 336, hash 7E0AB41
sample 45:
time = 1080000
flags = 1
data = length 336, hash 1C585FEF
sample 46:
time = 1104000
flags = 1
data = length 336, hash A4A4855E
sample 47:
time = 1128000
flags = 1
data = length 336, hash CECA51D3
sample 48:
time = 1152000
flags = 1
data = length 288, hash 2D362DC5
sample 49:
time = 1176000
flags = 1
data = length 336, hash 9EB2609D
sample 50:
time = 1200000
flags = 1
data = length 336, hash 28FFB3FE
sample 51:
time = 1224000
flags = 1
data = length 288, hash 2AA2D216
sample 52:
time = 1248000
flags = 1
data = length 336, hash CDBC7032
sample 53:
time = 1272000
flags = 1
data = length 336, hash 25B13FE7
sample 54:
time = 1296000
flags = 1
data = length 336, hash DB6BB1E
sample 55:
time = 1320000
flags = 1
data = length 336, hash EBE951F4
sample 56:
time = 1344000
flags = 1
data = length 288, hash 9E2EBFF7
sample 57:
time = 1368000
flags = 1
data = length 336, hash 36A7D455
sample 58:
time = 1392000
flags = 1
data = length 336, hash 84545F8C
sample 59:
time = 1416000
flags = 1
data = length 336, hash F66F3045
sample 60:
time = 1440000
flags = 1
data = length 576, hash 5AB089EA
sample 61:
time = 1464000
flags = 1
data = length 336, hash 8868086
sample 62:
time = 1488000
flags = 1
data = length 336, hash D5EB6D63
sample 63:
time = 1512000
flags = 1
data = length 288, hash 7A5374B7
sample 64:
time = 1536000
flags = 1
data = length 336, hash BEB27A75
sample 65:
time = 1560000
flags = 1
data = length 336, hash E251E0FD
sample 66:
time = 1584000
flags = 1
data = length 288, hash D54C970
sample 67:
time = 1608000
flags = 1
data = length 336, hash 52C473B9
sample 68:
time = 1632000
flags = 1
data = length 336, hash F5F13334
sample 69:
time = 1656000
flags = 1
data = length 480, hash A5F1E987
sample 70:
time = 1680000
flags = 1
data = length 288, hash 453A1267
sample 71:
time = 1704000
flags = 1
data = length 288, hash 7C6C2EA9
sample 72:
time = 1728000
flags = 1
data = length 336, hash F4BFECA4
sample 73:
time = 1752000
flags = 1
data = length 336, hash 751A395A
sample 74:
time = 1776000
flags = 1
data = length 336, hash EE38DB02
sample 75:
time = 1800000
flags = 1
data = length 336, hash F18837E2
sample 76:
time = 1824000
flags = 1
data = length 336, hash ED36B78E
sample 77:
time = 1848000
flags = 1
data = length 336, hash B3D28289
sample 78:
time = 1872000
flags = 1
data = length 288, hash 8BDE28E1
sample 79:
time = 1896000
flags = 1
data = length 336, hash CFD5E966
sample 80:
time = 1920000
flags = 1
data = length 288, hash DC08E267
sample 81:
time = 1944000
flags = 1
data = length 336, hash 6530CB78
sample 82:
time = 1968000
flags = 1
data = length 336, hash 6CC6636E
sample 83:
time = 1992000
flags = 1
data = length 336, hash 613047C1
sample 84:
time = 2016000
flags = 1
data = length 288, hash CDC747BF
sample 85:
time = 2040000
flags = 1
data = length 336, hash AF22AA74
sample 86:
time = 2064000
flags = 1
data = length 384, hash 82F326AA
sample 87:
time = 2088000
flags = 1
data = length 384, hash EDA26C4D
sample 88:
time = 2112000
flags = 1
data = length 336, hash 94C643DC
sample 89:
time = 2136000
flags = 1
data = length 288, hash CB5D9C40
sample 90:
time = 2160000
flags = 1
data = length 336, hash 1E69DE3F
sample 91:
time = 2184000
flags = 1
data = length 336, hash 7E472219
sample 92:
time = 2208000
flags = 1
data = length 336, hash DA47B9FA
sample 93:
time = 2232000
flags = 1
data = length 336, hash DD0ABB7C
sample 94:
time = 2256000
flags = 1
data = length 288, hash DBF93FAC
sample 95:
time = 2280000
flags = 1
data = length 336, hash 243F4B2
sample 96:
time = 2304000
flags = 1
data = length 336, hash 2E881490
sample 97:
time = 2328000
flags = 1
data = length 288, hash 1C28C8BE
sample 98:
time = 2352000
flags = 1
data = length 336, hash C73E5D30
sample 99:
time = 2376000
flags = 1
data = length 288, hash 98B5BFF6
sample 100:
time = 2400000
flags = 1
data = length 336, hash E0135533
sample 101:
time = 2424000
flags = 1
data = length 336, hash D13C9DBC
sample 102:
time = 2448000
flags = 1
data = length 336, hash 63D524CA
sample 103:
time = 2472000
flags = 1
data = length 288, hash A28514C3
sample 104:
time = 2496000
flags = 1
data = length 336, hash 72B647FF
sample 105:
time = 2520000
flags = 1
data = length 336, hash 8F740AB1
sample 106:
time = 2544000
flags = 1
data = length 336, hash 5E3C7E93
sample 107:
time = 2568000
flags = 1
data = length 336, hash 121B913B
sample 108:
time = 2592000
flags = 1
data = length 336, hash 578FCCF2
sample 109:
time = 2616000
flags = 1
data = length 336, hash 5B5823DE
sample 110:
time = 2640000
flags = 1
data = length 384, hash D8B83F78
sample 111:
time = 2664000
flags = 1
data = length 240, hash E649682F
sample 112:
time = 2688000
flags = 1
data = length 96, hash C559A6F4
sample 113:
time = 2712000
flags = 1
data = length 96, hash 792796BC
sample 114:
time = 2736000
flags = 1
data = length 120, hash 8172CD0E
sample 115:
time = 2760000
flags = 1
data = length 120, hash F562B52F
sample 116:
time = 2784000
flags = 1
data = length 96, hash FF8D5B98
tracksEnded = true

View file

@ -1,371 +0,0 @@
seekMap:
isSeekable = true
duration = 2808000
getPosition(0) = [[timeUs=0, position=141]]
getPosition(1) = [[timeUs=0, position=141], [timeUs=1404000, position=10413]]
getPosition(1404000) = [[timeUs=1404000, position=10413]]
getPosition(2808000) = [[timeUs=1404000, position=10413]]
numberOfTracks = 1
track 0:
total output bytes = 27888
sample count = 88
format 0:
averageBitrate = 32000
sampleMimeType = audio/mpeg
maxInputSize = 4096
channelCount = 2
sampleRate = 48000
metadata = entries=[TSSE: description=null: values=[Lavf58.29.100]]
sample 0:
time = 1404000
flags = 1
data = length 336, hash 8C435F6A
sample 1:
time = 1428000
flags = 1
data = length 336, hash 60D3F80C
sample 2:
time = 1452000
flags = 1
data = length 336, hash DC15B68B
sample 3:
time = 1476000
flags = 1
data = length 288, hash FF3DF141
sample 4:
time = 1500000
flags = 1
data = length 336, hash A64B3042
sample 5:
time = 1524000
flags = 1
data = length 336, hash ACA622A1
sample 6:
time = 1548000
flags = 1
data = length 288, hash 3E34B8D4
sample 7:
time = 1572000
flags = 1
data = length 288, hash 9B96F72A
sample 8:
time = 1596000
flags = 1
data = length 336, hash E917C122
sample 9:
time = 1620000
flags = 1
data = length 336, hash 10ED1470
sample 10:
time = 1644000
flags = 1
data = length 288, hash 706B8A7C
sample 11:
time = 1668000
flags = 1
data = length 336, hash 71FFE4A0
sample 12:
time = 1692000
flags = 1
data = length 336, hash D4160463
sample 13:
time = 1716000
flags = 1
data = length 336, hash EC557B14
sample 14:
time = 1740000
flags = 1
data = length 288, hash 5598CF8B
sample 15:
time = 1764000
flags = 1
data = length 336, hash 7E0AB41
sample 16:
time = 1788000
flags = 1
data = length 336, hash 1C585FEF
sample 17:
time = 1812000
flags = 1
data = length 336, hash A4A4855E
sample 18:
time = 1836000
flags = 1
data = length 336, hash CECA51D3
sample 19:
time = 1860000
flags = 1
data = length 288, hash 2D362DC5
sample 20:
time = 1884000
flags = 1
data = length 336, hash 9EB2609D
sample 21:
time = 1908000
flags = 1
data = length 336, hash 28FFB3FE
sample 22:
time = 1932000
flags = 1
data = length 288, hash 2AA2D216
sample 23:
time = 1956000
flags = 1
data = length 336, hash CDBC7032
sample 24:
time = 1980000
flags = 1
data = length 336, hash 25B13FE7
sample 25:
time = 2004000
flags = 1
data = length 336, hash DB6BB1E
sample 26:
time = 2028000
flags = 1
data = length 336, hash EBE951F4
sample 27:
time = 2052000
flags = 1
data = length 288, hash 9E2EBFF7
sample 28:
time = 2076000
flags = 1
data = length 336, hash 36A7D455
sample 29:
time = 2100000
flags = 1
data = length 336, hash 84545F8C
sample 30:
time = 2124000
flags = 1
data = length 336, hash F66F3045
sample 31:
time = 2148000
flags = 1
data = length 576, hash 5AB089EA
sample 32:
time = 2172000
flags = 1
data = length 336, hash 8868086
sample 33:
time = 2196000
flags = 1
data = length 336, hash D5EB6D63
sample 34:
time = 2220000
flags = 1
data = length 288, hash 7A5374B7
sample 35:
time = 2244000
flags = 1
data = length 336, hash BEB27A75
sample 36:
time = 2268000
flags = 1
data = length 336, hash E251E0FD
sample 37:
time = 2292000
flags = 1
data = length 288, hash D54C970
sample 38:
time = 2316000
flags = 1
data = length 336, hash 52C473B9
sample 39:
time = 2340000
flags = 1
data = length 336, hash F5F13334
sample 40:
time = 2364000
flags = 1
data = length 480, hash A5F1E987
sample 41:
time = 2388000
flags = 1
data = length 288, hash 453A1267
sample 42:
time = 2412000
flags = 1
data = length 288, hash 7C6C2EA9
sample 43:
time = 2436000
flags = 1
data = length 336, hash F4BFECA4
sample 44:
time = 2460000
flags = 1
data = length 336, hash 751A395A
sample 45:
time = 2484000
flags = 1
data = length 336, hash EE38DB02
sample 46:
time = 2508000
flags = 1
data = length 336, hash F18837E2
sample 47:
time = 2532000
flags = 1
data = length 336, hash ED36B78E
sample 48:
time = 2556000
flags = 1
data = length 336, hash B3D28289
sample 49:
time = 2580000
flags = 1
data = length 288, hash 8BDE28E1
sample 50:
time = 2604000
flags = 1
data = length 336, hash CFD5E966
sample 51:
time = 2628000
flags = 1
data = length 288, hash DC08E267
sample 52:
time = 2652000
flags = 1
data = length 336, hash 6530CB78
sample 53:
time = 2676000
flags = 1
data = length 336, hash 6CC6636E
sample 54:
time = 2700000
flags = 1
data = length 336, hash 613047C1
sample 55:
time = 2724000
flags = 1
data = length 288, hash CDC747BF
sample 56:
time = 2748000
flags = 1
data = length 336, hash AF22AA74
sample 57:
time = 2772000
flags = 1
data = length 384, hash 82F326AA
sample 58:
time = 2796000
flags = 1
data = length 384, hash EDA26C4D
sample 59:
time = 2820000
flags = 1
data = length 336, hash 94C643DC
sample 60:
time = 2844000
flags = 1
data = length 288, hash CB5D9C40
sample 61:
time = 2868000
flags = 1
data = length 336, hash 1E69DE3F
sample 62:
time = 2892000
flags = 1
data = length 336, hash 7E472219
sample 63:
time = 2916000
flags = 1
data = length 336, hash DA47B9FA
sample 64:
time = 2940000
flags = 1
data = length 336, hash DD0ABB7C
sample 65:
time = 2964000
flags = 1
data = length 288, hash DBF93FAC
sample 66:
time = 2988000
flags = 1
data = length 336, hash 243F4B2
sample 67:
time = 3012000
flags = 1
data = length 336, hash 2E881490
sample 68:
time = 3036000
flags = 1
data = length 288, hash 1C28C8BE
sample 69:
time = 3060000
flags = 1
data = length 336, hash C73E5D30
sample 70:
time = 3084000
flags = 1
data = length 288, hash 98B5BFF6
sample 71:
time = 3108000
flags = 1
data = length 336, hash E0135533
sample 72:
time = 3132000
flags = 1
data = length 336, hash D13C9DBC
sample 73:
time = 3156000
flags = 1
data = length 336, hash 63D524CA
sample 74:
time = 3180000
flags = 1
data = length 288, hash A28514C3
sample 75:
time = 3204000
flags = 1
data = length 336, hash 72B647FF
sample 76:
time = 3228000
flags = 1
data = length 336, hash 8F740AB1
sample 77:
time = 3252000
flags = 1
data = length 336, hash 5E3C7E93
sample 78:
time = 3276000
flags = 1
data = length 336, hash 121B913B
sample 79:
time = 3300000
flags = 1
data = length 336, hash 578FCCF2
sample 80:
time = 3324000
flags = 1
data = length 336, hash 5B5823DE
sample 81:
time = 3348000
flags = 1
data = length 384, hash D8B83F78
sample 82:
time = 3372000
flags = 1
data = length 240, hash E649682F
sample 83:
time = 3396000
flags = 1
data = length 96, hash C559A6F4
sample 84:
time = 3420000
flags = 1
data = length 96, hash 792796BC
sample 85:
time = 3444000
flags = 1
data = length 120, hash 8172CD0E
sample 86:
time = 3468000
flags = 1
data = length 120, hash F562B52F
sample 87:
time = 3492000
flags = 1
data = length 96, hash FF8D5B98
tracksEnded = true

View file

@ -1,371 +0,0 @@
seekMap:
isSeekable = true
duration = 2808000
getPosition(0) = [[timeUs=0, position=141]]
getPosition(1) = [[timeUs=0, position=141], [timeUs=1404000, position=10413]]
getPosition(1404000) = [[timeUs=1404000, position=10413]]
getPosition(2808000) = [[timeUs=1404000, position=10413]]
numberOfTracks = 1
track 0:
total output bytes = 27888
sample count = 88
format 0:
averageBitrate = 32000
sampleMimeType = audio/mpeg
maxInputSize = 4096
channelCount = 2
sampleRate = 48000
metadata = entries=[TSSE: description=null: values=[Lavf58.29.100]]
sample 0:
time = 1404000
flags = 1
data = length 336, hash 8C435F6A
sample 1:
time = 1428000
flags = 1
data = length 336, hash 60D3F80C
sample 2:
time = 1452000
flags = 1
data = length 336, hash DC15B68B
sample 3:
time = 1476000
flags = 1
data = length 288, hash FF3DF141
sample 4:
time = 1500000
flags = 1
data = length 336, hash A64B3042
sample 5:
time = 1524000
flags = 1
data = length 336, hash ACA622A1
sample 6:
time = 1548000
flags = 1
data = length 288, hash 3E34B8D4
sample 7:
time = 1572000
flags = 1
data = length 288, hash 9B96F72A
sample 8:
time = 1596000
flags = 1
data = length 336, hash E917C122
sample 9:
time = 1620000
flags = 1
data = length 336, hash 10ED1470
sample 10:
time = 1644000
flags = 1
data = length 288, hash 706B8A7C
sample 11:
time = 1668000
flags = 1
data = length 336, hash 71FFE4A0
sample 12:
time = 1692000
flags = 1
data = length 336, hash D4160463
sample 13:
time = 1716000
flags = 1
data = length 336, hash EC557B14
sample 14:
time = 1740000
flags = 1
data = length 288, hash 5598CF8B
sample 15:
time = 1764000
flags = 1
data = length 336, hash 7E0AB41
sample 16:
time = 1788000
flags = 1
data = length 336, hash 1C585FEF
sample 17:
time = 1812000
flags = 1
data = length 336, hash A4A4855E
sample 18:
time = 1836000
flags = 1
data = length 336, hash CECA51D3
sample 19:
time = 1860000
flags = 1
data = length 288, hash 2D362DC5
sample 20:
time = 1884000
flags = 1
data = length 336, hash 9EB2609D
sample 21:
time = 1908000
flags = 1
data = length 336, hash 28FFB3FE
sample 22:
time = 1932000
flags = 1
data = length 288, hash 2AA2D216
sample 23:
time = 1956000
flags = 1
data = length 336, hash CDBC7032
sample 24:
time = 1980000
flags = 1
data = length 336, hash 25B13FE7
sample 25:
time = 2004000
flags = 1
data = length 336, hash DB6BB1E
sample 26:
time = 2028000
flags = 1
data = length 336, hash EBE951F4
sample 27:
time = 2052000
flags = 1
data = length 288, hash 9E2EBFF7
sample 28:
time = 2076000
flags = 1
data = length 336, hash 36A7D455
sample 29:
time = 2100000
flags = 1
data = length 336, hash 84545F8C
sample 30:
time = 2124000
flags = 1
data = length 336, hash F66F3045
sample 31:
time = 2148000
flags = 1
data = length 576, hash 5AB089EA
sample 32:
time = 2172000
flags = 1
data = length 336, hash 8868086
sample 33:
time = 2196000
flags = 1
data = length 336, hash D5EB6D63
sample 34:
time = 2220000
flags = 1
data = length 288, hash 7A5374B7
sample 35:
time = 2244000
flags = 1
data = length 336, hash BEB27A75
sample 36:
time = 2268000
flags = 1
data = length 336, hash E251E0FD
sample 37:
time = 2292000
flags = 1
data = length 288, hash D54C970
sample 38:
time = 2316000
flags = 1
data = length 336, hash 52C473B9
sample 39:
time = 2340000
flags = 1
data = length 336, hash F5F13334
sample 40:
time = 2364000
flags = 1
data = length 480, hash A5F1E987
sample 41:
time = 2388000
flags = 1
data = length 288, hash 453A1267
sample 42:
time = 2412000
flags = 1
data = length 288, hash 7C6C2EA9
sample 43:
time = 2436000
flags = 1
data = length 336, hash F4BFECA4
sample 44:
time = 2460000
flags = 1
data = length 336, hash 751A395A
sample 45:
time = 2484000
flags = 1
data = length 336, hash EE38DB02
sample 46:
time = 2508000
flags = 1
data = length 336, hash F18837E2
sample 47:
time = 2532000
flags = 1
data = length 336, hash ED36B78E
sample 48:
time = 2556000
flags = 1
data = length 336, hash B3D28289
sample 49:
time = 2580000
flags = 1
data = length 288, hash 8BDE28E1
sample 50:
time = 2604000
flags = 1
data = length 336, hash CFD5E966
sample 51:
time = 2628000
flags = 1
data = length 288, hash DC08E267
sample 52:
time = 2652000
flags = 1
data = length 336, hash 6530CB78
sample 53:
time = 2676000
flags = 1
data = length 336, hash 6CC6636E
sample 54:
time = 2700000
flags = 1
data = length 336, hash 613047C1
sample 55:
time = 2724000
flags = 1
data = length 288, hash CDC747BF
sample 56:
time = 2748000
flags = 1
data = length 336, hash AF22AA74
sample 57:
time = 2772000
flags = 1
data = length 384, hash 82F326AA
sample 58:
time = 2796000
flags = 1
data = length 384, hash EDA26C4D
sample 59:
time = 2820000
flags = 1
data = length 336, hash 94C643DC
sample 60:
time = 2844000
flags = 1
data = length 288, hash CB5D9C40
sample 61:
time = 2868000
flags = 1
data = length 336, hash 1E69DE3F
sample 62:
time = 2892000
flags = 1
data = length 336, hash 7E472219
sample 63:
time = 2916000
flags = 1
data = length 336, hash DA47B9FA
sample 64:
time = 2940000
flags = 1
data = length 336, hash DD0ABB7C
sample 65:
time = 2964000
flags = 1
data = length 288, hash DBF93FAC
sample 66:
time = 2988000
flags = 1
data = length 336, hash 243F4B2
sample 67:
time = 3012000
flags = 1
data = length 336, hash 2E881490
sample 68:
time = 3036000
flags = 1
data = length 288, hash 1C28C8BE
sample 69:
time = 3060000
flags = 1
data = length 336, hash C73E5D30
sample 70:
time = 3084000
flags = 1
data = length 288, hash 98B5BFF6
sample 71:
time = 3108000
flags = 1
data = length 336, hash E0135533
sample 72:
time = 3132000
flags = 1
data = length 336, hash D13C9DBC
sample 73:
time = 3156000
flags = 1
data = length 336, hash 63D524CA
sample 74:
time = 3180000
flags = 1
data = length 288, hash A28514C3
sample 75:
time = 3204000
flags = 1
data = length 336, hash 72B647FF
sample 76:
time = 3228000
flags = 1
data = length 336, hash 8F740AB1
sample 77:
time = 3252000
flags = 1
data = length 336, hash 5E3C7E93
sample 78:
time = 3276000
flags = 1
data = length 336, hash 121B913B
sample 79:
time = 3300000
flags = 1
data = length 336, hash 578FCCF2
sample 80:
time = 3324000
flags = 1
data = length 336, hash 5B5823DE
sample 81:
time = 3348000
flags = 1
data = length 384, hash D8B83F78
sample 82:
time = 3372000
flags = 1
data = length 240, hash E649682F
sample 83:
time = 3396000
flags = 1
data = length 96, hash C559A6F4
sample 84:
time = 3420000
flags = 1
data = length 96, hash 792796BC
sample 85:
time = 3444000
flags = 1
data = length 120, hash 8172CD0E
sample 86:
time = 3468000
flags = 1
data = length 120, hash F562B52F
sample 87:
time = 3492000
flags = 1
data = length 96, hash FF8D5B98
tracksEnded = true

View file

@ -1,487 +0,0 @@
seekMap:
isSeekable = true
duration = 2808000
getPosition(0) = [[timeUs=0, position=141]]
getPosition(1) = [[timeUs=0, position=141], [timeUs=1404000, position=10413]]
getPosition(1404000) = [[timeUs=1404000, position=10413]]
getPosition(2808000) = [[timeUs=1404000, position=10413]]
numberOfTracks = 1
track 0:
total output bytes = 38160
sample count = 117
format 0:
averageBitrate = 32000
sampleMimeType = audio/mpeg
maxInputSize = 4096
channelCount = 2
sampleRate = 48000
metadata = entries=[TSSE: description=null: values=[Lavf58.29.100]]
sample 0:
time = 0
flags = 1
data = length 96, hash 1F161542
sample 1:
time = 24000
flags = 1
data = length 768, hash CD1DC50F
sample 2:
time = 48000
flags = 1
data = length 336, hash 3F64124B
sample 3:
time = 72000
flags = 1
data = length 336, hash 8FFED94E
sample 4:
time = 96000
flags = 1
data = length 288, hash 9CD77D47
sample 5:
time = 120000
flags = 1
data = length 384, hash 24607BB5
sample 6:
time = 144000
flags = 1
data = length 480, hash 4937EBAB
sample 7:
time = 168000
flags = 1
data = length 336, hash 546342B1
sample 8:
time = 192000
flags = 1
data = length 336, hash 79E0923F
sample 9:
time = 216000
flags = 1
data = length 336, hash AB1F3948
sample 10:
time = 240000
flags = 1
data = length 336, hash C3A4D888
sample 11:
time = 264000
flags = 1
data = length 288, hash 7867DA45
sample 12:
time = 288000
flags = 1
data = length 336, hash B1240B73
sample 13:
time = 312000
flags = 1
data = length 336, hash 94CFCD35
sample 14:
time = 336000
flags = 1
data = length 288, hash 94F412C
sample 15:
time = 360000
flags = 1
data = length 336, hash A1D9FF41
sample 16:
time = 384000
flags = 1
data = length 288, hash 2A8DA21B
sample 17:
time = 408000
flags = 1
data = length 336, hash 6A429CE
sample 18:
time = 432000
flags = 1
data = length 336, hash 68853982
sample 19:
time = 456000
flags = 1
data = length 384, hash 1D6F779C
sample 20:
time = 480000
flags = 1
data = length 480, hash 6B31EBEE
sample 21:
time = 504000
flags = 1
data = length 336, hash 888335BE
sample 22:
time = 528000
flags = 1
data = length 336, hash 6072AC8B
sample 23:
time = 552000
flags = 1
data = length 336, hash C9D24234
sample 24:
time = 576000
flags = 1
data = length 288, hash 52BF4D1E
sample 25:
time = 600000
flags = 1
data = length 336, hash F93F4F0
sample 26:
time = 624000
flags = 1
data = length 336, hash 8617688A
sample 27:
time = 648000
flags = 1
data = length 480, hash FAB0D31B
sample 28:
time = 672000
flags = 1
data = length 384, hash FA4B53E2
sample 29:
time = 696000
flags = 1
data = length 336, hash 8C435F6A
sample 30:
time = 720000
flags = 1
data = length 336, hash 60D3F80C
sample 31:
time = 744000
flags = 1
data = length 336, hash DC15B68B
sample 32:
time = 768000
flags = 1
data = length 288, hash FF3DF141
sample 33:
time = 792000
flags = 1
data = length 336, hash A64B3042
sample 34:
time = 816000
flags = 1
data = length 336, hash ACA622A1
sample 35:
time = 840000
flags = 1
data = length 288, hash 3E34B8D4
sample 36:
time = 864000
flags = 1
data = length 288, hash 9B96F72A
sample 37:
time = 888000
flags = 1
data = length 336, hash E917C122
sample 38:
time = 912000
flags = 1
data = length 336, hash 10ED1470
sample 39:
time = 936000
flags = 1
data = length 288, hash 706B8A7C
sample 40:
time = 960000
flags = 1
data = length 336, hash 71FFE4A0
sample 41:
time = 984000
flags = 1
data = length 336, hash D4160463
sample 42:
time = 1008000
flags = 1
data = length 336, hash EC557B14
sample 43:
time = 1032000
flags = 1
data = length 288, hash 5598CF8B
sample 44:
time = 1056000
flags = 1
data = length 336, hash 7E0AB41
sample 45:
time = 1080000
flags = 1
data = length 336, hash 1C585FEF
sample 46:
time = 1104000
flags = 1
data = length 336, hash A4A4855E
sample 47:
time = 1128000
flags = 1
data = length 336, hash CECA51D3
sample 48:
time = 1152000
flags = 1
data = length 288, hash 2D362DC5
sample 49:
time = 1176000
flags = 1
data = length 336, hash 9EB2609D
sample 50:
time = 1200000
flags = 1
data = length 336, hash 28FFB3FE
sample 51:
time = 1224000
flags = 1
data = length 288, hash 2AA2D216
sample 52:
time = 1248000
flags = 1
data = length 336, hash CDBC7032
sample 53:
time = 1272000
flags = 1
data = length 336, hash 25B13FE7
sample 54:
time = 1296000
flags = 1
data = length 336, hash DB6BB1E
sample 55:
time = 1320000
flags = 1
data = length 336, hash EBE951F4
sample 56:
time = 1344000
flags = 1
data = length 288, hash 9E2EBFF7
sample 57:
time = 1368000
flags = 1
data = length 336, hash 36A7D455
sample 58:
time = 1392000
flags = 1
data = length 336, hash 84545F8C
sample 59:
time = 1416000
flags = 1
data = length 336, hash F66F3045
sample 60:
time = 1440000
flags = 1
data = length 576, hash 5AB089EA
sample 61:
time = 1464000
flags = 1
data = length 336, hash 8868086
sample 62:
time = 1488000
flags = 1
data = length 336, hash D5EB6D63
sample 63:
time = 1512000
flags = 1
data = length 288, hash 7A5374B7
sample 64:
time = 1536000
flags = 1
data = length 336, hash BEB27A75
sample 65:
time = 1560000
flags = 1
data = length 336, hash E251E0FD
sample 66:
time = 1584000
flags = 1
data = length 288, hash D54C970
sample 67:
time = 1608000
flags = 1
data = length 336, hash 52C473B9
sample 68:
time = 1632000
flags = 1
data = length 336, hash F5F13334
sample 69:
time = 1656000
flags = 1
data = length 480, hash A5F1E987
sample 70:
time = 1680000
flags = 1
data = length 288, hash 453A1267
sample 71:
time = 1704000
flags = 1
data = length 288, hash 7C6C2EA9
sample 72:
time = 1728000
flags = 1
data = length 336, hash F4BFECA4
sample 73:
time = 1752000
flags = 1
data = length 336, hash 751A395A
sample 74:
time = 1776000
flags = 1
data = length 336, hash EE38DB02
sample 75:
time = 1800000
flags = 1
data = length 336, hash F18837E2
sample 76:
time = 1824000
flags = 1
data = length 336, hash ED36B78E
sample 77:
time = 1848000
flags = 1
data = length 336, hash B3D28289
sample 78:
time = 1872000
flags = 1
data = length 288, hash 8BDE28E1
sample 79:
time = 1896000
flags = 1
data = length 336, hash CFD5E966
sample 80:
time = 1920000
flags = 1
data = length 288, hash DC08E267
sample 81:
time = 1944000
flags = 1
data = length 336, hash 6530CB78
sample 82:
time = 1968000
flags = 1
data = length 336, hash 6CC6636E
sample 83:
time = 1992000
flags = 1
data = length 336, hash 613047C1
sample 84:
time = 2016000
flags = 1
data = length 288, hash CDC747BF
sample 85:
time = 2040000
flags = 1
data = length 336, hash AF22AA74
sample 86:
time = 2064000
flags = 1
data = length 384, hash 82F326AA
sample 87:
time = 2088000
flags = 1
data = length 384, hash EDA26C4D
sample 88:
time = 2112000
flags = 1
data = length 336, hash 94C643DC
sample 89:
time = 2136000
flags = 1
data = length 288, hash CB5D9C40
sample 90:
time = 2160000
flags = 1
data = length 336, hash 1E69DE3F
sample 91:
time = 2184000
flags = 1
data = length 336, hash 7E472219
sample 92:
time = 2208000
flags = 1
data = length 336, hash DA47B9FA
sample 93:
time = 2232000
flags = 1
data = length 336, hash DD0ABB7C
sample 94:
time = 2256000
flags = 1
data = length 288, hash DBF93FAC
sample 95:
time = 2280000
flags = 1
data = length 336, hash 243F4B2
sample 96:
time = 2304000
flags = 1
data = length 336, hash 2E881490
sample 97:
time = 2328000
flags = 1
data = length 288, hash 1C28C8BE
sample 98:
time = 2352000
flags = 1
data = length 336, hash C73E5D30
sample 99:
time = 2376000
flags = 1
data = length 288, hash 98B5BFF6
sample 100:
time = 2400000
flags = 1
data = length 336, hash E0135533
sample 101:
time = 2424000
flags = 1
data = length 336, hash D13C9DBC
sample 102:
time = 2448000
flags = 1
data = length 336, hash 63D524CA
sample 103:
time = 2472000
flags = 1
data = length 288, hash A28514C3
sample 104:
time = 2496000
flags = 1
data = length 336, hash 72B647FF
sample 105:
time = 2520000
flags = 1
data = length 336, hash 8F740AB1
sample 106:
time = 2544000
flags = 1
data = length 336, hash 5E3C7E93
sample 107:
time = 2568000
flags = 1
data = length 336, hash 121B913B
sample 108:
time = 2592000
flags = 1
data = length 336, hash 578FCCF2
sample 109:
time = 2616000
flags = 1
data = length 336, hash 5B5823DE
sample 110:
time = 2640000
flags = 1
data = length 384, hash D8B83F78
sample 111:
time = 2664000
flags = 1
data = length 240, hash E649682F
sample 112:
time = 2688000
flags = 1
data = length 96, hash C559A6F4
sample 113:
time = 2712000
flags = 1
data = length 96, hash 792796BC
sample 114:
time = 2736000
flags = 1
data = length 120, hash 8172CD0E
sample 115:
time = 2760000
flags = 1
data = length 120, hash F562B52F
sample 116:
time = 2784000
flags = 1
data = length 96, hash FF8D5B98
tracksEnded = true

View file

@ -1,487 +0,0 @@
seekMap:
isSeekable = true
duration = 2808000
getPosition(0) = [[timeUs=0, position=141]]
getPosition(1) = [[timeUs=0, position=141], [timeUs=702000, position=10413]]
getPosition(1404000) = [[timeUs=1404000, position=19773]]
getPosition(2808000) = [[timeUs=2106000, position=29613]]
numberOfTracks = 1
track 0:
total output bytes = 38160
sample count = 117
format 0:
averageBitrate = 32000
sampleMimeType = audio/mpeg
maxInputSize = 4096
channelCount = 2
sampleRate = 48000
metadata = entries=[TSSE: description=null: values=[Lavf58.29.100]]
sample 0:
time = 0
flags = 1
data = length 96, hash 1F161542
sample 1:
time = 24000
flags = 1
data = length 768, hash CD1DC50F
sample 2:
time = 48000
flags = 1
data = length 336, hash 3F64124B
sample 3:
time = 72000
flags = 1
data = length 336, hash 8FFED94E
sample 4:
time = 96000
flags = 1
data = length 288, hash 9CD77D47
sample 5:
time = 120000
flags = 1
data = length 384, hash 24607BB5
sample 6:
time = 144000
flags = 1
data = length 480, hash 4937EBAB
sample 7:
time = 168000
flags = 1
data = length 336, hash 546342B1
sample 8:
time = 192000
flags = 1
data = length 336, hash 79E0923F
sample 9:
time = 216000
flags = 1
data = length 336, hash AB1F3948
sample 10:
time = 240000
flags = 1
data = length 336, hash C3A4D888
sample 11:
time = 264000
flags = 1
data = length 288, hash 7867DA45
sample 12:
time = 288000
flags = 1
data = length 336, hash B1240B73
sample 13:
time = 312000
flags = 1
data = length 336, hash 94CFCD35
sample 14:
time = 336000
flags = 1
data = length 288, hash 94F412C
sample 15:
time = 360000
flags = 1
data = length 336, hash A1D9FF41
sample 16:
time = 384000
flags = 1
data = length 288, hash 2A8DA21B
sample 17:
time = 408000
flags = 1
data = length 336, hash 6A429CE
sample 18:
time = 432000
flags = 1
data = length 336, hash 68853982
sample 19:
time = 456000
flags = 1
data = length 384, hash 1D6F779C
sample 20:
time = 480000
flags = 1
data = length 480, hash 6B31EBEE
sample 21:
time = 504000
flags = 1
data = length 336, hash 888335BE
sample 22:
time = 528000
flags = 1
data = length 336, hash 6072AC8B
sample 23:
time = 552000
flags = 1
data = length 336, hash C9D24234
sample 24:
time = 576000
flags = 1
data = length 288, hash 52BF4D1E
sample 25:
time = 600000
flags = 1
data = length 336, hash F93F4F0
sample 26:
time = 624000
flags = 1
data = length 336, hash 8617688A
sample 27:
time = 648000
flags = 1
data = length 480, hash FAB0D31B
sample 28:
time = 672000
flags = 1
data = length 384, hash FA4B53E2
sample 29:
time = 696000
flags = 1
data = length 336, hash 8C435F6A
sample 30:
time = 720000
flags = 1
data = length 336, hash 60D3F80C
sample 31:
time = 744000
flags = 1
data = length 336, hash DC15B68B
sample 32:
time = 768000
flags = 1
data = length 288, hash FF3DF141
sample 33:
time = 792000
flags = 1
data = length 336, hash A64B3042
sample 34:
time = 816000
flags = 1
data = length 336, hash ACA622A1
sample 35:
time = 840000
flags = 1
data = length 288, hash 3E34B8D4
sample 36:
time = 864000
flags = 1
data = length 288, hash 9B96F72A
sample 37:
time = 888000
flags = 1
data = length 336, hash E917C122
sample 38:
time = 912000
flags = 1
data = length 336, hash 10ED1470
sample 39:
time = 936000
flags = 1
data = length 288, hash 706B8A7C
sample 40:
time = 960000
flags = 1
data = length 336, hash 71FFE4A0
sample 41:
time = 984000
flags = 1
data = length 336, hash D4160463
sample 42:
time = 1008000
flags = 1
data = length 336, hash EC557B14
sample 43:
time = 1032000
flags = 1
data = length 288, hash 5598CF8B
sample 44:
time = 1056000
flags = 1
data = length 336, hash 7E0AB41
sample 45:
time = 1080000
flags = 1
data = length 336, hash 1C585FEF
sample 46:
time = 1104000
flags = 1
data = length 336, hash A4A4855E
sample 47:
time = 1128000
flags = 1
data = length 336, hash CECA51D3
sample 48:
time = 1152000
flags = 1
data = length 288, hash 2D362DC5
sample 49:
time = 1176000
flags = 1
data = length 336, hash 9EB2609D
sample 50:
time = 1200000
flags = 1
data = length 336, hash 28FFB3FE
sample 51:
time = 1224000
flags = 1
data = length 288, hash 2AA2D216
sample 52:
time = 1248000
flags = 1
data = length 336, hash CDBC7032
sample 53:
time = 1272000
flags = 1
data = length 336, hash 25B13FE7
sample 54:
time = 1296000
flags = 1
data = length 336, hash DB6BB1E
sample 55:
time = 1320000
flags = 1
data = length 336, hash EBE951F4
sample 56:
time = 1344000
flags = 1
data = length 288, hash 9E2EBFF7
sample 57:
time = 1368000
flags = 1
data = length 336, hash 36A7D455
sample 58:
time = 1392000
flags = 1
data = length 336, hash 84545F8C
sample 59:
time = 1416000
flags = 1
data = length 336, hash F66F3045
sample 60:
time = 1440000
flags = 1
data = length 576, hash 5AB089EA
sample 61:
time = 1464000
flags = 1
data = length 336, hash 8868086
sample 62:
time = 1488000
flags = 1
data = length 336, hash D5EB6D63
sample 63:
time = 1512000
flags = 1
data = length 288, hash 7A5374B7
sample 64:
time = 1536000
flags = 1
data = length 336, hash BEB27A75
sample 65:
time = 1560000
flags = 1
data = length 336, hash E251E0FD
sample 66:
time = 1584000
flags = 1
data = length 288, hash D54C970
sample 67:
time = 1608000
flags = 1
data = length 336, hash 52C473B9
sample 68:
time = 1632000
flags = 1
data = length 336, hash F5F13334
sample 69:
time = 1656000
flags = 1
data = length 480, hash A5F1E987
sample 70:
time = 1680000
flags = 1
data = length 288, hash 453A1267
sample 71:
time = 1704000
flags = 1
data = length 288, hash 7C6C2EA9
sample 72:
time = 1728000
flags = 1
data = length 336, hash F4BFECA4
sample 73:
time = 1752000
flags = 1
data = length 336, hash 751A395A
sample 74:
time = 1776000
flags = 1
data = length 336, hash EE38DB02
sample 75:
time = 1800000
flags = 1
data = length 336, hash F18837E2
sample 76:
time = 1824000
flags = 1
data = length 336, hash ED36B78E
sample 77:
time = 1848000
flags = 1
data = length 336, hash B3D28289
sample 78:
time = 1872000
flags = 1
data = length 288, hash 8BDE28E1
sample 79:
time = 1896000
flags = 1
data = length 336, hash CFD5E966
sample 80:
time = 1920000
flags = 1
data = length 288, hash DC08E267
sample 81:
time = 1944000
flags = 1
data = length 336, hash 6530CB78
sample 82:
time = 1968000
flags = 1
data = length 336, hash 6CC6636E
sample 83:
time = 1992000
flags = 1
data = length 336, hash 613047C1
sample 84:
time = 2016000
flags = 1
data = length 288, hash CDC747BF
sample 85:
time = 2040000
flags = 1
data = length 336, hash AF22AA74
sample 86:
time = 2064000
flags = 1
data = length 384, hash 82F326AA
sample 87:
time = 2088000
flags = 1
data = length 384, hash EDA26C4D
sample 88:
time = 2112000
flags = 1
data = length 336, hash 94C643DC
sample 89:
time = 2136000
flags = 1
data = length 288, hash CB5D9C40
sample 90:
time = 2160000
flags = 1
data = length 336, hash 1E69DE3F
sample 91:
time = 2184000
flags = 1
data = length 336, hash 7E472219
sample 92:
time = 2208000
flags = 1
data = length 336, hash DA47B9FA
sample 93:
time = 2232000
flags = 1
data = length 336, hash DD0ABB7C
sample 94:
time = 2256000
flags = 1
data = length 288, hash DBF93FAC
sample 95:
time = 2280000
flags = 1
data = length 336, hash 243F4B2
sample 96:
time = 2304000
flags = 1
data = length 336, hash 2E881490
sample 97:
time = 2328000
flags = 1
data = length 288, hash 1C28C8BE
sample 98:
time = 2352000
flags = 1
data = length 336, hash C73E5D30
sample 99:
time = 2376000
flags = 1
data = length 288, hash 98B5BFF6
sample 100:
time = 2400000
flags = 1
data = length 336, hash E0135533
sample 101:
time = 2424000
flags = 1
data = length 336, hash D13C9DBC
sample 102:
time = 2448000
flags = 1
data = length 336, hash 63D524CA
sample 103:
time = 2472000
flags = 1
data = length 288, hash A28514C3
sample 104:
time = 2496000
flags = 1
data = length 336, hash 72B647FF
sample 105:
time = 2520000
flags = 1
data = length 336, hash 8F740AB1
sample 106:
time = 2544000
flags = 1
data = length 336, hash 5E3C7E93
sample 107:
time = 2568000
flags = 1
data = length 336, hash 121B913B
sample 108:
time = 2592000
flags = 1
data = length 336, hash 578FCCF2
sample 109:
time = 2616000
flags = 1
data = length 336, hash 5B5823DE
sample 110:
time = 2640000
flags = 1
data = length 384, hash D8B83F78
sample 111:
time = 2664000
flags = 1
data = length 240, hash E649682F
sample 112:
time = 2688000
flags = 1
data = length 96, hash C559A6F4
sample 113:
time = 2712000
flags = 1
data = length 96, hash 792796BC
sample 114:
time = 2736000
flags = 1
data = length 120, hash 8172CD0E
sample 115:
time = 2760000
flags = 1
data = length 120, hash F562B52F
sample 116:
time = 2784000
flags = 1
data = length 96, hash FF8D5B98
tracksEnded = true

View file

@ -1,371 +0,0 @@
seekMap:
isSeekable = true
duration = 2808000
getPosition(0) = [[timeUs=0, position=141]]
getPosition(1) = [[timeUs=0, position=141], [timeUs=702000, position=10413]]
getPosition(1404000) = [[timeUs=1404000, position=19773]]
getPosition(2808000) = [[timeUs=2106000, position=29613]]
numberOfTracks = 1
track 0:
total output bytes = 27888
sample count = 88
format 0:
averageBitrate = 32000
sampleMimeType = audio/mpeg
maxInputSize = 4096
channelCount = 2
sampleRate = 48000
metadata = entries=[TSSE: description=null: values=[Lavf58.29.100]]
sample 0:
time = 702000
flags = 1
data = length 336, hash 8C435F6A
sample 1:
time = 726000
flags = 1
data = length 336, hash 60D3F80C
sample 2:
time = 750000
flags = 1
data = length 336, hash DC15B68B
sample 3:
time = 774000
flags = 1
data = length 288, hash FF3DF141
sample 4:
time = 798000
flags = 1
data = length 336, hash A64B3042
sample 5:
time = 822000
flags = 1
data = length 336, hash ACA622A1
sample 6:
time = 846000
flags = 1
data = length 288, hash 3E34B8D4
sample 7:
time = 870000
flags = 1
data = length 288, hash 9B96F72A
sample 8:
time = 894000
flags = 1
data = length 336, hash E917C122
sample 9:
time = 918000
flags = 1
data = length 336, hash 10ED1470
sample 10:
time = 942000
flags = 1
data = length 288, hash 706B8A7C
sample 11:
time = 966000
flags = 1
data = length 336, hash 71FFE4A0
sample 12:
time = 990000
flags = 1
data = length 336, hash D4160463
sample 13:
time = 1014000
flags = 1
data = length 336, hash EC557B14
sample 14:
time = 1038000
flags = 1
data = length 288, hash 5598CF8B
sample 15:
time = 1062000
flags = 1
data = length 336, hash 7E0AB41
sample 16:
time = 1086000
flags = 1
data = length 336, hash 1C585FEF
sample 17:
time = 1110000
flags = 1
data = length 336, hash A4A4855E
sample 18:
time = 1134000
flags = 1
data = length 336, hash CECA51D3
sample 19:
time = 1158000
flags = 1
data = length 288, hash 2D362DC5
sample 20:
time = 1182000
flags = 1
data = length 336, hash 9EB2609D
sample 21:
time = 1206000
flags = 1
data = length 336, hash 28FFB3FE
sample 22:
time = 1230000
flags = 1
data = length 288, hash 2AA2D216
sample 23:
time = 1254000
flags = 1
data = length 336, hash CDBC7032
sample 24:
time = 1278000
flags = 1
data = length 336, hash 25B13FE7
sample 25:
time = 1302000
flags = 1
data = length 336, hash DB6BB1E
sample 26:
time = 1326000
flags = 1
data = length 336, hash EBE951F4
sample 27:
time = 1350000
flags = 1
data = length 288, hash 9E2EBFF7
sample 28:
time = 1374000
flags = 1
data = length 336, hash 36A7D455
sample 29:
time = 1398000
flags = 1
data = length 336, hash 84545F8C
sample 30:
time = 1422000
flags = 1
data = length 336, hash F66F3045
sample 31:
time = 1446000
flags = 1
data = length 576, hash 5AB089EA
sample 32:
time = 1470000
flags = 1
data = length 336, hash 8868086
sample 33:
time = 1494000
flags = 1
data = length 336, hash D5EB6D63
sample 34:
time = 1518000
flags = 1
data = length 288, hash 7A5374B7
sample 35:
time = 1542000
flags = 1
data = length 336, hash BEB27A75
sample 36:
time = 1566000
flags = 1
data = length 336, hash E251E0FD
sample 37:
time = 1590000
flags = 1
data = length 288, hash D54C970
sample 38:
time = 1614000
flags = 1
data = length 336, hash 52C473B9
sample 39:
time = 1638000
flags = 1
data = length 336, hash F5F13334
sample 40:
time = 1662000
flags = 1
data = length 480, hash A5F1E987
sample 41:
time = 1686000
flags = 1
data = length 288, hash 453A1267
sample 42:
time = 1710000
flags = 1
data = length 288, hash 7C6C2EA9
sample 43:
time = 1734000
flags = 1
data = length 336, hash F4BFECA4
sample 44:
time = 1758000
flags = 1
data = length 336, hash 751A395A
sample 45:
time = 1782000
flags = 1
data = length 336, hash EE38DB02
sample 46:
time = 1806000
flags = 1
data = length 336, hash F18837E2
sample 47:
time = 1830000
flags = 1
data = length 336, hash ED36B78E
sample 48:
time = 1854000
flags = 1
data = length 336, hash B3D28289
sample 49:
time = 1878000
flags = 1
data = length 288, hash 8BDE28E1
sample 50:
time = 1902000
flags = 1
data = length 336, hash CFD5E966
sample 51:
time = 1926000
flags = 1
data = length 288, hash DC08E267
sample 52:
time = 1950000
flags = 1
data = length 336, hash 6530CB78
sample 53:
time = 1974000
flags = 1
data = length 336, hash 6CC6636E
sample 54:
time = 1998000
flags = 1
data = length 336, hash 613047C1
sample 55:
time = 2022000
flags = 1
data = length 288, hash CDC747BF
sample 56:
time = 2046000
flags = 1
data = length 336, hash AF22AA74
sample 57:
time = 2070000
flags = 1
data = length 384, hash 82F326AA
sample 58:
time = 2094000
flags = 1
data = length 384, hash EDA26C4D
sample 59:
time = 2118000
flags = 1
data = length 336, hash 94C643DC
sample 60:
time = 2142000
flags = 1
data = length 288, hash CB5D9C40
sample 61:
time = 2166000
flags = 1
data = length 336, hash 1E69DE3F
sample 62:
time = 2190000
flags = 1
data = length 336, hash 7E472219
sample 63:
time = 2214000
flags = 1
data = length 336, hash DA47B9FA
sample 64:
time = 2238000
flags = 1
data = length 336, hash DD0ABB7C
sample 65:
time = 2262000
flags = 1
data = length 288, hash DBF93FAC
sample 66:
time = 2286000
flags = 1
data = length 336, hash 243F4B2
sample 67:
time = 2310000
flags = 1
data = length 336, hash 2E881490
sample 68:
time = 2334000
flags = 1
data = length 288, hash 1C28C8BE
sample 69:
time = 2358000
flags = 1
data = length 336, hash C73E5D30
sample 70:
time = 2382000
flags = 1
data = length 288, hash 98B5BFF6
sample 71:
time = 2406000
flags = 1
data = length 336, hash E0135533
sample 72:
time = 2430000
flags = 1
data = length 336, hash D13C9DBC
sample 73:
time = 2454000
flags = 1
data = length 336, hash 63D524CA
sample 74:
time = 2478000
flags = 1
data = length 288, hash A28514C3
sample 75:
time = 2502000
flags = 1
data = length 336, hash 72B647FF
sample 76:
time = 2526000
flags = 1
data = length 336, hash 8F740AB1
sample 77:
time = 2550000
flags = 1
data = length 336, hash 5E3C7E93
sample 78:
time = 2574000
flags = 1
data = length 336, hash 121B913B
sample 79:
time = 2598000
flags = 1
data = length 336, hash 578FCCF2
sample 80:
time = 2622000
flags = 1
data = length 336, hash 5B5823DE
sample 81:
time = 2646000
flags = 1
data = length 384, hash D8B83F78
sample 82:
time = 2670000
flags = 1
data = length 240, hash E649682F
sample 83:
time = 2694000
flags = 1
data = length 96, hash C559A6F4
sample 84:
time = 2718000
flags = 1
data = length 96, hash 792796BC
sample 85:
time = 2742000
flags = 1
data = length 120, hash 8172CD0E
sample 86:
time = 2766000
flags = 1
data = length 120, hash F562B52F
sample 87:
time = 2790000
flags = 1
data = length 96, hash FF8D5B98
tracksEnded = true

View file

@ -1,255 +0,0 @@
seekMap:
isSeekable = true
duration = 2808000
getPosition(0) = [[timeUs=0, position=141]]
getPosition(1) = [[timeUs=0, position=141], [timeUs=702000, position=10413]]
getPosition(1404000) = [[timeUs=1404000, position=19773]]
getPosition(2808000) = [[timeUs=2106000, position=29613]]
numberOfTracks = 1
track 0:
total output bytes = 18528
sample count = 59
format 0:
averageBitrate = 32000
sampleMimeType = audio/mpeg
maxInputSize = 4096
channelCount = 2
sampleRate = 48000
metadata = entries=[TSSE: description=null: values=[Lavf58.29.100]]
sample 0:
time = 1404000
flags = 1
data = length 336, hash 84545F8C
sample 1:
time = 1428000
flags = 1
data = length 336, hash F66F3045
sample 2:
time = 1452000
flags = 1
data = length 576, hash 5AB089EA
sample 3:
time = 1476000
flags = 1
data = length 336, hash 8868086
sample 4:
time = 1500000
flags = 1
data = length 336, hash D5EB6D63
sample 5:
time = 1524000
flags = 1
data = length 288, hash 7A5374B7
sample 6:
time = 1548000
flags = 1
data = length 336, hash BEB27A75
sample 7:
time = 1572000
flags = 1
data = length 336, hash E251E0FD
sample 8:
time = 1596000
flags = 1
data = length 288, hash D54C970
sample 9:
time = 1620000
flags = 1
data = length 336, hash 52C473B9
sample 10:
time = 1644000
flags = 1
data = length 336, hash F5F13334
sample 11:
time = 1668000
flags = 1
data = length 480, hash A5F1E987
sample 12:
time = 1692000
flags = 1
data = length 288, hash 453A1267
sample 13:
time = 1716000
flags = 1
data = length 288, hash 7C6C2EA9
sample 14:
time = 1740000
flags = 1
data = length 336, hash F4BFECA4
sample 15:
time = 1764000
flags = 1
data = length 336, hash 751A395A
sample 16:
time = 1788000
flags = 1
data = length 336, hash EE38DB02
sample 17:
time = 1812000
flags = 1
data = length 336, hash F18837E2
sample 18:
time = 1836000
flags = 1
data = length 336, hash ED36B78E
sample 19:
time = 1860000
flags = 1
data = length 336, hash B3D28289
sample 20:
time = 1884000
flags = 1
data = length 288, hash 8BDE28E1
sample 21:
time = 1908000
flags = 1
data = length 336, hash CFD5E966
sample 22:
time = 1932000
flags = 1
data = length 288, hash DC08E267
sample 23:
time = 1956000
flags = 1
data = length 336, hash 6530CB78
sample 24:
time = 1980000
flags = 1
data = length 336, hash 6CC6636E
sample 25:
time = 2004000
flags = 1
data = length 336, hash 613047C1
sample 26:
time = 2028000
flags = 1
data = length 288, hash CDC747BF
sample 27:
time = 2052000
flags = 1
data = length 336, hash AF22AA74
sample 28:
time = 2076000
flags = 1
data = length 384, hash 82F326AA
sample 29:
time = 2100000
flags = 1
data = length 384, hash EDA26C4D
sample 30:
time = 2124000
flags = 1
data = length 336, hash 94C643DC
sample 31:
time = 2148000
flags = 1
data = length 288, hash CB5D9C40
sample 32:
time = 2172000
flags = 1
data = length 336, hash 1E69DE3F
sample 33:
time = 2196000
flags = 1
data = length 336, hash 7E472219
sample 34:
time = 2220000
flags = 1
data = length 336, hash DA47B9FA
sample 35:
time = 2244000
flags = 1
data = length 336, hash DD0ABB7C
sample 36:
time = 2268000
flags = 1
data = length 288, hash DBF93FAC
sample 37:
time = 2292000
flags = 1
data = length 336, hash 243F4B2
sample 38:
time = 2316000
flags = 1
data = length 336, hash 2E881490
sample 39:
time = 2340000
flags = 1
data = length 288, hash 1C28C8BE
sample 40:
time = 2364000
flags = 1
data = length 336, hash C73E5D30
sample 41:
time = 2388000
flags = 1
data = length 288, hash 98B5BFF6
sample 42:
time = 2412000
flags = 1
data = length 336, hash E0135533
sample 43:
time = 2436000
flags = 1
data = length 336, hash D13C9DBC
sample 44:
time = 2460000
flags = 1
data = length 336, hash 63D524CA
sample 45:
time = 2484000
flags = 1
data = length 288, hash A28514C3
sample 46:
time = 2508000
flags = 1
data = length 336, hash 72B647FF
sample 47:
time = 2532000
flags = 1
data = length 336, hash 8F740AB1
sample 48:
time = 2556000
flags = 1
data = length 336, hash 5E3C7E93
sample 49:
time = 2580000
flags = 1
data = length 336, hash 121B913B
sample 50:
time = 2604000
flags = 1
data = length 336, hash 578FCCF2
sample 51:
time = 2628000
flags = 1
data = length 336, hash 5B5823DE
sample 52:
time = 2652000
flags = 1
data = length 384, hash D8B83F78
sample 53:
time = 2676000
flags = 1
data = length 240, hash E649682F
sample 54:
time = 2700000
flags = 1
data = length 96, hash C559A6F4
sample 55:
time = 2724000
flags = 1
data = length 96, hash 792796BC
sample 56:
time = 2748000
flags = 1
data = length 120, hash 8172CD0E
sample 57:
time = 2772000
flags = 1
data = length 120, hash F562B52F
sample 58:
time = 2796000
flags = 1
data = length 96, hash FF8D5B98
tracksEnded = true

View file

@ -1,139 +0,0 @@
seekMap:
isSeekable = true
duration = 2808000
getPosition(0) = [[timeUs=0, position=141]]
getPosition(1) = [[timeUs=0, position=141], [timeUs=702000, position=10413]]
getPosition(1404000) = [[timeUs=1404000, position=19773]]
getPosition(2808000) = [[timeUs=2106000, position=29613]]
numberOfTracks = 1
track 0:
total output bytes = 8688
sample count = 30
format 0:
averageBitrate = 32000
sampleMimeType = audio/mpeg
maxInputSize = 4096
channelCount = 2
sampleRate = 48000
metadata = entries=[TSSE: description=null: values=[Lavf58.29.100]]
sample 0:
time = 2106000
flags = 1
data = length 384, hash EDA26C4D
sample 1:
time = 2130000
flags = 1
data = length 336, hash 94C643DC
sample 2:
time = 2154000
flags = 1
data = length 288, hash CB5D9C40
sample 3:
time = 2178000
flags = 1
data = length 336, hash 1E69DE3F
sample 4:
time = 2202000
flags = 1
data = length 336, hash 7E472219
sample 5:
time = 2226000
flags = 1
data = length 336, hash DA47B9FA
sample 6:
time = 2250000
flags = 1
data = length 336, hash DD0ABB7C
sample 7:
time = 2274000
flags = 1
data = length 288, hash DBF93FAC
sample 8:
time = 2298000
flags = 1
data = length 336, hash 243F4B2
sample 9:
time = 2322000
flags = 1
data = length 336, hash 2E881490
sample 10:
time = 2346000
flags = 1
data = length 288, hash 1C28C8BE
sample 11:
time = 2370000
flags = 1
data = length 336, hash C73E5D30
sample 12:
time = 2394000
flags = 1
data = length 288, hash 98B5BFF6
sample 13:
time = 2418000
flags = 1
data = length 336, hash E0135533
sample 14:
time = 2442000
flags = 1
data = length 336, hash D13C9DBC
sample 15:
time = 2466000
flags = 1
data = length 336, hash 63D524CA
sample 16:
time = 2490000
flags = 1
data = length 288, hash A28514C3
sample 17:
time = 2514000
flags = 1
data = length 336, hash 72B647FF
sample 18:
time = 2538000
flags = 1
data = length 336, hash 8F740AB1
sample 19:
time = 2562000
flags = 1
data = length 336, hash 5E3C7E93
sample 20:
time = 2586000
flags = 1
data = length 336, hash 121B913B
sample 21:
time = 2610000
flags = 1
data = length 336, hash 578FCCF2
sample 22:
time = 2634000
flags = 1
data = length 336, hash 5B5823DE
sample 23:
time = 2658000
flags = 1
data = length 384, hash D8B83F78
sample 24:
time = 2682000
flags = 1
data = length 240, hash E649682F
sample 25:
time = 2706000
flags = 1
data = length 96, hash C559A6F4
sample 26:
time = 2730000
flags = 1
data = length 96, hash 792796BC
sample 27:
time = 2754000
flags = 1
data = length 120, hash 8172CD0E
sample 28:
time = 2778000
flags = 1
data = length 120, hash F562B52F
sample 29:
time = 2802000
flags = 1
data = length 96, hash FF8D5B98
tracksEnded = true

View file

@ -1,487 +0,0 @@
seekMap:
isSeekable = true
duration = 2808000
getPosition(0) = [[timeUs=0, position=141]]
getPosition(1) = [[timeUs=0, position=141], [timeUs=702000, position=10413]]
getPosition(1404000) = [[timeUs=1404000, position=19773]]
getPosition(2808000) = [[timeUs=2106000, position=29613]]
numberOfTracks = 1
track 0:
total output bytes = 38160
sample count = 117
format 0:
averageBitrate = 32000
sampleMimeType = audio/mpeg
maxInputSize = 4096
channelCount = 2
sampleRate = 48000
metadata = entries=[TSSE: description=null: values=[Lavf58.29.100]]
sample 0:
time = 0
flags = 1
data = length 96, hash 1F161542
sample 1:
time = 24000
flags = 1
data = length 768, hash CD1DC50F
sample 2:
time = 48000
flags = 1
data = length 336, hash 3F64124B
sample 3:
time = 72000
flags = 1
data = length 336, hash 8FFED94E
sample 4:
time = 96000
flags = 1
data = length 288, hash 9CD77D47
sample 5:
time = 120000
flags = 1
data = length 384, hash 24607BB5
sample 6:
time = 144000
flags = 1
data = length 480, hash 4937EBAB
sample 7:
time = 168000
flags = 1
data = length 336, hash 546342B1
sample 8:
time = 192000
flags = 1
data = length 336, hash 79E0923F
sample 9:
time = 216000
flags = 1
data = length 336, hash AB1F3948
sample 10:
time = 240000
flags = 1
data = length 336, hash C3A4D888
sample 11:
time = 264000
flags = 1
data = length 288, hash 7867DA45
sample 12:
time = 288000
flags = 1
data = length 336, hash B1240B73
sample 13:
time = 312000
flags = 1
data = length 336, hash 94CFCD35
sample 14:
time = 336000
flags = 1
data = length 288, hash 94F412C
sample 15:
time = 360000
flags = 1
data = length 336, hash A1D9FF41
sample 16:
time = 384000
flags = 1
data = length 288, hash 2A8DA21B
sample 17:
time = 408000
flags = 1
data = length 336, hash 6A429CE
sample 18:
time = 432000
flags = 1
data = length 336, hash 68853982
sample 19:
time = 456000
flags = 1
data = length 384, hash 1D6F779C
sample 20:
time = 480000
flags = 1
data = length 480, hash 6B31EBEE
sample 21:
time = 504000
flags = 1
data = length 336, hash 888335BE
sample 22:
time = 528000
flags = 1
data = length 336, hash 6072AC8B
sample 23:
time = 552000
flags = 1
data = length 336, hash C9D24234
sample 24:
time = 576000
flags = 1
data = length 288, hash 52BF4D1E
sample 25:
time = 600000
flags = 1
data = length 336, hash F93F4F0
sample 26:
time = 624000
flags = 1
data = length 336, hash 8617688A
sample 27:
time = 648000
flags = 1
data = length 480, hash FAB0D31B
sample 28:
time = 672000
flags = 1
data = length 384, hash FA4B53E2
sample 29:
time = 696000
flags = 1
data = length 336, hash 8C435F6A
sample 30:
time = 720000
flags = 1
data = length 336, hash 60D3F80C
sample 31:
time = 744000
flags = 1
data = length 336, hash DC15B68B
sample 32:
time = 768000
flags = 1
data = length 288, hash FF3DF141
sample 33:
time = 792000
flags = 1
data = length 336, hash A64B3042
sample 34:
time = 816000
flags = 1
data = length 336, hash ACA622A1
sample 35:
time = 840000
flags = 1
data = length 288, hash 3E34B8D4
sample 36:
time = 864000
flags = 1
data = length 288, hash 9B96F72A
sample 37:
time = 888000
flags = 1
data = length 336, hash E917C122
sample 38:
time = 912000
flags = 1
data = length 336, hash 10ED1470
sample 39:
time = 936000
flags = 1
data = length 288, hash 706B8A7C
sample 40:
time = 960000
flags = 1
data = length 336, hash 71FFE4A0
sample 41:
time = 984000
flags = 1
data = length 336, hash D4160463
sample 42:
time = 1008000
flags = 1
data = length 336, hash EC557B14
sample 43:
time = 1032000
flags = 1
data = length 288, hash 5598CF8B
sample 44:
time = 1056000
flags = 1
data = length 336, hash 7E0AB41
sample 45:
time = 1080000
flags = 1
data = length 336, hash 1C585FEF
sample 46:
time = 1104000
flags = 1
data = length 336, hash A4A4855E
sample 47:
time = 1128000
flags = 1
data = length 336, hash CECA51D3
sample 48:
time = 1152000
flags = 1
data = length 288, hash 2D362DC5
sample 49:
time = 1176000
flags = 1
data = length 336, hash 9EB2609D
sample 50:
time = 1200000
flags = 1
data = length 336, hash 28FFB3FE
sample 51:
time = 1224000
flags = 1
data = length 288, hash 2AA2D216
sample 52:
time = 1248000
flags = 1
data = length 336, hash CDBC7032
sample 53:
time = 1272000
flags = 1
data = length 336, hash 25B13FE7
sample 54:
time = 1296000
flags = 1
data = length 336, hash DB6BB1E
sample 55:
time = 1320000
flags = 1
data = length 336, hash EBE951F4
sample 56:
time = 1344000
flags = 1
data = length 288, hash 9E2EBFF7
sample 57:
time = 1368000
flags = 1
data = length 336, hash 36A7D455
sample 58:
time = 1392000
flags = 1
data = length 336, hash 84545F8C
sample 59:
time = 1416000
flags = 1
data = length 336, hash F66F3045
sample 60:
time = 1440000
flags = 1
data = length 576, hash 5AB089EA
sample 61:
time = 1464000
flags = 1
data = length 336, hash 8868086
sample 62:
time = 1488000
flags = 1
data = length 336, hash D5EB6D63
sample 63:
time = 1512000
flags = 1
data = length 288, hash 7A5374B7
sample 64:
time = 1536000
flags = 1
data = length 336, hash BEB27A75
sample 65:
time = 1560000
flags = 1
data = length 336, hash E251E0FD
sample 66:
time = 1584000
flags = 1
data = length 288, hash D54C970
sample 67:
time = 1608000
flags = 1
data = length 336, hash 52C473B9
sample 68:
time = 1632000
flags = 1
data = length 336, hash F5F13334
sample 69:
time = 1656000
flags = 1
data = length 480, hash A5F1E987
sample 70:
time = 1680000
flags = 1
data = length 288, hash 453A1267
sample 71:
time = 1704000
flags = 1
data = length 288, hash 7C6C2EA9
sample 72:
time = 1728000
flags = 1
data = length 336, hash F4BFECA4
sample 73:
time = 1752000
flags = 1
data = length 336, hash 751A395A
sample 74:
time = 1776000
flags = 1
data = length 336, hash EE38DB02
sample 75:
time = 1800000
flags = 1
data = length 336, hash F18837E2
sample 76:
time = 1824000
flags = 1
data = length 336, hash ED36B78E
sample 77:
time = 1848000
flags = 1
data = length 336, hash B3D28289
sample 78:
time = 1872000
flags = 1
data = length 288, hash 8BDE28E1
sample 79:
time = 1896000
flags = 1
data = length 336, hash CFD5E966
sample 80:
time = 1920000
flags = 1
data = length 288, hash DC08E267
sample 81:
time = 1944000
flags = 1
data = length 336, hash 6530CB78
sample 82:
time = 1968000
flags = 1
data = length 336, hash 6CC6636E
sample 83:
time = 1992000
flags = 1
data = length 336, hash 613047C1
sample 84:
time = 2016000
flags = 1
data = length 288, hash CDC747BF
sample 85:
time = 2040000
flags = 1
data = length 336, hash AF22AA74
sample 86:
time = 2064000
flags = 1
data = length 384, hash 82F326AA
sample 87:
time = 2088000
flags = 1
data = length 384, hash EDA26C4D
sample 88:
time = 2112000
flags = 1
data = length 336, hash 94C643DC
sample 89:
time = 2136000
flags = 1
data = length 288, hash CB5D9C40
sample 90:
time = 2160000
flags = 1
data = length 336, hash 1E69DE3F
sample 91:
time = 2184000
flags = 1
data = length 336, hash 7E472219
sample 92:
time = 2208000
flags = 1
data = length 336, hash DA47B9FA
sample 93:
time = 2232000
flags = 1
data = length 336, hash DD0ABB7C
sample 94:
time = 2256000
flags = 1
data = length 288, hash DBF93FAC
sample 95:
time = 2280000
flags = 1
data = length 336, hash 243F4B2
sample 96:
time = 2304000
flags = 1
data = length 336, hash 2E881490
sample 97:
time = 2328000
flags = 1
data = length 288, hash 1C28C8BE
sample 98:
time = 2352000
flags = 1
data = length 336, hash C73E5D30
sample 99:
time = 2376000
flags = 1
data = length 288, hash 98B5BFF6
sample 100:
time = 2400000
flags = 1
data = length 336, hash E0135533
sample 101:
time = 2424000
flags = 1
data = length 336, hash D13C9DBC
sample 102:
time = 2448000
flags = 1
data = length 336, hash 63D524CA
sample 103:
time = 2472000
flags = 1
data = length 288, hash A28514C3
sample 104:
time = 2496000
flags = 1
data = length 336, hash 72B647FF
sample 105:
time = 2520000
flags = 1
data = length 336, hash 8F740AB1
sample 106:
time = 2544000
flags = 1
data = length 336, hash 5E3C7E93
sample 107:
time = 2568000
flags = 1
data = length 336, hash 121B913B
sample 108:
time = 2592000
flags = 1
data = length 336, hash 578FCCF2
sample 109:
time = 2616000
flags = 1
data = length 336, hash 5B5823DE
sample 110:
time = 2640000
flags = 1
data = length 384, hash D8B83F78
sample 111:
time = 2664000
flags = 1
data = length 240, hash E649682F
sample 112:
time = 2688000
flags = 1
data = length 96, hash C559A6F4
sample 113:
time = 2712000
flags = 1
data = length 96, hash 792796BC
sample 114:
time = 2736000
flags = 1
data = length 120, hash 8172CD0E
sample 115:
time = 2760000
flags = 1
data = length 120, hash F562B52F
sample 116:
time = 2784000
flags = 1
data = length 96, hash FF8D5B98
tracksEnded = true

View file

@ -17,9 +17,7 @@ track 0:
height = 144 height = 144
frameRate = 15.00 frameRate = 15.00
colorInfo: colorInfo:
colorSpace = 1
colorRange = 2 colorRange = 2
colorTransfer = 3
lumaBitdepth = 8 lumaBitdepth = 8
chromaBitdepth = 8 chromaBitdepth = 8
metadata = entries=[Mp4Timestamp: creation time=3000000000, modification time=4000000000, timescale=10000] metadata = entries=[Mp4Timestamp: creation time=3000000000, modification time=4000000000, timescale=10000]

View file

@ -19,9 +19,7 @@ track 0:
height = 144 height = 144
frameRate = 15.00 frameRate = 15.00
colorInfo: colorInfo:
colorSpace = 1
colorRange = 2 colorRange = 2
colorTransfer = 3
lumaBitdepth = 8 lumaBitdepth = 8
chromaBitdepth = 8 chromaBitdepth = 8
metadata = entries=[Mp4Timestamp: creation time=3000000000, modification time=4000000000, timescale=10000] metadata = entries=[Mp4Timestamp: creation time=3000000000, modification time=4000000000, timescale=10000]

View file

@ -17,9 +17,7 @@ track 0:
height = 720 height = 720
frameRate = 29.97 frameRate = 29.97
colorInfo: colorInfo:
colorSpace = 1
colorRange = 2 colorRange = 2
colorTransfer = 3
lumaBitdepth = 8 lumaBitdepth = 8
chromaBitdepth = 8 chromaBitdepth = 8
metadata = entries=[Mp4Timestamp: creation time=3000000000, modification time=4000000000, timescale=10000] metadata = entries=[Mp4Timestamp: creation time=3000000000, modification time=4000000000, timescale=10000]

View file

@ -19,9 +19,7 @@ track 0:
height = 480 height = 480
frameRate = 30.00 frameRate = 30.00
colorInfo: colorInfo:
colorSpace = 1
colorRange = 2 colorRange = 2
colorTransfer = 3
lumaBitdepth = 8 lumaBitdepth = 8
chromaBitdepth = 8 chromaBitdepth = 8
metadata = entries=[Mp4Timestamp: creation time=3000000000, modification time=4000000000, timescale=10000] metadata = entries=[Mp4Timestamp: creation time=3000000000, modification time=4000000000, timescale=10000]