Skip to content

Commit 73c0ebb

Browse files
committed
Additional clean-up and formatting
1 parent 8673e6d commit 73c0ebb

File tree

8 files changed

+145
-125
lines changed

8 files changed

+145
-125
lines changed

RELEASENOTES.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
### Unreleased changes
44

55
* Common Library:
6+
* Add `Format.labels` to allow localized or other alternative labels.
67
* ExoPlayer:
78
* Fix issue where `PreloadMediaPeriod` cannot retain the streams when it
89
is preloaded again.
@@ -100,6 +101,8 @@
100101
* RTMP Extension:
101102
* HLS Extension:
102103
* DASH Extension:
104+
* Populate all `Label` elements from the manifest into `Format.labels`
105+
([#1054](https://github.com/androidx/media/pull/1054)).
103106
* Smooth Streaming Extension:
104107
* RTSP Extension:
105108
* Skip empty session information values (i-tags) in SDP parsing

libraries/common/src/main/java/androidx/media3/common/Format.java

Lines changed: 48 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
*/
1616
package androidx.media3.common;
1717

18+
import static androidx.media3.common.util.Assertions.checkState;
1819
import static java.lang.annotation.ElementType.TYPE_USE;
1920

2021
import android.os.Bundle;
@@ -140,7 +141,7 @@ public static final class Builder {
140141

141142
@Nullable private String id;
142143
@Nullable private String label;
143-
@Nullable private List<Label> labels;
144+
private List<Label> labels;
144145
@Nullable private String language;
145146
private @C.SelectionFlags int selectionFlags;
146147
private @C.RoleFlags int roleFlags;
@@ -196,6 +197,7 @@ public static final class Builder {
196197

197198
/** Creates a new instance with default values. */
198199
public Builder() {
200+
labels = ImmutableList.of();
199201
averageBitrate = NO_VALUE;
200202
peakBitrate = NO_VALUE;
201203
// Sample specific.
@@ -298,6 +300,9 @@ public Builder setId(int id) {
298300
/**
299301
* Sets {@link Format#label}. The default value is {@code null}.
300302
*
303+
*

If both this default label and a list of {@link #setLabels labels} are set, this default

304+
* label must be part of label list.
305+
*
301306
* @param label The {@link Format#label}.
302307
* @return The builder.
303308
*/
@@ -308,14 +313,17 @@ public Builder setLabel(@Nullable String label) {
308313
}
309314

310315
/**
311-
* Sets {@link Format#labels}. The default value is {@code null}.
316+
* Sets {@link Format#labels}. The default value is an empty list.
317+
*
318+
*

If both the default {@linkplain #setLabel label} and this list are set, the default label

319+
* must be part of this list of labels.
312320
*
313321
* @param labels The {@link Format#labels}.
314322
* @return The builder.
315323
*/
316324
@CanIgnoreReturnValue
317-
public Builder setLabels(@Nullable List<Label> labels) {
318-
this.labels = labels;
325+
public Builder setLabels(List<Label> labels) {
326+
this.labels = ImmutableList.copyOf(labels);
319327
return this;
320328
}
321329

@@ -757,10 +765,20 @@ public Format build() {
757765
/** An identifier for the format, or null if unknown or not applicable. */
758766
@Nullable public final String id;
759767

760-
/** The human readable label, or null if unknown or not applicable. */
768+
/**
769+
* The default human readable label, or null if unknown or not applicable.
770+
*
771+
*

If non-null, the same label will be part of {@link #labels} too. If null, {@link #labels}

772+
* will be empty.
773+
*/
761774
@Nullable public final String label;
762775

763-
/** The human readable list of labels, or null if unknown or not applicable. */
776+
/**
777+
* The human readable list of labels, or an empty list if unknown or not applicable.
778+
*
779+
*

If non-empty, the default {@link #label} will be part of this list. If empty, the default

780+
* {@link #label} will be null.
781+
*/
764782
@UnstableApi public final List<Label> labels;
765783

766784
/** The language as an IETF BCP 47 conformant tag, or null if unknown or not applicable. */
@@ -952,17 +970,19 @@ public Format build() {
952970
private Format(Builder builder) {
953971
id = builder.id;
954972
language = Util.normalizeLanguageCode(builder.language);
955-
@Nullable String tmpLabel = builder.label;
956-
labels = builder.labels == null ? new ArrayList<>() : builder.labels;
957-
if (labels.isEmpty() && !TextUtils.isEmpty(tmpLabel)) {
958-
labels.add(new Label(language, tmpLabel));
959-
label = tmpLabel;
960-
} else if (!labels.isEmpty() && TextUtils.isEmpty(tmpLabel)) {
961-
label = getDefaultLabel(tmpLabel, labels);
973+
if (builder.labels.isEmpty() && builder.label != null) {
974+
labels = ImmutableList.of(new Label(language, builder.label));
975+
label = builder.label;
976+
} else if (!builder.labels.isEmpty() && builder.label == null) {
977+
labels = builder.labels;
978+
label = getDefaultLabel(builder.labels, language);
962979
} else {
963-
label = tmpLabel;
980+
checkState(
981+
(builder.labels.isEmpty() && builder.label == null)
982+
|| (builder.labels.stream().anyMatch(l -> l.value.equals(builder.label))));
983+
labels = builder.labels;
984+
label = builder.label;
964985
}
965-
checkLabels(label, labels);
966986
selectionFlags = builder.selectionFlags;
967987
roleFlags = builder.roleFlags;
968988
averageBitrate = builder.averageBitrate;
@@ -1010,29 +1030,6 @@ private Format(Builder builder) {
10101030
}
10111031
}
10121032

1013-
private @Nullable String getDefaultLabel(@Nullable String label, List<Label> labels) {
1014-
if (TextUtils.isEmpty(label)) {
1015-
for (Label l : labels) {
1016-
if (TextUtils.equals(l.lang, language)) {
1017-
return l.value;
1018-
}
1019-
}
1020-
if (!labels.isEmpty()) {
1021-
return labels.get(0).value;
1022-
}
1023-
}
1024-
return label;
1025-
}
1026-
1027-
private void checkLabels(@Nullable String label, List<Label> labels)
1028-
throws IllegalStateException {
1029-
if (!TextUtils.isEmpty(label)
1030-
&& !labels.isEmpty()
1031-
&& labels.stream().noneMatch(l -> TextUtils.equals(l.value, label))) {
1032-
throw new IllegalStateException();
1033-
}
1034-
}
1035-
10361033
/** Returns a {@link Format.Builder} initialized with the values of this instance. */
10371034
@UnstableApi
10381035
public Builder buildUpon() {
@@ -1056,7 +1053,7 @@ public Format withManifestFormatInfo(Format manifestFormat) {
10561053

10571054
// Prefer manifest values, but fill in from sample format if missing.
10581055
@Nullable String label = manifestFormat.label != null ? manifestFormat.label : this.label;
1059-
List<Label> labels = manifestFormat.labels;
1056+
List<Label> labels = !manifestFormat.labels.isEmpty() ? manifestFormat.labels : this.labels;
10601057
@Nullable String language = this.language;
10611058
if ((trackType == C.TRACK_TYPE_TEXT || trackType == C.TRACK_TYPE_AUDIO)
10621059
&& manifestFormat.language != null) {
@@ -1246,6 +1243,7 @@ public boolean equals(@Nullable Object obj) {
12461243
&& Float.compare(pixelWidthHeightRatio, other.pixelWidthHeightRatio) == 0
12471244
&& Util.areEqual(id, other.id)
12481245
&& Util.areEqual(label, other.label)
1246+
&& labels.equals(other.labels)
12491247
&& Util.areEqual(codecs, other.codecs)
12501248
&& Util.areEqual(containerMimeType, other.containerMimeType)
12511249
&& Util.areEqual(sampleMimeType, other.sampleMimeType)
@@ -1254,8 +1252,7 @@ public boolean equals(@Nullable Object obj) {
12541252
&& Util.areEqual(metadata, other.metadata)
12551253
&& Util.areEqual(colorInfo, other.colorInfo)
12561254
&& Util.areEqual(drmInitData, other.drmInitData)
1257-
&& initializationDataEquals(other)
1258-
&& labels.equals(other.labels);
1255+
&& initializationDataEquals(other);
12591256
}
12601257

12611258
/**
@@ -1338,7 +1335,7 @@ public static String toLogString(@Nullable Format format) {
13381335
if (format.language != null) {
13391336
builder.append(", language=").append(format.language);
13401337
}
1341-
if (format.labels.size() > 0) {
1338+
if (!format.labels.isEmpty()) {
13421339
builder.append(", labels=[");
13431340
Joiner.on(',').appendTo(builder, format.labels);
13441341
builder.append("]");
@@ -1561,4 +1558,13 @@ private static String keyForInitializationData(int initialisationDataIndex) {
15611558
private static <T> T defaultIfNull(@Nullable T value, @Nullable T defaultValue) {
15621559
return value != null ? value : defaultValue;
15631560
}
1561+
1562+
private static String getDefaultLabel(List<Label> labels, @Nullable String language) {
1563+
for (Label l : labels) {
1564+
if (TextUtils.equals(l.language, language)) {
1565+
return l.value;
1566+
}
1567+
}
1568+
return labels.get(0).value;
1569+
}
15641570
}
Lines changed: 45 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,94 +1,86 @@
1+
/*
2+
* Copyright 2024 The Android Open Source Project
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
116
package androidx.media3.common;
217

318
import static androidx.media3.common.util.Assertions.checkNotNull;
419

520
import android.os.Bundle;
6-
import android.os.Parcel;
7-
import android.os.Parcelable;
8-
import androidx.annotation.NonNull;
921
import androidx.annotation.Nullable;
1022
import androidx.media3.common.util.UnstableApi;
1123
import androidx.media3.common.util.Util;
1224

13-
/** A Label, as defined by ISO 23009-1, 4th edition, 5.3.7.2. */
25+
/** A label for a {@link Format}. */
1426
@UnstableApi
15-
public class Label implements Parcelable, Bundleable {
16-
/** Declares the language code(s) for this Label. */
17-
@Nullable public final String lang;
27+
public class Label {
28+
/**
29+
* The language of this label, as an IETF BCP 47 conformant tag, or null if unknown or not
30+
* applicable.
31+
*/
32+
@Nullable public final String language;
1833

19-
/** The value for this Label. */
34+
/** The value for this label. */
2035
public final String value;
2136

2237
/**
23-
* @param lang The lang code.
24-
* @param value The value.
38+
* Creates a label.
39+
*
40+
* @param language The language of this label, as an IETF BCP 47 conformant tag, or null if
41+
* unknown or not applicable.
42+
* @param value The label value.
2543
*/
26-
public Label(@Nullable String lang, String value) {
27-
this.lang = lang;
44+
public Label(@Nullable String language, String value) {
45+
this.language = Util.normalizeLanguageCode(language);
2846
this.value = value;
2947
}
3048

31-
/* package */ Label(Parcel in) {
32-
lang = in.readString();
33-
value = in.readString();
34-
}
35-
3649
@Override
3750
public boolean equals(@Nullable Object o) {
38-
if (this == o) return true;
39-
if (o == null || getClass() != o.getClass()) return false;
51+
if (this == o) {
52+
return true;
53+
}
54+
if (o == null || getClass() != o.getClass()) {
55+
return false;
56+
}
4057
Label label = (Label) o;
41-
return Util.areEqual(lang, label.lang) && Util.areEqual(value, label.value);
58+
return Util.areEqual(language, label.language) && Util.areEqual(value, label.value);
4259
}
4360

4461
@Override
4562
public int hashCode() {
4663
int result = value.hashCode();
47-
result = 31 * result + (lang != null ? lang.hashCode() : 0);
64+
result = 31 * result + (language != null ? language.hashCode() : 0);
4865
return result;
4966
}
5067

51-
@Override
52-
public int describeContents() {
53-
return 0;
54-
}
55-
56-
@Override
57-
public void writeToParcel(@NonNull Parcel dest, int flags) {
58-
dest.writeString(lang);
59-
dest.writeString(value);
60-
}
61-
62-
public static final Parcelable.Creator<Label> CREATOR =
63-
new Parcelable.Creator<Label>() {
64-
65-
@Override
66-
public Label createFromParcel(Parcel in) {
67-
return new Label(in);
68-
}
69-
70-
@Override
71-
public Label[] newArray(int size) {
72-
return new Label[size];
73-
}
74-
};
75-
76-
private static final String FIELD_LANG_INDEX = Util.intToStringMaxRadix(0);
68+
private static final String FIELD_LANGUAGE_INDEX = Util.intToStringMaxRadix(0);
7769
private static final String FIELD_VALUE_INDEX = Util.intToStringMaxRadix(1);
7870

79-
@Override
71+
/** Serializes this instance to a {@link Bundle}. */
8072
public Bundle toBundle() {
8173
Bundle bundle = new Bundle();
82-
bundle.putString(FIELD_LANG_INDEX, lang);
74+
if (language != null) {
75+
bundle.putString(FIELD_LANGUAGE_INDEX, language);
76+
}
8377
bundle.putString(FIELD_VALUE_INDEX, value);
8478
return bundle;
8579
}
8680

87-
/**
88-
* Constructs an instance of {@link Label} from a {@link Bundle} produced by {@link #toBundle()}.
89-
*/
81+
/** Deserializes an instance from a {@link Bundle} produced by {@link #toBundle()}. */
9082
public static Label fromBundle(Bundle bundle) {
9183
return new Label(
92-
bundle.getString(FIELD_LANG_INDEX), checkNotNull(bundle.getString(FIELD_VALUE_INDEX)));
84+
bundle.getString(FIELD_LANGUAGE_INDEX), checkNotNull(bundle.getString(FIELD_VALUE_INDEX)));
9385
}
9486
}

0 commit comments

Comments
 (0)