diff --git a/libraries/common/src/main/java/androidx/media3/common/Metadata.java b/libraries/common/src/main/java/androidx/media3/common/Metadata.java index 1af08378f7..eadf456c18 100644 --- a/libraries/common/src/main/java/androidx/media3/common/Metadata.java +++ b/libraries/common/src/main/java/androidx/media3/common/Metadata.java @@ -20,6 +20,7 @@ import android.os.Parcelable; import androidx.annotation.Nullable; import androidx.media3.common.util.UnstableApi; import androidx.media3.common.util.Util; +import com.google.common.primitives.Longs; import java.util.Arrays; import java.util.List; @@ -61,11 +62,28 @@ public final class Metadata implements Parcelable { } private final Entry[] entries; + /** + * The presentation time of the metadata, in microseconds. + * + *
This time is an offset from the start of the current {@link Timeline.Period}. + * + *
This time is {@link C#TIME_UNSET} when not known or undefined.
+ */
+ public final long presentationTimeUs;
/**
* @param entries The metadata entries.
*/
public Metadata(Entry... entries) {
+ this(/* presentationTimeUs= */ C.TIME_UNSET, entries);
+ }
+
+ /**
+ * @param presentationTimeUs The presentation time for the metadata entries.
+ * @param entries The metadata entries.
+ */
+ public Metadata(long presentationTimeUs, Entry... entries) {
+ this.presentationTimeUs = presentationTimeUs;
this.entries = entries;
}
@@ -73,7 +91,15 @@ public final class Metadata implements Parcelable {
* @param entries The metadata entries.
*/
public Metadata(List extends Entry> entries) {
- this.entries = entries.toArray(new Entry[0]);
+ this(entries.toArray(new Entry[0]));
+ }
+
+ /**
+ * @param presentationTimeUs The presentation time for the metadata entries.
+ * @param entries The metadata entries.
+ */
+ public Metadata(long presentationTimeUs, List extends Entry> entries) {
+ this(presentationTimeUs, entries.toArray(new Entry[0]));
}
/* package */ Metadata(Parcel in) {
@@ -81,6 +107,7 @@ public final class Metadata implements Parcelable {
for (int i = 0; i < entries.length; i++) {
entries[i] = in.readParcelable(Entry.class.getClassLoader());
}
+ presentationTimeUs = in.readLong();
}
/** Returns the number of metadata entries. */
@@ -123,7 +150,8 @@ public final class Metadata implements Parcelable {
if (entriesToAppend.length == 0) {
return this;
}
- return new Metadata(Util.nullSafeArrayConcatenation(entries, entriesToAppend));
+ return new Metadata(
+ presentationTimeUs, Util.nullSafeArrayConcatenation(entries, entriesToAppend));
}
@Override
@@ -135,17 +163,21 @@ public final class Metadata implements Parcelable {
return false;
}
Metadata other = (Metadata) obj;
- return Arrays.equals(entries, other.entries);
+ return Arrays.equals(entries, other.entries) && presentationTimeUs == other.presentationTimeUs;
}
@Override
public int hashCode() {
- return Arrays.hashCode(entries);
+ int result = Arrays.hashCode(entries);
+ result = 31 * result + Longs.hashCode(presentationTimeUs);
+ return result;
}
@Override
public String toString() {
- return "entries=" + Arrays.toString(entries);
+ return "entries="
+ + Arrays.toString(entries)
+ + (presentationTimeUs == C.TIME_UNSET ? "" : ", presentationTimeUs=" + presentationTimeUs);
}
// Parcelable implementation.
@@ -161,6 +193,7 @@ public final class Metadata implements Parcelable {
for (Entry entry : entries) {
dest.writeParcelable(entry, 0);
}
+ dest.writeLong(presentationTimeUs);
}
public static final Parcelable.Creator This time is an offset from the start of the current {@link Timeline.Period}
+ * This time is an offset from the start of the current {@link Timeline.Period}.
*/
@UnstableApi public final long presentationTimeUs;
diff --git a/libraries/common/src/test/java/androidx/media3/common/MetadataTest.java b/libraries/common/src/test/java/androidx/media3/common/MetadataTest.java
index 31ad83244a..0aa869aaad 100644
--- a/libraries/common/src/test/java/androidx/media3/common/MetadataTest.java
+++ b/libraries/common/src/test/java/androidx/media3/common/MetadataTest.java
@@ -30,7 +30,10 @@ public class MetadataTest {
@Test
public void parcelable() {
Metadata metadataToParcel =
- new Metadata(new FakeMetadataEntry("id1"), new FakeMetadataEntry("id2"));
+ new Metadata(
+ /* presentationTimeUs= */ 1_230_000,
+ new FakeMetadataEntry("id1"),
+ new FakeMetadataEntry("id2"));
Parcel parcel = Parcel.obtain();
metadataToParcel.writeToParcel(parcel, 0);
diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/metadata/MetadataRenderer.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/metadata/MetadataRenderer.java
index 4aca3b8164..0c7b16f8f3 100644
--- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/metadata/MetadataRenderer.java
+++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/metadata/MetadataRenderer.java
@@ -15,6 +15,7 @@
*/
package androidx.media3.exoplayer.metadata;
+import static androidx.media3.common.util.Assertions.checkState;
import static androidx.media3.common.util.Util.castNonNull;
import android.os.Handler;
@@ -36,6 +37,7 @@ import androidx.media3.extractor.metadata.MetadataDecoder;
import androidx.media3.extractor.metadata.MetadataInputBuffer;
import java.util.ArrayList;
import java.util.List;
+import org.checkerframework.dataflow.qual.SideEffectFree;
/** A renderer for metadata. */
@UnstableApi
@@ -53,8 +55,8 @@ public final class MetadataRenderer extends BaseRenderer implements Callback {
private boolean inputStreamEnded;
private boolean outputStreamEnded;
private long subsampleOffsetUs;
- private long pendingMetadataTimestampUs;
@Nullable private Metadata pendingMetadata;
+ private long outputStreamOffsetUs;
/**
* @param output The output.
@@ -85,7 +87,7 @@ public final class MetadataRenderer extends BaseRenderer implements Callback {
outputLooper == null ? null : Util.createHandler(outputLooper, /* callback= */ this);
this.decoderFactory = Assertions.checkNotNull(decoderFactory);
buffer = new MetadataInputBuffer();
- pendingMetadataTimestampUs = C.TIME_UNSET;
+ outputStreamOffsetUs = C.TIME_UNSET;
}
@Override
@@ -106,12 +108,12 @@ public final class MetadataRenderer extends BaseRenderer implements Callback {
@Override
protected void onStreamChanged(Format[] formats, long startPositionUs, long offsetUs) {
decoder = decoderFactory.createDecoder(formats[0]);
+ outputStreamOffsetUs = offsetUs;
}
@Override
protected void onPositionReset(long positionUs, boolean joining) {
pendingMetadata = null;
- pendingMetadataTimestampUs = C.TIME_UNSET;
inputStreamEnded = false;
outputStreamEnded = false;
}
@@ -158,8 +160,8 @@ public final class MetadataRenderer extends BaseRenderer implements Callback {
@Override
protected void onDisabled() {
pendingMetadata = null;
- pendingMetadataTimestampUs = C.TIME_UNSET;
decoder = null;
+ outputStreamOffsetUs = C.TIME_UNSET;
}
@Override
@@ -200,9 +202,9 @@ public final class MetadataRenderer extends BaseRenderer implements Callback {
List