Replacing label with a list of Label elements in Format.
This commit is contained in:
parent
d997ba367c
commit
df763220c8
3
gradle/wrapper/gradle-wrapper.properties
vendored
3
gradle/wrapper/gradle-wrapper.properties
vendored
@ -1,5 +1,6 @@
|
|||||||
|
#Tue Jan 30 08:51:00 MST 2024
|
||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.0-all.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-8.0-bin.zip
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
|
@ -49,7 +49,7 @@ import java.util.UUID;
|
|||||||
*
|
*
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li>{@link #id}
|
* <li>{@link #id}
|
||||||
* <li>{@link #label}
|
* <li>{@link #labels}
|
||||||
* <li>{@link #language}
|
* <li>{@link #language}
|
||||||
* <li>{@link #selectionFlags}
|
* <li>{@link #selectionFlags}
|
||||||
* <li>{@link #roleFlags}
|
* <li>{@link #roleFlags}
|
||||||
@ -136,7 +136,7 @@ public final class Format implements Bundleable {
|
|||||||
public static final class Builder {
|
public static final class Builder {
|
||||||
|
|
||||||
@Nullable private String id;
|
@Nullable private String id;
|
||||||
@Nullable private String label;
|
@Nullable private List<Label> labels;
|
||||||
@Nullable private String language;
|
@Nullable private String language;
|
||||||
private @C.SelectionFlags int selectionFlags;
|
private @C.SelectionFlags int selectionFlags;
|
||||||
private @C.RoleFlags int roleFlags;
|
private @C.RoleFlags int roleFlags;
|
||||||
@ -224,7 +224,7 @@ public final class Format implements Bundleable {
|
|||||||
*/
|
*/
|
||||||
private Builder(Format format) {
|
private Builder(Format format) {
|
||||||
this.id = format.id;
|
this.id = format.id;
|
||||||
this.label = format.label;
|
this.labels = format.labels;
|
||||||
this.language = format.language;
|
this.language = format.language;
|
||||||
this.selectionFlags = format.selectionFlags;
|
this.selectionFlags = format.selectionFlags;
|
||||||
this.roleFlags = format.roleFlags;
|
this.roleFlags = format.roleFlags;
|
||||||
@ -291,14 +291,14 @@ public final class Format implements Bundleable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets {@link Format#label}. The default value is {@code null}.
|
* Sets {@link Format#labels}. The default value is {@code null}.
|
||||||
*
|
*
|
||||||
* @param label The {@link Format#label}.
|
* @param labels The {@link Format#labels}.
|
||||||
* @return The builder.
|
* @return The builder.
|
||||||
*/
|
*/
|
||||||
@CanIgnoreReturnValue
|
@CanIgnoreReturnValue
|
||||||
public Builder setLabel(@Nullable String label) {
|
public Builder setLabels(@Nullable List<Label> labels) {
|
||||||
this.label = label;
|
this.labels = labels;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -741,7 +741,7 @@ public final class Format implements Bundleable {
|
|||||||
@Nullable public final String id;
|
@Nullable public final String id;
|
||||||
|
|
||||||
/** The human readable label, or null if unknown or not applicable. */
|
/** The human readable label, or null if unknown or not applicable. */
|
||||||
@Nullable public final String label;
|
@Nullable public final List<Label> labels;
|
||||||
|
|
||||||
/** The language as an IETF BCP 47 conformant tag, or null if unknown or not applicable. */
|
/** The language as an IETF BCP 47 conformant tag, or null if unknown or not applicable. */
|
||||||
@Nullable public final String language;
|
@Nullable public final String language;
|
||||||
@ -931,7 +931,7 @@ public final class Format implements Bundleable {
|
|||||||
|
|
||||||
private Format(Builder builder) {
|
private Format(Builder builder) {
|
||||||
id = builder.id;
|
id = builder.id;
|
||||||
label = builder.label;
|
labels = builder.labels;
|
||||||
language = Util.normalizeLanguageCode(builder.language);
|
language = Util.normalizeLanguageCode(builder.language);
|
||||||
selectionFlags = builder.selectionFlags;
|
selectionFlags = builder.selectionFlags;
|
||||||
roleFlags = builder.roleFlags;
|
roleFlags = builder.roleFlags;
|
||||||
@ -1002,7 +1002,8 @@ public final class Format implements Bundleable {
|
|||||||
int tileCountVertical = manifestFormat.tileCountVertical;
|
int tileCountVertical = manifestFormat.tileCountVertical;
|
||||||
|
|
||||||
// Prefer manifest values, but fill in from sample format if missing.
|
// Prefer manifest values, but fill in from sample format if missing.
|
||||||
@Nullable String label = manifestFormat.label != null ? manifestFormat.label : this.label;
|
@Nullable
|
||||||
|
List<Label> labels = manifestFormat.labels != null ? manifestFormat.labels : this.labels;
|
||||||
@Nullable String language = this.language;
|
@Nullable String language = this.language;
|
||||||
if ((trackType == C.TRACK_TYPE_TEXT || trackType == C.TRACK_TYPE_AUDIO)
|
if ((trackType == C.TRACK_TYPE_TEXT || trackType == C.TRACK_TYPE_AUDIO)
|
||||||
&& manifestFormat.language != null) {
|
&& manifestFormat.language != null) {
|
||||||
@ -1043,7 +1044,7 @@ public final class Format implements Bundleable {
|
|||||||
|
|
||||||
return buildUpon()
|
return buildUpon()
|
||||||
.setId(id)
|
.setId(id)
|
||||||
.setLabel(label)
|
.setLabels(labels)
|
||||||
.setLanguage(language)
|
.setLanguage(language)
|
||||||
.setSelectionFlags(selectionFlags)
|
.setSelectionFlags(selectionFlags)
|
||||||
.setRoleFlags(roleFlags)
|
.setRoleFlags(roleFlags)
|
||||||
@ -1078,7 +1079,7 @@ public final class Format implements Bundleable {
|
|||||||
return "Format("
|
return "Format("
|
||||||
+ id
|
+ id
|
||||||
+ ", "
|
+ ", "
|
||||||
+ label
|
+ labels
|
||||||
+ ", "
|
+ ", "
|
||||||
+ containerMimeType
|
+ containerMimeType
|
||||||
+ ", "
|
+ ", "
|
||||||
@ -1111,7 +1112,7 @@ public final class Format implements Bundleable {
|
|||||||
// Some fields for which hashing is expensive are deliberately omitted.
|
// Some fields for which hashing is expensive are deliberately omitted.
|
||||||
int result = 17;
|
int result = 17;
|
||||||
result = 31 * result + (id == null ? 0 : id.hashCode());
|
result = 31 * result + (id == null ? 0 : id.hashCode());
|
||||||
result = 31 * result + (label != null ? label.hashCode() : 0);
|
result = 31 * result + (labels != null ? labels.hashCode() : 0);
|
||||||
result = 31 * result + (language == null ? 0 : language.hashCode());
|
result = 31 * result + (language == null ? 0 : language.hashCode());
|
||||||
result = 31 * result + selectionFlags;
|
result = 31 * result + selectionFlags;
|
||||||
result = 31 * result + roleFlags;
|
result = 31 * result + roleFlags;
|
||||||
@ -1189,7 +1190,7 @@ public final class Format implements Bundleable {
|
|||||||
&& Float.compare(frameRate, other.frameRate) == 0
|
&& Float.compare(frameRate, other.frameRate) == 0
|
||||||
&& Float.compare(pixelWidthHeightRatio, other.pixelWidthHeightRatio) == 0
|
&& Float.compare(pixelWidthHeightRatio, other.pixelWidthHeightRatio) == 0
|
||||||
&& Util.areEqual(id, other.id)
|
&& Util.areEqual(id, other.id)
|
||||||
&& Util.areEqual(label, other.label)
|
&& Util.areEqual(labels, other.labels)
|
||||||
&& Util.areEqual(codecs, other.codecs)
|
&& Util.areEqual(codecs, other.codecs)
|
||||||
&& Util.areEqual(containerMimeType, other.containerMimeType)
|
&& Util.areEqual(containerMimeType, other.containerMimeType)
|
||||||
&& Util.areEqual(sampleMimeType, other.sampleMimeType)
|
&& Util.areEqual(sampleMimeType, other.sampleMimeType)
|
||||||
@ -1281,8 +1282,8 @@ public final class Format implements Bundleable {
|
|||||||
if (format.language != null) {
|
if (format.language != null) {
|
||||||
builder.append(", language=").append(format.language);
|
builder.append(", language=").append(format.language);
|
||||||
}
|
}
|
||||||
if (format.label != null) {
|
if (format.labels != null) {
|
||||||
builder.append(", label=").append(format.label);
|
builder.append(", label=").append(format.labels);
|
||||||
}
|
}
|
||||||
if (format.selectionFlags != 0) {
|
if (format.selectionFlags != 0) {
|
||||||
builder.append(", selectionFlags=[");
|
builder.append(", selectionFlags=[");
|
||||||
@ -1300,7 +1301,7 @@ public final class Format implements Bundleable {
|
|||||||
// Bundleable implementation.
|
// Bundleable implementation.
|
||||||
|
|
||||||
private static final String FIELD_ID = Util.intToStringMaxRadix(0);
|
private static final String FIELD_ID = Util.intToStringMaxRadix(0);
|
||||||
private static final String FIELD_LABEL = Util.intToStringMaxRadix(1);
|
private static final String FIELD_LABELS = Util.intToStringMaxRadix(1);
|
||||||
private static final String FIELD_LANGUAGE = Util.intToStringMaxRadix(2);
|
private static final String FIELD_LANGUAGE = Util.intToStringMaxRadix(2);
|
||||||
private static final String FIELD_SELECTION_FLAGS = Util.intToStringMaxRadix(3);
|
private static final String FIELD_SELECTION_FLAGS = Util.intToStringMaxRadix(3);
|
||||||
private static final String FIELD_ROLE_FLAGS = Util.intToStringMaxRadix(4);
|
private static final String FIELD_ROLE_FLAGS = Util.intToStringMaxRadix(4);
|
||||||
@ -1346,7 +1347,11 @@ public final class Format implements Bundleable {
|
|||||||
public Bundle toBundle(boolean excludeMetadata) {
|
public Bundle toBundle(boolean excludeMetadata) {
|
||||||
Bundle bundle = new Bundle();
|
Bundle bundle = new Bundle();
|
||||||
bundle.putString(FIELD_ID, id);
|
bundle.putString(FIELD_ID, id);
|
||||||
bundle.putString(FIELD_LABEL, label);
|
if (labels != null) {
|
||||||
|
for (int i = 0; i < labels.size(); i++) {
|
||||||
|
bundle.putParcelable(keyForLabel(i), labels.get(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
bundle.putString(FIELD_LANGUAGE, language);
|
bundle.putString(FIELD_LANGUAGE, language);
|
||||||
bundle.putInt(FIELD_SELECTION_FLAGS, selectionFlags);
|
bundle.putInt(FIELD_SELECTION_FLAGS, selectionFlags);
|
||||||
bundle.putInt(FIELD_ROLE_FLAGS, roleFlags);
|
bundle.putInt(FIELD_ROLE_FLAGS, roleFlags);
|
||||||
@ -1411,9 +1416,18 @@ public final class Format implements Bundleable {
|
|||||||
public static Format fromBundle(Bundle bundle) {
|
public static Format fromBundle(Bundle bundle) {
|
||||||
Builder builder = new Builder();
|
Builder builder = new Builder();
|
||||||
BundleCollectionUtil.ensureClassLoader(bundle);
|
BundleCollectionUtil.ensureClassLoader(bundle);
|
||||||
|
builder.setId(defaultIfNull(bundle.getString(FIELD_ID), DEFAULT.id));
|
||||||
|
|
||||||
|
List<Label> labels = new ArrayList<>();
|
||||||
|
for (int i = 0; ; i++) {
|
||||||
|
@Nullable Label label = bundle.getParcelable(keyForLabel(i));
|
||||||
|
if (label == null) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
labels.add(label);
|
||||||
|
}
|
||||||
builder
|
builder
|
||||||
.setId(defaultIfNull(bundle.getString(FIELD_ID), DEFAULT.id))
|
.setLabels(labels)
|
||||||
.setLabel(defaultIfNull(bundle.getString(FIELD_LABEL), DEFAULT.label))
|
|
||||||
.setLanguage(defaultIfNull(bundle.getString(FIELD_LANGUAGE), DEFAULT.language))
|
.setLanguage(defaultIfNull(bundle.getString(FIELD_LANGUAGE), DEFAULT.language))
|
||||||
.setSelectionFlags(bundle.getInt(FIELD_SELECTION_FLAGS, DEFAULT.selectionFlags))
|
.setSelectionFlags(bundle.getInt(FIELD_SELECTION_FLAGS, DEFAULT.selectionFlags))
|
||||||
.setRoleFlags(bundle.getInt(FIELD_ROLE_FLAGS, DEFAULT.roleFlags))
|
.setRoleFlags(bundle.getInt(FIELD_ROLE_FLAGS, DEFAULT.roleFlags))
|
||||||
@ -1480,6 +1494,10 @@ public final class Format implements Bundleable {
|
|||||||
+ Integer.toString(initialisationDataIndex, Character.MAX_RADIX);
|
+ Integer.toString(initialisationDataIndex, Character.MAX_RADIX);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static String keyForLabel(int labelIndex) {
|
||||||
|
return FIELD_LABELS + "_" + Integer.toString(labelIndex, Character.MAX_RADIX);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utility method to get {@code defaultValue} if {@code value} is {@code null}. {@code
|
* Utility method to get {@code defaultValue} if {@code value} is {@code null}. {@code
|
||||||
* defaultValue} can be {@code null}.
|
* defaultValue} can be {@code null}.
|
||||||
|
@ -0,0 +1,82 @@
|
|||||||
|
package androidx.media3.common;
|
||||||
|
|
||||||
|
import android.os.Parcel;
|
||||||
|
import android.os.Parcelable;
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.media3.common.util.UnstableApi;
|
||||||
|
import androidx.media3.common.util.Util;
|
||||||
|
|
||||||
|
/** A Label, as defined by ISO 23009-1, 4th edition, 5.3.7.2. */
|
||||||
|
@UnstableApi
|
||||||
|
public class Label implements Parcelable {
|
||||||
|
/** The Label identifier, if one exists. */
|
||||||
|
@Nullable public final String id;
|
||||||
|
|
||||||
|
/** Declares the language code(s) for this Label. */
|
||||||
|
@Nullable public final String lang;
|
||||||
|
|
||||||
|
/** The value for this Label. */
|
||||||
|
public final String value;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param id The id.
|
||||||
|
* @param lang The lang code.
|
||||||
|
* @param value The value.
|
||||||
|
*/
|
||||||
|
public Label(@Nullable String id, @Nullable String lang, String value) {
|
||||||
|
this.id = id;
|
||||||
|
this.lang = lang;
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* package */ Label(Parcel in) {
|
||||||
|
id = in.readString();
|
||||||
|
lang = in.readString();
|
||||||
|
value = in.readString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(@Nullable Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
Label label = (Label) o;
|
||||||
|
return Util.areEqual(id, label.id)
|
||||||
|
&& Util.areEqual(lang, label.lang)
|
||||||
|
&& Util.areEqual(value, label.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
int result = value.hashCode();
|
||||||
|
result = 31 * result + (id != null ? id.hashCode() : 0);
|
||||||
|
result = 31 * result + (lang != null ? lang.hashCode() : 0);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int describeContents() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||||
|
dest.writeString(id);
|
||||||
|
dest.writeString(lang);
|
||||||
|
dest.writeString(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final Parcelable.Creator<Label> CREATOR =
|
||||||
|
new Parcelable.Creator<Label>() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Label createFromParcel(Parcel in) {
|
||||||
|
return new Label(in);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Label[] newArray(int size) {
|
||||||
|
return new Label[size];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
@ -83,9 +83,11 @@ public final class FormatTest {
|
|||||||
.setChromaBitdepth(11)
|
.setChromaBitdepth(11)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
|
List<Label> labels = new ArrayList<>();
|
||||||
|
labels.add(new Label("id", "en", "label"));
|
||||||
return new Format.Builder()
|
return new Format.Builder()
|
||||||
.setId("id")
|
.setId("id")
|
||||||
.setLabel("label")
|
.setLabels(labels)
|
||||||
.setLanguage("language")
|
.setLanguage("language")
|
||||||
.setSelectionFlags(C.SELECTION_FLAG_DEFAULT)
|
.setSelectionFlags(C.SELECTION_FLAG_DEFAULT)
|
||||||
.setRoleFlags(C.ROLE_FLAG_MAIN)
|
.setRoleFlags(C.ROLE_FLAG_MAIN)
|
||||||
|
@ -450,7 +450,7 @@ public abstract class DecoderAudioRenderer<
|
|||||||
.setEncoderPadding(encoderPadding)
|
.setEncoderPadding(encoderPadding)
|
||||||
.setMetadata(inputFormat.metadata)
|
.setMetadata(inputFormat.metadata)
|
||||||
.setId(inputFormat.id)
|
.setId(inputFormat.id)
|
||||||
.setLabel(inputFormat.label)
|
.setLabels(inputFormat.labels)
|
||||||
.setLanguage(inputFormat.language)
|
.setLanguage(inputFormat.language)
|
||||||
.setSelectionFlags(inputFormat.selectionFlags)
|
.setSelectionFlags(inputFormat.selectionFlags)
|
||||||
.setRoleFlags(inputFormat.roleFlags)
|
.setRoleFlags(inputFormat.roleFlags)
|
||||||
|
@ -551,7 +551,7 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media
|
|||||||
.setEncoderPadding(format.encoderPadding)
|
.setEncoderPadding(format.encoderPadding)
|
||||||
.setMetadata(format.metadata)
|
.setMetadata(format.metadata)
|
||||||
.setId(format.id)
|
.setId(format.id)
|
||||||
.setLabel(format.label)
|
.setLabels(format.labels)
|
||||||
.setLanguage(format.language)
|
.setLanguage(format.language)
|
||||||
.setSelectionFlags(format.selectionFlags)
|
.setSelectionFlags(format.selectionFlags)
|
||||||
.setRoleFlags(format.roleFlags)
|
.setRoleFlags(format.roleFlags)
|
||||||
|
@ -26,6 +26,7 @@ import androidx.annotation.Nullable;
|
|||||||
import androidx.media3.common.AdViewProvider;
|
import androidx.media3.common.AdViewProvider;
|
||||||
import androidx.media3.common.C;
|
import androidx.media3.common.C;
|
||||||
import androidx.media3.common.Format;
|
import androidx.media3.common.Format;
|
||||||
|
import androidx.media3.common.Label;
|
||||||
import androidx.media3.common.MediaItem;
|
import androidx.media3.common.MediaItem;
|
||||||
import androidx.media3.common.MimeTypes;
|
import androidx.media3.common.MimeTypes;
|
||||||
import androidx.media3.common.util.Assertions;
|
import androidx.media3.common.util.Assertions;
|
||||||
@ -58,6 +59,7 @@ import com.google.common.collect.ImmutableList;
|
|||||||
import com.google.common.primitives.Ints;
|
import com.google.common.primitives.Ints;
|
||||||
import com.google.errorprone.annotations.CanIgnoreReturnValue;
|
import com.google.errorprone.annotations.CanIgnoreReturnValue;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -513,13 +515,21 @@ public final class DefaultMediaSourceFactory implements MediaSourceFactory {
|
|||||||
mediaSources[0] = mediaSource;
|
mediaSources[0] = mediaSource;
|
||||||
for (int i = 0; i < subtitleConfigurations.size(); i++) {
|
for (int i = 0; i < subtitleConfigurations.size(); i++) {
|
||||||
if (parseSubtitlesDuringExtraction) {
|
if (parseSubtitlesDuringExtraction) {
|
||||||
|
List<Label> labels = new ArrayList<>();
|
||||||
|
String label = subtitleConfigurations.get(i).label;
|
||||||
|
if (label != null) {
|
||||||
|
labels.add(new Label(null, null, label));
|
||||||
|
} else {
|
||||||
|
labels = null;
|
||||||
|
}
|
||||||
|
|
||||||
Format format =
|
Format format =
|
||||||
new Format.Builder()
|
new Format.Builder()
|
||||||
.setSampleMimeType(subtitleConfigurations.get(i).mimeType)
|
.setSampleMimeType(subtitleConfigurations.get(i).mimeType)
|
||||||
.setLanguage(subtitleConfigurations.get(i).language)
|
.setLanguage(subtitleConfigurations.get(i).language)
|
||||||
.setSelectionFlags(subtitleConfigurations.get(i).selectionFlags)
|
.setSelectionFlags(subtitleConfigurations.get(i).selectionFlags)
|
||||||
.setRoleFlags(subtitleConfigurations.get(i).roleFlags)
|
.setRoleFlags(subtitleConfigurations.get(i).roleFlags)
|
||||||
.setLabel(subtitleConfigurations.get(i).label)
|
.setLabels(labels)
|
||||||
.setId(subtitleConfigurations.get(i).id)
|
.setId(subtitleConfigurations.get(i).id)
|
||||||
.build();
|
.build();
|
||||||
ExtractorsFactory extractorsFactory =
|
ExtractorsFactory extractorsFactory =
|
||||||
|
@ -21,6 +21,7 @@ import static com.google.common.base.MoreObjects.firstNonNull;
|
|||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.media3.common.Format;
|
import androidx.media3.common.Format;
|
||||||
|
import androidx.media3.common.Label;
|
||||||
import androidx.media3.common.MediaItem;
|
import androidx.media3.common.MediaItem;
|
||||||
import androidx.media3.common.MimeTypes;
|
import androidx.media3.common.MimeTypes;
|
||||||
import androidx.media3.common.Timeline;
|
import androidx.media3.common.Timeline;
|
||||||
@ -33,6 +34,8 @@ import androidx.media3.exoplayer.upstream.DefaultLoadErrorHandlingPolicy;
|
|||||||
import androidx.media3.exoplayer.upstream.LoadErrorHandlingPolicy;
|
import androidx.media3.exoplayer.upstream.LoadErrorHandlingPolicy;
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.google.errorprone.annotations.CanIgnoreReturnValue;
|
import com.google.errorprone.annotations.CanIgnoreReturnValue;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads data at a given {@link Uri} as a single sample belonging to a single {@link MediaPeriod}.
|
* Loads data at a given {@link Uri} as a single sample belonging to a single {@link MediaPeriod}.
|
||||||
@ -170,13 +173,20 @@ public final class SingleSampleMediaSource extends BaseMediaSource {
|
|||||||
.setSubtitleConfigurations(ImmutableList.of(subtitleConfiguration))
|
.setSubtitleConfigurations(ImmutableList.of(subtitleConfiguration))
|
||||||
.setTag(tag)
|
.setTag(tag)
|
||||||
.build();
|
.build();
|
||||||
|
List<Label> labels = new ArrayList<>();
|
||||||
|
String label = subtitleConfiguration.label;
|
||||||
|
if (label != null) {
|
||||||
|
labels.add(new Label(null, null, label));
|
||||||
|
} else {
|
||||||
|
labels = null;
|
||||||
|
}
|
||||||
this.format =
|
this.format =
|
||||||
new Format.Builder()
|
new Format.Builder()
|
||||||
.setSampleMimeType(firstNonNull(subtitleConfiguration.mimeType, MimeTypes.TEXT_UNKNOWN))
|
.setSampleMimeType(firstNonNull(subtitleConfiguration.mimeType, MimeTypes.TEXT_UNKNOWN))
|
||||||
.setLanguage(subtitleConfiguration.language)
|
.setLanguage(subtitleConfiguration.language)
|
||||||
.setSelectionFlags(subtitleConfiguration.selectionFlags)
|
.setSelectionFlags(subtitleConfiguration.selectionFlags)
|
||||||
.setRoleFlags(subtitleConfiguration.roleFlags)
|
.setRoleFlags(subtitleConfiguration.roleFlags)
|
||||||
.setLabel(subtitleConfiguration.label)
|
.setLabels(labels)
|
||||||
.setId(subtitleConfiguration.id != null ? subtitleConfiguration.id : trackId)
|
.setId(subtitleConfiguration.id != null ? subtitleConfiguration.id : trackId)
|
||||||
.build();
|
.build();
|
||||||
this.dataSpec =
|
this.dataSpec =
|
||||||
|
@ -517,7 +517,7 @@ public final class OutputConsumerAdapterV30 implements MediaParser.OutputConsume
|
|||||||
.setLanguage(muxedCaptionFormat.language)
|
.setLanguage(muxedCaptionFormat.language)
|
||||||
.setRoleFlags(muxedCaptionFormat.roleFlags)
|
.setRoleFlags(muxedCaptionFormat.roleFlags)
|
||||||
.setSelectionFlags(muxedCaptionFormat.selectionFlags)
|
.setSelectionFlags(muxedCaptionFormat.selectionFlags)
|
||||||
.setLabel(muxedCaptionFormat.label)
|
.setLabels(muxedCaptionFormat.labels)
|
||||||
.setMetadata(muxedCaptionFormat.metadata);
|
.setMetadata(muxedCaptionFormat.metadata);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -2058,7 +2058,7 @@ public final class SampleQueueTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static Format copyWithLabel(Format format, String label) {
|
private static Format copyWithLabel(Format format, String label) {
|
||||||
return format.buildUpon().setLabel(label).build();
|
return format.buildUpon().setLabels(label).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final class MockDrmSessionManager implements DrmSessionManager {
|
private static final class MockDrmSessionManager implements DrmSessionManager {
|
||||||
|
@ -29,6 +29,7 @@ import androidx.media3.common.C;
|
|||||||
import androidx.media3.common.DrmInitData;
|
import androidx.media3.common.DrmInitData;
|
||||||
import androidx.media3.common.DrmInitData.SchemeData;
|
import androidx.media3.common.DrmInitData.SchemeData;
|
||||||
import androidx.media3.common.Format;
|
import androidx.media3.common.Format;
|
||||||
|
import androidx.media3.common.Label;
|
||||||
import androidx.media3.common.MimeTypes;
|
import androidx.media3.common.MimeTypes;
|
||||||
import androidx.media3.common.ParserException;
|
import androidx.media3.common.ParserException;
|
||||||
import androidx.media3.common.util.Assertions;
|
import androidx.media3.common.util.Assertions;
|
||||||
@ -404,7 +405,8 @@ public class DashManifestParser extends DefaultHandler
|
|||||||
int audioChannels = Format.NO_VALUE;
|
int audioChannels = Format.NO_VALUE;
|
||||||
int audioSamplingRate = parseInt(xpp, "audioSamplingRate", Format.NO_VALUE);
|
int audioSamplingRate = parseInt(xpp, "audioSamplingRate", Format.NO_VALUE);
|
||||||
String language = xpp.getAttributeValue(null, "lang");
|
String language = xpp.getAttributeValue(null, "lang");
|
||||||
String label = xpp.getAttributeValue(null, "label");
|
String adaptationSetLabel = xpp.getAttributeValue(null, "label");
|
||||||
|
List<Label> labels = new ArrayList<>();
|
||||||
String drmSchemeType = null;
|
String drmSchemeType = null;
|
||||||
ArrayList<SchemeData> drmSchemeDatas = new ArrayList<>();
|
ArrayList<SchemeData> drmSchemeDatas = new ArrayList<>();
|
||||||
ArrayList<Descriptor> inbandEventStreams = new ArrayList<>();
|
ArrayList<Descriptor> inbandEventStreams = new ArrayList<>();
|
||||||
@ -504,19 +506,23 @@ public class DashManifestParser extends DefaultHandler
|
|||||||
} else if (XmlPullParserUtil.isStartTag(xpp, "InbandEventStream")) {
|
} else if (XmlPullParserUtil.isStartTag(xpp, "InbandEventStream")) {
|
||||||
inbandEventStreams.add(parseDescriptor(xpp, "InbandEventStream"));
|
inbandEventStreams.add(parseDescriptor(xpp, "InbandEventStream"));
|
||||||
} else if (XmlPullParserUtil.isStartTag(xpp, "Label")) {
|
} else if (XmlPullParserUtil.isStartTag(xpp, "Label")) {
|
||||||
label = parseLabel(xpp);
|
labels.add(parseLabel(xpp));
|
||||||
} else if (XmlPullParserUtil.isStartTag(xpp)) {
|
} else if (XmlPullParserUtil.isStartTag(xpp)) {
|
||||||
parseAdaptationSetChild(xpp);
|
parseAdaptationSetChild(xpp);
|
||||||
}
|
}
|
||||||
} while (!XmlPullParserUtil.isEndTag(xpp, "AdaptationSet"));
|
} while (!XmlPullParserUtil.isEndTag(xpp, "AdaptationSet"));
|
||||||
|
|
||||||
|
if (labels.size() == 0 && adaptationSetLabel != null) {
|
||||||
|
labels.add(new Label(null, null, adaptationSetLabel));
|
||||||
|
}
|
||||||
|
|
||||||
// Build the representations.
|
// Build the representations.
|
||||||
List<Representation> representations = new ArrayList<>(representationInfos.size());
|
List<Representation> representations = new ArrayList<>(representationInfos.size());
|
||||||
for (int i = 0; i < representationInfos.size(); i++) {
|
for (int i = 0; i < representationInfos.size(); i++) {
|
||||||
representations.add(
|
representations.add(
|
||||||
buildRepresentation(
|
buildRepresentation(
|
||||||
representationInfos.get(i),
|
representationInfos.get(i),
|
||||||
label,
|
labels.isEmpty() ? null : labels,
|
||||||
drmSchemeType,
|
drmSchemeType,
|
||||||
drmSchemeDatas,
|
drmSchemeDatas,
|
||||||
inbandEventStreams));
|
inbandEventStreams));
|
||||||
@ -855,14 +861,12 @@ public class DashManifestParser extends DefaultHandler
|
|||||||
|
|
||||||
protected Representation buildRepresentation(
|
protected Representation buildRepresentation(
|
||||||
RepresentationInfo representationInfo,
|
RepresentationInfo representationInfo,
|
||||||
@Nullable String label,
|
@Nullable List<Label> labels,
|
||||||
@Nullable String extraDrmSchemeType,
|
@Nullable String extraDrmSchemeType,
|
||||||
ArrayList<SchemeData> extraDrmSchemeDatas,
|
ArrayList<SchemeData> extraDrmSchemeDatas,
|
||||||
ArrayList<Descriptor> extraInbandEventStreams) {
|
ArrayList<Descriptor> extraInbandEventStreams) {
|
||||||
Format.Builder formatBuilder = representationInfo.format.buildUpon();
|
Format.Builder formatBuilder = representationInfo.format.buildUpon();
|
||||||
if (label != null) {
|
formatBuilder.setLabels(labels);
|
||||||
formatBuilder.setLabel(label);
|
|
||||||
}
|
|
||||||
@Nullable String drmSchemeType = representationInfo.drmSchemeType;
|
@Nullable String drmSchemeType = representationInfo.drmSchemeType;
|
||||||
if (drmSchemeType == null) {
|
if (drmSchemeType == null) {
|
||||||
drmSchemeType = extraDrmSchemeType;
|
drmSchemeType = extraDrmSchemeType;
|
||||||
@ -1405,8 +1409,11 @@ public class DashManifestParser extends DefaultHandler
|
|||||||
* @throws IOException If an error occurs reading the element.
|
* @throws IOException If an error occurs reading the element.
|
||||||
* @return The parsed label.
|
* @return The parsed label.
|
||||||
*/
|
*/
|
||||||
protected String parseLabel(XmlPullParser xpp) throws XmlPullParserException, IOException {
|
protected Label parseLabel(XmlPullParser xpp) throws XmlPullParserException, IOException {
|
||||||
return parseText(xpp, "Label");
|
String id = xpp.getAttributeValue(null, "id");
|
||||||
|
String lang = xpp.getAttributeValue(null, "lang");
|
||||||
|
String value = parseText(xpp, "Label");
|
||||||
|
return new Label(id, lang, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -22,6 +22,7 @@ import androidx.annotation.Nullable;
|
|||||||
import androidx.media3.common.C;
|
import androidx.media3.common.C;
|
||||||
import androidx.media3.common.DrmInitData;
|
import androidx.media3.common.DrmInitData;
|
||||||
import androidx.media3.common.Format;
|
import androidx.media3.common.Format;
|
||||||
|
import androidx.media3.common.Label;
|
||||||
import androidx.media3.common.MimeTypes;
|
import androidx.media3.common.MimeTypes;
|
||||||
import androidx.media3.common.util.Util;
|
import androidx.media3.common.util.Util;
|
||||||
import androidx.media3.exoplayer.dash.manifest.Representation.MultiSegmentRepresentation;
|
import androidx.media3.exoplayer.dash.manifest.Representation.MultiSegmentRepresentation;
|
||||||
@ -278,8 +279,10 @@ public class DashManifestParserTest {
|
|||||||
|
|
||||||
List<AdaptationSet> adaptationSets = manifest.getPeriod(0).adaptationSets;
|
List<AdaptationSet> adaptationSets = manifest.getPeriod(0).adaptationSets;
|
||||||
|
|
||||||
assertThat(adaptationSets.get(0).representations.get(0).format.label).isEqualTo("audio label");
|
assertThat(adaptationSets.get(0).representations.get(0).format.labels.get(0).value)
|
||||||
assertThat(adaptationSets.get(1).representations.get(0).format.label).isEqualTo("video label");
|
.isEqualTo("audio label");
|
||||||
|
assertThat(adaptationSets.get(1).representations.get(0).format.labels.get(0).value)
|
||||||
|
.isEqualTo("video label");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -431,13 +434,39 @@ public class DashManifestParserTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void parseLabel() throws Exception {
|
public void parseLabel() throws Exception {
|
||||||
|
DashManifestParser parser = new DashManifestParser();
|
||||||
|
XmlPullParser xpp = XmlPullParserFactory.newInstance().newPullParser();
|
||||||
|
xpp.setInput(new StringReader("<Label id=\"1\" lang=\"en\">test label</Label>" + NEXT_TAG));
|
||||||
|
xpp.next();
|
||||||
|
|
||||||
|
Label label = parser.parseLabel(xpp);
|
||||||
|
assertThat(label.id).isEqualTo("1");
|
||||||
|
assertThat(label.lang).isEqualTo("en");
|
||||||
|
assertThat(label.value).isEqualTo("test label");
|
||||||
|
assertNextTag(xpp);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void parseLabel_noId() throws Exception {
|
||||||
|
DashManifestParser parser = new DashManifestParser();
|
||||||
|
XmlPullParser xpp = XmlPullParserFactory.newInstance().newPullParser();
|
||||||
|
xpp.setInput(new StringReader("<Label lang=\"en\">test label</Label>" + NEXT_TAG));
|
||||||
|
xpp.next();
|
||||||
|
|
||||||
|
Label label = parser.parseLabel(xpp);
|
||||||
|
assertThat(label.id).isEqualTo(null);
|
||||||
|
assertNextTag(xpp);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void parseLabel_noLang() throws Exception {
|
||||||
DashManifestParser parser = new DashManifestParser();
|
DashManifestParser parser = new DashManifestParser();
|
||||||
XmlPullParser xpp = XmlPullParserFactory.newInstance().newPullParser();
|
XmlPullParser xpp = XmlPullParserFactory.newInstance().newPullParser();
|
||||||
xpp.setInput(new StringReader("<Label>test label</Label>" + NEXT_TAG));
|
xpp.setInput(new StringReader("<Label>test label</Label>" + NEXT_TAG));
|
||||||
xpp.next();
|
xpp.next();
|
||||||
|
|
||||||
String label = parser.parseLabel(xpp);
|
Label label = parser.parseLabel(xpp);
|
||||||
assertThat(label).isEqualTo("test label");
|
assertThat(label.lang).isEqualTo(null);
|
||||||
assertNextTag(xpp);
|
assertNextTag(xpp);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -448,8 +477,8 @@ public class DashManifestParserTest {
|
|||||||
xpp.setInput(new StringReader("<Label/>" + NEXT_TAG));
|
xpp.setInput(new StringReader("<Label/>" + NEXT_TAG));
|
||||||
xpp.next();
|
xpp.next();
|
||||||
|
|
||||||
String label = parser.parseLabel(xpp);
|
Label label = parser.parseLabel(xpp);
|
||||||
assertThat(label).isEqualTo("");
|
assertThat(label.value).isEqualTo("");
|
||||||
assertNextTag(xpp);
|
assertNextTag(xpp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,6 +21,7 @@ import androidx.annotation.Nullable;
|
|||||||
import androidx.media3.common.C;
|
import androidx.media3.common.C;
|
||||||
import androidx.media3.common.DrmInitData;
|
import androidx.media3.common.DrmInitData;
|
||||||
import androidx.media3.common.Format;
|
import androidx.media3.common.Format;
|
||||||
|
import androidx.media3.common.Label;
|
||||||
import androidx.media3.common.Metadata;
|
import androidx.media3.common.Metadata;
|
||||||
import androidx.media3.common.MimeTypes;
|
import androidx.media3.common.MimeTypes;
|
||||||
import androidx.media3.common.StreamKey;
|
import androidx.media3.common.StreamKey;
|
||||||
@ -851,7 +852,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
|||||||
@Nullable String sampleMimeType = MimeTypes.getMediaMimeType(codecs);
|
@Nullable String sampleMimeType = MimeTypes.getMediaMimeType(codecs);
|
||||||
return new Format.Builder()
|
return new Format.Builder()
|
||||||
.setId(variantFormat.id)
|
.setId(variantFormat.id)
|
||||||
.setLabel(variantFormat.label)
|
.setLabels(variantFormat.labels)
|
||||||
.setContainerMimeType(variantFormat.containerMimeType)
|
.setContainerMimeType(variantFormat.containerMimeType)
|
||||||
.setSampleMimeType(sampleMimeType)
|
.setSampleMimeType(sampleMimeType)
|
||||||
.setCodecs(codecs)
|
.setCodecs(codecs)
|
||||||
@ -874,7 +875,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
|||||||
int selectionFlags = 0;
|
int selectionFlags = 0;
|
||||||
int roleFlags = 0;
|
int roleFlags = 0;
|
||||||
@Nullable String language = null;
|
@Nullable String language = null;
|
||||||
@Nullable String label = null;
|
@Nullable List<Label> labels = null;
|
||||||
if (mediaTagFormat != null) {
|
if (mediaTagFormat != null) {
|
||||||
codecs = mediaTagFormat.codecs;
|
codecs = mediaTagFormat.codecs;
|
||||||
metadata = mediaTagFormat.metadata;
|
metadata = mediaTagFormat.metadata;
|
||||||
@ -882,7 +883,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
|||||||
selectionFlags = mediaTagFormat.selectionFlags;
|
selectionFlags = mediaTagFormat.selectionFlags;
|
||||||
roleFlags = mediaTagFormat.roleFlags;
|
roleFlags = mediaTagFormat.roleFlags;
|
||||||
language = mediaTagFormat.language;
|
language = mediaTagFormat.language;
|
||||||
label = mediaTagFormat.label;
|
labels = mediaTagFormat.labels;
|
||||||
} else {
|
} else {
|
||||||
codecs = Util.getCodecsOfType(variantFormat.codecs, C.TRACK_TYPE_AUDIO);
|
codecs = Util.getCodecsOfType(variantFormat.codecs, C.TRACK_TYPE_AUDIO);
|
||||||
metadata = variantFormat.metadata;
|
metadata = variantFormat.metadata;
|
||||||
@ -891,7 +892,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
|||||||
selectionFlags = variantFormat.selectionFlags;
|
selectionFlags = variantFormat.selectionFlags;
|
||||||
roleFlags = variantFormat.roleFlags;
|
roleFlags = variantFormat.roleFlags;
|
||||||
language = variantFormat.language;
|
language = variantFormat.language;
|
||||||
label = variantFormat.label;
|
labels = variantFormat.labels;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@Nullable String sampleMimeType = MimeTypes.getMediaMimeType(codecs);
|
@Nullable String sampleMimeType = MimeTypes.getMediaMimeType(codecs);
|
||||||
@ -899,7 +900,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
|||||||
int peakBitrate = isPrimaryTrackInVariant ? variantFormat.peakBitrate : Format.NO_VALUE;
|
int peakBitrate = isPrimaryTrackInVariant ? variantFormat.peakBitrate : Format.NO_VALUE;
|
||||||
return new Format.Builder()
|
return new Format.Builder()
|
||||||
.setId(variantFormat.id)
|
.setId(variantFormat.id)
|
||||||
.setLabel(label)
|
.setLabels(labels)
|
||||||
.setContainerMimeType(variantFormat.containerMimeType)
|
.setContainerMimeType(variantFormat.containerMimeType)
|
||||||
.setSampleMimeType(sampleMimeType)
|
.setSampleMimeType(sampleMimeType)
|
||||||
.setCodecs(codecs)
|
.setCodecs(codecs)
|
||||||
|
@ -1583,7 +1583,7 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
|
|||||||
sampleFormat
|
sampleFormat
|
||||||
.buildUpon()
|
.buildUpon()
|
||||||
.setId(playlistFormat.id)
|
.setId(playlistFormat.id)
|
||||||
.setLabel(playlistFormat.label)
|
.setLabels(playlistFormat.labels)
|
||||||
.setLanguage(playlistFormat.language)
|
.setLanguage(playlistFormat.language)
|
||||||
.setSelectionFlags(playlistFormat.selectionFlags)
|
.setSelectionFlags(playlistFormat.selectionFlags)
|
||||||
.setRoleFlags(playlistFormat.roleFlags)
|
.setRoleFlags(playlistFormat.roleFlags)
|
||||||
|
@ -27,6 +27,7 @@ import androidx.media3.common.C;
|
|||||||
import androidx.media3.common.DrmInitData;
|
import androidx.media3.common.DrmInitData;
|
||||||
import androidx.media3.common.DrmInitData.SchemeData;
|
import androidx.media3.common.DrmInitData.SchemeData;
|
||||||
import androidx.media3.common.Format;
|
import androidx.media3.common.Format;
|
||||||
|
import androidx.media3.common.Label;
|
||||||
import androidx.media3.common.Metadata;
|
import androidx.media3.common.Metadata;
|
||||||
import androidx.media3.common.MimeTypes;
|
import androidx.media3.common.MimeTypes;
|
||||||
import androidx.media3.common.ParserException;
|
import androidx.media3.common.ParserException;
|
||||||
@ -471,10 +472,12 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli
|
|||||||
line = mediaTags.get(i);
|
line = mediaTags.get(i);
|
||||||
String groupId = parseStringAttr(line, REGEX_GROUP_ID, variableDefinitions);
|
String groupId = parseStringAttr(line, REGEX_GROUP_ID, variableDefinitions);
|
||||||
String name = parseStringAttr(line, REGEX_NAME, variableDefinitions);
|
String name = parseStringAttr(line, REGEX_NAME, variableDefinitions);
|
||||||
|
List<Label> labels = new ArrayList<>();
|
||||||
|
labels.add(new Label(null, null, name));
|
||||||
Format.Builder formatBuilder =
|
Format.Builder formatBuilder =
|
||||||
new Format.Builder()
|
new Format.Builder()
|
||||||
.setId(groupId + ":" + name)
|
.setId(groupId + ":" + name)
|
||||||
.setLabel(name)
|
.setLabels(labels)
|
||||||
.setContainerMimeType(MimeTypes.APPLICATION_M3U8)
|
.setContainerMimeType(MimeTypes.APPLICATION_M3U8)
|
||||||
.setSelectionFlags(parseSelectionFlags(line))
|
.setSelectionFlags(parseSelectionFlags(line))
|
||||||
.setRoleFlags(parseRoleFlags(line, variableDefinitions))
|
.setRoleFlags(parseRoleFlags(line, variableDefinitions))
|
||||||
|
@ -24,6 +24,7 @@ import androidx.media3.common.C;
|
|||||||
import androidx.media3.common.DrmInitData;
|
import androidx.media3.common.DrmInitData;
|
||||||
import androidx.media3.common.DrmInitData.SchemeData;
|
import androidx.media3.common.DrmInitData.SchemeData;
|
||||||
import androidx.media3.common.Format;
|
import androidx.media3.common.Format;
|
||||||
|
import androidx.media3.common.Label;
|
||||||
import androidx.media3.common.MimeTypes;
|
import androidx.media3.common.MimeTypes;
|
||||||
import androidx.media3.common.ParserException;
|
import androidx.media3.common.ParserException;
|
||||||
import androidx.media3.common.util.Assertions;
|
import androidx.media3.common.util.Assertions;
|
||||||
@ -740,10 +741,17 @@ public class SsManifestParser implements ParsingLoadable.Parser<SsManifest> {
|
|||||||
formatBuilder.setContainerMimeType(MimeTypes.APPLICATION_MP4);
|
formatBuilder.setContainerMimeType(MimeTypes.APPLICATION_MP4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
List<Label> labels = new ArrayList<>();
|
||||||
|
String label = (String) getNormalizedAttribute(KEY_NAME);
|
||||||
|
if (label != null) {
|
||||||
|
labels.add(new Label(null, null, label));
|
||||||
|
} else {
|
||||||
|
labels = null;
|
||||||
|
}
|
||||||
format =
|
format =
|
||||||
formatBuilder
|
formatBuilder
|
||||||
.setId(parser.getAttributeValue(null, KEY_INDEX))
|
.setId(parser.getAttributeValue(null, KEY_INDEX))
|
||||||
.setLabel((String) getNormalizedAttribute(KEY_NAME))
|
.setLabels(labels)
|
||||||
.setSampleMimeType(sampleMimeType)
|
.setSampleMimeType(sampleMimeType)
|
||||||
.setAverageBitrate(parseRequiredInt(parser, KEY_BITRATE))
|
.setAverageBitrate(parseRequiredInt(parser, KEY_BITRATE))
|
||||||
.setLanguage((String) getNormalizedAttribute(KEY_LANGUAGE))
|
.setLanguage((String) getNormalizedAttribute(KEY_LANGUAGE))
|
||||||
|
@ -51,6 +51,6 @@ public final class SsManifestParserTest {
|
|||||||
Uri.parse("https://example.com/test.ismc"),
|
Uri.parse("https://example.com/test.ismc"),
|
||||||
TestUtil.getInputStream(ApplicationProvider.getApplicationContext(), SAMPLE_ISMC_1));
|
TestUtil.getInputStream(ApplicationProvider.getApplicationContext(), SAMPLE_ISMC_1));
|
||||||
|
|
||||||
assertThat(ssManifest.streamElements[0].formats[0].label).isEqualTo("video");
|
assertThat(ssManifest.streamElements[0].formats[0].labels).isEqualTo("video");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,7 @@ import androidx.annotation.IntDef;
|
|||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.media3.common.C;
|
import androidx.media3.common.C;
|
||||||
import androidx.media3.common.Format;
|
import androidx.media3.common.Format;
|
||||||
|
import androidx.media3.common.Label;
|
||||||
import androidx.media3.common.MimeTypes;
|
import androidx.media3.common.MimeTypes;
|
||||||
import androidx.media3.common.ParserException;
|
import androidx.media3.common.ParserException;
|
||||||
import androidx.media3.common.util.Assertions;
|
import androidx.media3.common.util.Assertions;
|
||||||
@ -42,6 +43,7 @@ import java.lang.annotation.Retention;
|
|||||||
import java.lang.annotation.RetentionPolicy;
|
import java.lang.annotation.RetentionPolicy;
|
||||||
import java.lang.annotation.Target;
|
import java.lang.annotation.Target;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -514,7 +516,9 @@ public final class AviExtractor implements Extractor {
|
|||||||
}
|
}
|
||||||
StreamNameChunk streamName = streamList.getChild(StreamNameChunk.class);
|
StreamNameChunk streamName = streamList.getChild(StreamNameChunk.class);
|
||||||
if (streamName != null) {
|
if (streamName != null) {
|
||||||
builder.setLabel(streamName.name);
|
List<Label> labels = new ArrayList<>();
|
||||||
|
labels.add(new Label(null, null, streamName.name));
|
||||||
|
builder.setLabels(labels);
|
||||||
}
|
}
|
||||||
int trackType = MimeTypes.getTrackType(streamFormat.sampleMimeType);
|
int trackType = MimeTypes.getTrackType(streamFormat.sampleMimeType);
|
||||||
if (trackType == C.TRACK_TYPE_AUDIO || trackType == C.TRACK_TYPE_VIDEO) {
|
if (trackType == C.TRACK_TYPE_AUDIO || trackType == C.TRACK_TYPE_VIDEO) {
|
||||||
|
@ -33,6 +33,7 @@ import androidx.media3.common.ColorInfo;
|
|||||||
import androidx.media3.common.DrmInitData;
|
import androidx.media3.common.DrmInitData;
|
||||||
import androidx.media3.common.DrmInitData.SchemeData;
|
import androidx.media3.common.DrmInitData.SchemeData;
|
||||||
import androidx.media3.common.Format;
|
import androidx.media3.common.Format;
|
||||||
|
import androidx.media3.common.Label;
|
||||||
import androidx.media3.common.MimeTypes;
|
import androidx.media3.common.MimeTypes;
|
||||||
import androidx.media3.common.ParserException;
|
import androidx.media3.common.ParserException;
|
||||||
import androidx.media3.common.util.Log;
|
import androidx.media3.common.util.Log;
|
||||||
@ -2423,7 +2424,9 @@ public class MatroskaExtractor implements Extractor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (name != null && !TRACK_NAME_TO_ROTATION_DEGREES.containsKey(name)) {
|
if (name != null && !TRACK_NAME_TO_ROTATION_DEGREES.containsKey(name)) {
|
||||||
formatBuilder.setLabel(name);
|
List<Label> labels = new ArrayList<>();
|
||||||
|
labels.add(new Label(null, null, name));
|
||||||
|
formatBuilder.setLabels(labels);
|
||||||
}
|
}
|
||||||
|
|
||||||
Format format =
|
Format format =
|
||||||
|
@ -100,7 +100,7 @@ public final class DumpableFormat implements Dumper.Dumpable {
|
|||||||
DEFAULT_FORMAT,
|
DEFAULT_FORMAT,
|
||||||
format -> Util.getRoleFlagStrings(format.roleFlags));
|
format -> Util.getRoleFlagStrings(format.roleFlags));
|
||||||
addIfNonDefault(dumper, "language", format, DEFAULT_FORMAT, format -> format.language);
|
addIfNonDefault(dumper, "language", format, DEFAULT_FORMAT, format -> format.language);
|
||||||
addIfNonDefault(dumper, "label", format, DEFAULT_FORMAT, format -> format.label);
|
addIfNonDefault(dumper, "label", format, DEFAULT_FORMAT, format -> format.labels);
|
||||||
if (format.drmInitData != null) {
|
if (format.drmInitData != null) {
|
||||||
dumper.add("drmInitData", format.drmInitData.hashCode());
|
dumper.add("drmInitData", format.drmInitData.hashCode());
|
||||||
}
|
}
|
||||||
|
@ -20,11 +20,14 @@ import android.text.TextUtils;
|
|||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.media3.common.C;
|
import androidx.media3.common.C;
|
||||||
import androidx.media3.common.Format;
|
import androidx.media3.common.Format;
|
||||||
|
import androidx.media3.common.Label;
|
||||||
import androidx.media3.common.MimeTypes;
|
import androidx.media3.common.MimeTypes;
|
||||||
import androidx.media3.common.util.Assertions;
|
import androidx.media3.common.util.Assertions;
|
||||||
import androidx.media3.common.util.UnstableApi;
|
import androidx.media3.common.util.UnstableApi;
|
||||||
import androidx.media3.common.util.Util;
|
import androidx.media3.common.util.Util;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/** A default {@link TrackNameProvider}. */
|
/** A default {@link TrackNameProvider}. */
|
||||||
@UnstableApi
|
@UnstableApi
|
||||||
@ -107,7 +110,19 @@ public class DefaultTrackNameProvider implements TrackNameProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private String buildLabelString(Format format) {
|
private String buildLabelString(Format format) {
|
||||||
return TextUtils.isEmpty(format.label) ? "" : format.label;
|
if (format.labels == null || format.labels.isEmpty()) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
if (!TextUtils.isEmpty(format.language)) {
|
||||||
|
List<Label> labelsByLanguage =
|
||||||
|
format.labels.stream()
|
||||||
|
.filter(label -> format.language.equals(label.lang))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
if (!labelsByLanguage.isEmpty()) {
|
||||||
|
return labelsByLanguage.get(0).value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return TextUtils.isEmpty(format.labels.get(0).value) ? "" : format.labels.get(0).value;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String buildLanguageString(Format format) {
|
private String buildLanguageString(Format format) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user