diff --git a/library/core/src/main/java/com/google/android/exoplayer2/Format.java b/library/core/src/main/java/com/google/android/exoplayer2/Format.java index 9606d20062..8ace1ff339 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/Format.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/Format.java @@ -161,6 +161,11 @@ public final class Format implements Parcelable { /** The language, or null if unknown or not applicable. */ public final @Nullable String language; + /** + * The label, or null if unknown or not applicable. + */ + public final String label; + /** * The Accessibility channel, or {@link #NO_VALUE} if not known or applicable. */ @@ -185,7 +190,7 @@ public final class Format implements Parcelable { return new Format(id, containerMimeType, sampleMimeType, codecs, bitrate, NO_VALUE, width, height, frameRate, NO_VALUE, NO_VALUE, null, NO_VALUE, null, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, selectionFlags, null, NO_VALUE, OFFSET_SAMPLE_RELATIVE, - initializationData, null, null); + initializationData, null, null, null); } public static Format createVideoSampleFormat( @@ -240,7 +245,7 @@ public final class Format implements Parcelable { return new Format(id, null, sampleMimeType, codecs, bitrate, maxInputSize, width, height, frameRate, rotationDegrees, pixelWidthHeightRatio, projectionData, stereoMode, colorInfo, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, 0, null, NO_VALUE, - OFFSET_SAMPLE_RELATIVE, initializationData, drmInitData, null); + OFFSET_SAMPLE_RELATIVE, initializationData, drmInitData, null, null); } // Audio. @@ -255,11 +260,12 @@ public final class Format implements Parcelable { int sampleRate, List initializationData, @C.SelectionFlags int selectionFlags, - @Nullable String language) { + @Nullable String language, + @Nullable String label) { return new Format(id, containerMimeType, sampleMimeType, codecs, bitrate, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, null, NO_VALUE, null, channelCount, sampleRate, NO_VALUE, NO_VALUE, NO_VALUE, selectionFlags, language, NO_VALUE, OFFSET_SAMPLE_RELATIVE, - initializationData, null, null); + initializationData, null, null, label); } public static Format createAudioSampleFormat( @@ -315,7 +321,7 @@ public final class Format implements Parcelable { return new Format(id, null, sampleMimeType, codecs, bitrate, maxInputSize, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, null, NO_VALUE, null, channelCount, sampleRate, pcmEncoding, encoderDelay, encoderPadding, selectionFlags, language, NO_VALUE, OFFSET_SAMPLE_RELATIVE, - initializationData, drmInitData, metadata); + initializationData, drmInitData, metadata, null); } // Text. @@ -327,9 +333,10 @@ public final class Format implements Parcelable { @Nullable String codecs, int bitrate, @C.SelectionFlags int selectionFlags, - @Nullable String language) { + @Nullable String language, + @Nullable String label) { return createTextContainerFormat(id, containerMimeType, sampleMimeType, codecs, bitrate, - selectionFlags, language, NO_VALUE); + selectionFlags, language, NO_VALUE, label); } public static Format createTextContainerFormat( @@ -340,11 +347,13 @@ public final class Format implements Parcelable { int bitrate, @C.SelectionFlags int selectionFlags, @Nullable String language, - int accessibilityChannel) { + int accessibilityChannel, + @Nullable String label + ) { return new Format(id, containerMimeType, sampleMimeType, codecs, bitrate, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, null, NO_VALUE, null, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, selectionFlags, language, accessibilityChannel, - OFFSET_SAMPLE_RELATIVE, null, null, null); + OFFSET_SAMPLE_RELATIVE, null, null, null, label); } public static Format createTextSampleFormat( @@ -405,7 +414,7 @@ public final class Format implements Parcelable { return new Format(id, null, sampleMimeType, codecs, bitrate, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, null, NO_VALUE, null, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, selectionFlags, language, accessibilityChannel, subsampleOffsetUs, - initializationData, drmInitData, null); + initializationData, drmInitData, null, null); } // Image. @@ -445,7 +454,8 @@ public final class Format implements Parcelable { OFFSET_SAMPLE_RELATIVE, initializationData, drmInitData, - null); + null, + null); } // Generic. @@ -461,14 +471,14 @@ public final class Format implements Parcelable { return new Format(id, containerMimeType, sampleMimeType, codecs, bitrate, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, null, NO_VALUE, null, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, selectionFlags, language, NO_VALUE, OFFSET_SAMPLE_RELATIVE, null, null, - null); + null, null); } public static Format createSampleFormat( @Nullable String id, @Nullable String sampleMimeType, long subsampleOffsetUs) { return new Format(id, null, sampleMimeType, null, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, null, NO_VALUE, null, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, - NO_VALUE, 0, null, NO_VALUE, subsampleOffsetUs, null, null, null); + NO_VALUE, 0, null, NO_VALUE, subsampleOffsetUs, null, null, null, null); } public static Format createSampleFormat( @@ -479,7 +489,7 @@ public final class Format implements Parcelable { @Nullable DrmInitData drmInitData) { return new Format(id, null, sampleMimeType, codecs, bitrate, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, null, NO_VALUE, null, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, - NO_VALUE, 0, null, NO_VALUE, OFFSET_SAMPLE_RELATIVE, null, drmInitData, null); + NO_VALUE, 0, null, NO_VALUE, OFFSET_SAMPLE_RELATIVE, null, drmInitData, null, null); } /* package */ Format( @@ -508,7 +518,9 @@ public final class Format implements Parcelable { long subsampleOffsetUs, @Nullable List initializationData, @Nullable DrmInitData drmInitData, - @Nullable Metadata metadata) { + @Nullable Metadata metadata, + @Nullable String label + ) { this.id = id; this.containerMimeType = containerMimeType; this.sampleMimeType = sampleMimeType; @@ -531,6 +543,7 @@ public final class Format implements Parcelable { this.encoderPadding = encoderPadding == Format.NO_VALUE ? 0 : encoderPadding; this.selectionFlags = selectionFlags; this.language = language; + this.label = label; this.accessibilityChannel = accessibilityChannel; this.subsampleOffsetUs = subsampleOffsetUs; this.initializationData = initializationData == null ? Collections.emptyList() @@ -563,6 +576,7 @@ public final class Format implements Parcelable { encoderPadding = in.readInt(); selectionFlags = in.readInt(); language = in.readString(); + label = in.readString(); accessibilityChannel = in.readInt(); subsampleOffsetUs = in.readLong(); int initializationDataSize = in.readInt(); @@ -579,7 +593,7 @@ public final class Format implements Parcelable { height, frameRate, rotationDegrees, pixelWidthHeightRatio, projectionData, stereoMode, colorInfo, channelCount, sampleRate, pcmEncoding, encoderDelay, encoderPadding, selectionFlags, language, accessibilityChannel, subsampleOffsetUs, initializationData, - drmInitData, metadata); + drmInitData, metadata, label); } public Format copyWithSubsampleOffsetUs(long subsampleOffsetUs) { @@ -587,7 +601,7 @@ public final class Format implements Parcelable { height, frameRate, rotationDegrees, pixelWidthHeightRatio, projectionData, stereoMode, colorInfo, channelCount, sampleRate, pcmEncoding, encoderDelay, encoderPadding, selectionFlags, language, accessibilityChannel, subsampleOffsetUs, initializationData, - drmInitData, metadata); + drmInitData, metadata, label); } public Format copyWithContainerInfo( @@ -603,7 +617,7 @@ public final class Format implements Parcelable { height, frameRate, rotationDegrees, pixelWidthHeightRatio, projectionData, stereoMode, colorInfo, channelCount, sampleRate, pcmEncoding, encoderDelay, encoderPadding, selectionFlags, language, accessibilityChannel, subsampleOffsetUs, initializationData, - drmInitData, metadata); + drmInitData, metadata, label); } @SuppressWarnings("ReferenceEquality") @@ -618,13 +632,14 @@ public final class Format implements Parcelable { float frameRate = this.frameRate == NO_VALUE ? manifestFormat.frameRate : this.frameRate; @C.SelectionFlags int selectionFlags = this.selectionFlags | manifestFormat.selectionFlags; String language = this.language == null ? manifestFormat.language : this.language; - DrmInitData drmInitData = - DrmInitData.createSessionCreationData(manifestFormat.drmInitData, this.drmInitData); + String label = this.label == null ? manifestFormat.label : this.label; + DrmInitData drmInitData = + DrmInitData.createSessionCreationData(manifestFormat.drmInitData, this.drmInitData); return new Format(id, containerMimeType, sampleMimeType, codecs, bitrate, maxInputSize, width, height, frameRate, rotationDegrees, pixelWidthHeightRatio, projectionData, stereoMode, colorInfo, channelCount, sampleRate, pcmEncoding, encoderDelay, encoderPadding, selectionFlags, language, accessibilityChannel, subsampleOffsetUs, initializationData, - drmInitData, metadata); + drmInitData, metadata, label); } public Format copyWithGaplessInfo(int encoderDelay, int encoderPadding) { @@ -632,7 +647,7 @@ public final class Format implements Parcelable { height, frameRate, rotationDegrees, pixelWidthHeightRatio, projectionData, stereoMode, colorInfo, channelCount, sampleRate, pcmEncoding, encoderDelay, encoderPadding, selectionFlags, language, accessibilityChannel, subsampleOffsetUs, initializationData, - drmInitData, metadata); + drmInitData, metadata, label); } public Format copyWithDrmInitData(@Nullable DrmInitData drmInitData) { @@ -640,7 +655,7 @@ public final class Format implements Parcelable { height, frameRate, rotationDegrees, pixelWidthHeightRatio, projectionData, stereoMode, colorInfo, channelCount, sampleRate, pcmEncoding, encoderDelay, encoderPadding, selectionFlags, language, accessibilityChannel, subsampleOffsetUs, initializationData, - drmInitData, metadata); + drmInitData, metadata, label); } public Format copyWithMetadata(@Nullable Metadata metadata) { @@ -648,7 +663,7 @@ public final class Format implements Parcelable { height, frameRate, rotationDegrees, pixelWidthHeightRatio, projectionData, stereoMode, colorInfo, channelCount, sampleRate, pcmEncoding, encoderDelay, encoderPadding, selectionFlags, language, accessibilityChannel, subsampleOffsetUs, initializationData, - drmInitData, metadata); + drmInitData, metadata, label); } public Format copyWithRotationDegrees(int rotationDegrees) { @@ -656,7 +671,7 @@ public final class Format implements Parcelable { height, frameRate, rotationDegrees, pixelWidthHeightRatio, projectionData, stereoMode, colorInfo, channelCount, sampleRate, pcmEncoding, encoderDelay, encoderPadding, selectionFlags, language, accessibilityChannel, subsampleOffsetUs, initializationData, - drmInitData, metadata); + drmInitData, metadata, label); } /** @@ -782,6 +797,9 @@ public final class Format implements Parcelable { if (format.language != null) { builder.append(", language=").append(format.language); } + if (format.label != null) { + builder.append(", label=").append(format.label); + } return builder.toString(); } diff --git a/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/manifest/DashManifestParser.java b/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/manifest/DashManifestParser.java index 0a4274e674..223049486a 100644 --- a/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/manifest/DashManifestParser.java +++ b/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/manifest/DashManifestParser.java @@ -248,6 +248,7 @@ public class DashManifestParser extends DefaultHandler int audioSamplingRate = parseInt(xpp, "audioSamplingRate", Format.NO_VALUE); String language = xpp.getAttributeValue(null, "lang"); String drmSchemeType = null; + String label = xpp.getAttributeValue(null, "label"); ArrayList drmSchemeDatas = new ArrayList<>(); ArrayList inbandEventStreams = new ArrayList<>(); ArrayList accessibilityDescriptors = new ArrayList<>(); @@ -285,7 +286,7 @@ public class DashManifestParser extends DefaultHandler } else if (XmlPullParserUtil.isStartTag(xpp, "Representation")) { RepresentationInfo representationInfo = parseRepresentation(xpp, baseUrl, mimeType, codecs, width, height, frameRate, audioChannels, audioSamplingRate, language, - selectionFlags, accessibilityDescriptors, segmentBase); + selectionFlags, accessibilityDescriptors, segmentBase, label); contentType = checkContentTypeConsistency(contentType, getContentType(representationInfo.format)); representationInfos.add(representationInfo); @@ -451,7 +452,7 @@ public class DashManifestParser extends DefaultHandler int adaptationSetHeight, float adaptationSetFrameRate, int adaptationSetAudioChannels, int adaptationSetAudioSamplingRate, String adaptationSetLanguage, @C.SelectionFlags int adaptationSetSelectionFlags, - List adaptationSetAccessibilityDescriptors, SegmentBase segmentBase) + List adaptationSetAccessibilityDescriptors, SegmentBase segmentBase, String label) throws XmlPullParserException, IOException { String id = xpp.getAttributeValue(null, "id"); int bandwidth = parseInt(xpp, "bandwidth", Format.NO_VALUE); @@ -501,7 +502,7 @@ public class DashManifestParser extends DefaultHandler Format format = buildFormat(id, mimeType, width, height, frameRate, audioChannels, audioSamplingRate, bandwidth, adaptationSetLanguage, adaptationSetSelectionFlags, - adaptationSetAccessibilityDescriptors, codecs, supplementalProperties); + adaptationSetAccessibilityDescriptors, codecs, supplementalProperties, label); segmentBase = segmentBase != null ? segmentBase : new SingleSegmentBase(); return new RepresentationInfo(format, baseUrl, segmentBase, drmSchemeType, drmSchemeDatas, @@ -511,7 +512,7 @@ public class DashManifestParser extends DefaultHandler protected Format buildFormat(String id, String containerMimeType, int width, int height, float frameRate, int audioChannels, int audioSamplingRate, int bitrate, String language, @C.SelectionFlags int selectionFlags, List accessibilityDescriptors, - String codecs, List supplementalProperties) { + String codecs, List supplementalProperties, String label) { String sampleMimeType = getSampleMimeType(containerMimeType, codecs); if (sampleMimeType != null) { if (MimeTypes.AUDIO_E_AC3.equals(sampleMimeType)) { @@ -522,7 +523,7 @@ public class DashManifestParser extends DefaultHandler bitrate, width, height, frameRate, null, selectionFlags); } else if (MimeTypes.isAudio(sampleMimeType)) { return Format.createAudioContainerFormat(id, containerMimeType, sampleMimeType, codecs, - bitrate, audioChannels, audioSamplingRate, null, selectionFlags, language); + bitrate, audioChannels, audioSamplingRate, null, selectionFlags, language, label); } else if (mimeTypeIsRawText(sampleMimeType)) { int accessibilityChannel; if (MimeTypes.APPLICATION_CEA608.equals(sampleMimeType)) { @@ -533,7 +534,7 @@ public class DashManifestParser extends DefaultHandler accessibilityChannel = Format.NO_VALUE; } return Format.createTextContainerFormat(id, containerMimeType, sampleMimeType, codecs, - bitrate, selectionFlags, language, accessibilityChannel); + bitrate, selectionFlags, language, accessibilityChannel, label); } } return Format.createContainerFormat(id, containerMimeType, sampleMimeType, codecs, bitrate, diff --git a/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/playlist/HlsPlaylistParser.java b/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/playlist/HlsPlaylistParser.java index 7187bdb0ca..6d65c2184d 100644 --- a/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/playlist/HlsPlaylistParser.java +++ b/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/playlist/HlsPlaylistParser.java @@ -288,7 +288,7 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser(); } muxedCaptionFormats.add(Format.createTextContainerFormat(id, null, mimeType, null, - Format.NO_VALUE, selectionFlags, language, accessibilityChannel)); + Format.NO_VALUE, selectionFlags, language, accessibilityChannel, id)); break; default: // Do nothing. diff --git a/library/smoothstreaming/src/main/java/com/google/android/exoplayer2/source/smoothstreaming/manifest/SsManifestParser.java b/library/smoothstreaming/src/main/java/com/google/android/exoplayer2/source/smoothstreaming/manifest/SsManifestParser.java index 3ca5f8d997..30c082c986 100644 --- a/library/smoothstreaming/src/main/java/com/google/android/exoplayer2/source/smoothstreaming/manifest/SsManifestParser.java +++ b/library/smoothstreaming/src/main/java/com/google/android/exoplayer2/source/smoothstreaming/manifest/SsManifestParser.java @@ -603,6 +603,7 @@ public class SsManifestParser implements ParsingLoadable.Parser { private static final String KEY_FOUR_CC = "FourCC"; private static final String KEY_TYPE = "Type"; private static final String KEY_LANGUAGE = "Language"; + private static final String KEY_NAME = "Name"; private static final String KEY_MAX_WIDTH = "MaxWidth"; private static final String KEY_MAX_HEIGHT = "MaxHeight"; @@ -637,12 +638,14 @@ public class SsManifestParser implements ParsingLoadable.Parser { CodecSpecificDataUtil.buildAacLcAudioSpecificConfig(samplingRate, channels)); } String language = (String) getNormalizedAttribute(KEY_LANGUAGE); + String label = (String) getNormalizedAttribute(KEY_NAME); format = Format.createAudioContainerFormat(id, MimeTypes.AUDIO_MP4, sampleMimeType, null, - bitrate, channels, samplingRate, codecSpecificData, 0, language); + bitrate, channels, samplingRate, codecSpecificData, 0, language, label); } else if (type == C.TRACK_TYPE_TEXT) { String language = (String) getNormalizedAttribute(KEY_LANGUAGE); + String label = (String) getNormalizedAttribute(KEY_NAME); format = Format.createTextContainerFormat(id, MimeTypes.APPLICATION_MP4, sampleMimeType, - null, bitrate, 0, language); + null, bitrate, 0, language, label); } else { format = Format.createContainerFormat(id, MimeTypes.APPLICATION_MP4, sampleMimeType, null, bitrate, 0, null); diff --git a/library/ui/src/main/java/com/google/android/exoplayer2/ui/DefaultTrackNameProvider.java b/library/ui/src/main/java/com/google/android/exoplayer2/ui/DefaultTrackNameProvider.java index b36941e999..44deb8e0e8 100644 --- a/library/ui/src/main/java/com/google/android/exoplayer2/ui/DefaultTrackNameProvider.java +++ b/library/ui/src/main/java/com/google/android/exoplayer2/ui/DefaultTrackNameProvider.java @@ -88,6 +88,9 @@ public class DefaultTrackNameProvider implements TrackNameProvider { } private String buildLanguageString(Format format) { + if ( !TextUtils.isEmpty(format.label) ){ + return format.label; + } String language = format.language; return TextUtils.isEmpty(language) || C.LANGUAGE_UNDETERMINED.equals(language) ? ""