Add optional id to TrackGroup.
This allows to give TrackGroups an identifier. The underlying goal is to provide a way to make otherwise identical TrackGroups distinguishable. Also set this id in all internal sources that may produce identical TrackGroups in certain edge cases. Issue: google/ExoPlayer#9718 PiperOrigin-RevId: 413430719
This commit is contained in:
parent
73ed482094
commit
f1a5825d73
@ -1060,7 +1060,8 @@ public final class CastPlayer extends BasePlayer {
|
|||||||
new TracksInfo.TrackGroupInfo[castMediaTracks.size()];
|
new TracksInfo.TrackGroupInfo[castMediaTracks.size()];
|
||||||
for (int i = 0; i < castMediaTracks.size(); i++) {
|
for (int i = 0; i < castMediaTracks.size(); i++) {
|
||||||
MediaTrack mediaTrack = castMediaTracks.get(i);
|
MediaTrack mediaTrack = castMediaTracks.get(i);
|
||||||
trackGroups[i] = new TrackGroup(CastUtils.mediaTrackToFormat(mediaTrack));
|
trackGroups[i] =
|
||||||
|
new TrackGroup(/* id= */ Integer.toString(i), CastUtils.mediaTrackToFormat(mediaTrack));
|
||||||
|
|
||||||
long id = mediaTrack.getId();
|
long id = mediaTrack.getId();
|
||||||
@C.TrackType int trackType = MimeTypes.getTrackType(mediaTrack.getContentType());
|
@C.TrackType int trackType = MimeTypes.getTrackType(mediaTrack.getContentType());
|
||||||
|
@ -18,6 +18,7 @@ package androidx.media3.common;
|
|||||||
import static androidx.media3.common.util.Assertions.checkArgument;
|
import static androidx.media3.common.util.Assertions.checkArgument;
|
||||||
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import androidx.annotation.CheckResult;
|
||||||
import androidx.annotation.IntDef;
|
import androidx.annotation.IntDef;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.media3.common.util.BundleableUtil;
|
import androidx.media3.common.util.BundleableUtil;
|
||||||
@ -38,6 +39,8 @@ public final class TrackGroup implements Bundleable {
|
|||||||
|
|
||||||
/** The number of tracks in the group. */
|
/** The number of tracks in the group. */
|
||||||
public final int length;
|
public final int length;
|
||||||
|
/** An identifier for the track group. */
|
||||||
|
public final String id;
|
||||||
|
|
||||||
private final Format[] formats;
|
private final Format[] formats;
|
||||||
|
|
||||||
@ -45,18 +48,42 @@ public final class TrackGroup implements Bundleable {
|
|||||||
private int hashCode;
|
private int hashCode;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs an instance {@code TrackGroup} containing the provided {@code formats}.
|
* Constructs a track group containing the provided {@code formats}.
|
||||||
*
|
*
|
||||||
* @param formats Non empty array of format.
|
* @param formats The list of {@link Format Formats}. Must not be empty.
|
||||||
*/
|
*/
|
||||||
@UnstableApi
|
@UnstableApi
|
||||||
public TrackGroup(Format... formats) {
|
public TrackGroup(Format... formats) {
|
||||||
|
this(/* id= */ "", formats);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a track group with the provided {@code id} and {@code formats}.
|
||||||
|
*
|
||||||
|
* @param id The identifier of the track group. May be an empty string.
|
||||||
|
* @param formats The list of {@link Format Formats}. Must not be empty.
|
||||||
|
*/
|
||||||
|
@UnstableApi
|
||||||
|
public TrackGroup(String id, Format... formats) {
|
||||||
checkArgument(formats.length > 0);
|
checkArgument(formats.length > 0);
|
||||||
|
this.id = id;
|
||||||
this.formats = formats;
|
this.formats = formats;
|
||||||
this.length = formats.length;
|
this.length = formats.length;
|
||||||
verifyCorrectness();
|
verifyCorrectness();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a copy of this track group with the specified {@code id}.
|
||||||
|
*
|
||||||
|
* @param id The identifier for the copy of the track group.
|
||||||
|
* @return The copied track group.
|
||||||
|
*/
|
||||||
|
@UnstableApi
|
||||||
|
@CheckResult
|
||||||
|
public TrackGroup copyWithId(String id) {
|
||||||
|
return new TrackGroup(id, formats);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the format of the track at a given index.
|
* Returns the format of the track at a given index.
|
||||||
*
|
*
|
||||||
@ -89,6 +116,7 @@ public final class TrackGroup implements Bundleable {
|
|||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
if (hashCode == 0) {
|
if (hashCode == 0) {
|
||||||
int result = 17;
|
int result = 17;
|
||||||
|
result = 31 * result + id.hashCode();
|
||||||
result = 31 * result + Arrays.hashCode(formats);
|
result = 31 * result + Arrays.hashCode(formats);
|
||||||
hashCode = result;
|
hashCode = result;
|
||||||
}
|
}
|
||||||
@ -104,19 +132,18 @@ public final class TrackGroup implements Bundleable {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
TrackGroup other = (TrackGroup) obj;
|
TrackGroup other = (TrackGroup) obj;
|
||||||
return length == other.length && Arrays.equals(formats, other.formats);
|
return length == other.length && id.equals(other.id) && Arrays.equals(formats, other.formats);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bundleable implementation.
|
// Bundleable implementation.
|
||||||
|
|
||||||
@Documented
|
@Documented
|
||||||
@Retention(RetentionPolicy.SOURCE)
|
@Retention(RetentionPolicy.SOURCE)
|
||||||
@IntDef({
|
@IntDef({FIELD_FORMATS, FIELD_ID})
|
||||||
FIELD_FORMATS,
|
|
||||||
})
|
|
||||||
private @interface FieldNumber {}
|
private @interface FieldNumber {}
|
||||||
|
|
||||||
private static final int FIELD_FORMATS = 0;
|
private static final int FIELD_FORMATS = 0;
|
||||||
|
private static final int FIELD_ID = 1;
|
||||||
|
|
||||||
@UnstableApi
|
@UnstableApi
|
||||||
@Override
|
@Override
|
||||||
@ -124,6 +151,7 @@ public final class TrackGroup implements Bundleable {
|
|||||||
Bundle bundle = new Bundle();
|
Bundle bundle = new Bundle();
|
||||||
bundle.putParcelableArrayList(
|
bundle.putParcelableArrayList(
|
||||||
keyForField(FIELD_FORMATS), BundleableUtil.toBundleArrayList(Lists.newArrayList(formats)));
|
keyForField(FIELD_FORMATS), BundleableUtil.toBundleArrayList(Lists.newArrayList(formats)));
|
||||||
|
bundle.putString(keyForField(FIELD_ID), id);
|
||||||
return bundle;
|
return bundle;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -136,7 +164,8 @@ public final class TrackGroup implements Bundleable {
|
|||||||
Format.CREATOR,
|
Format.CREATOR,
|
||||||
bundle.getParcelableArrayList(keyForField(FIELD_FORMATS)),
|
bundle.getParcelableArrayList(keyForField(FIELD_FORMATS)),
|
||||||
ImmutableList.of());
|
ImmutableList.of());
|
||||||
return new TrackGroup(formats.toArray(new Format[0]));
|
String id = bundle.getString(keyForField(FIELD_ID), /* defaultValue= */ "");
|
||||||
|
return new TrackGroup(id, formats.toArray(new Format[0]));
|
||||||
};
|
};
|
||||||
|
|
||||||
private static String keyForField(@FieldNumber int field) {
|
private static String keyForField(@FieldNumber int field) {
|
||||||
|
@ -30,8 +30,9 @@ public final class TrackGroupTest {
|
|||||||
Format.Builder formatBuilder = new Format.Builder();
|
Format.Builder formatBuilder = new Format.Builder();
|
||||||
Format format1 = formatBuilder.setSampleMimeType(MimeTypes.VIDEO_H264).build();
|
Format format1 = formatBuilder.setSampleMimeType(MimeTypes.VIDEO_H264).build();
|
||||||
Format format2 = formatBuilder.setSampleMimeType(MimeTypes.AUDIO_AAC).build();
|
Format format2 = formatBuilder.setSampleMimeType(MimeTypes.AUDIO_AAC).build();
|
||||||
|
String id = "abc";
|
||||||
|
|
||||||
TrackGroup trackGroupToBundle = new TrackGroup(format1, format2);
|
TrackGroup trackGroupToBundle = new TrackGroup(id, format1, format2);
|
||||||
|
|
||||||
TrackGroup trackGroupFromBundle = TrackGroup.CREATOR.fromBundle(trackGroupToBundle.toBundle());
|
TrackGroup trackGroupFromBundle = TrackGroup.CREATOR.fromBundle(trackGroupToBundle.toBundle());
|
||||||
|
|
||||||
|
@ -15,10 +15,12 @@
|
|||||||
*/
|
*/
|
||||||
package androidx.media3.exoplayer.source;
|
package androidx.media3.exoplayer.source;
|
||||||
|
|
||||||
|
import static androidx.media3.common.util.Assertions.checkNotNull;
|
||||||
import static java.lang.Math.max;
|
import static java.lang.Math.max;
|
||||||
|
|
||||||
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.StreamKey;
|
import androidx.media3.common.StreamKey;
|
||||||
import androidx.media3.common.TrackGroup;
|
import androidx.media3.common.TrackGroup;
|
||||||
import androidx.media3.common.TrackGroupArray;
|
import androidx.media3.common.TrackGroupArray;
|
||||||
@ -26,10 +28,14 @@ import androidx.media3.common.util.Assertions;
|
|||||||
import androidx.media3.decoder.DecoderInputBuffer;
|
import androidx.media3.decoder.DecoderInputBuffer;
|
||||||
import androidx.media3.exoplayer.FormatHolder;
|
import androidx.media3.exoplayer.FormatHolder;
|
||||||
import androidx.media3.exoplayer.SeekParameters;
|
import androidx.media3.exoplayer.SeekParameters;
|
||||||
|
import androidx.media3.exoplayer.source.chunk.Chunk;
|
||||||
|
import androidx.media3.exoplayer.source.chunk.MediaChunk;
|
||||||
|
import androidx.media3.exoplayer.source.chunk.MediaChunkIterator;
|
||||||
import androidx.media3.exoplayer.trackselection.ExoTrackSelection;
|
import androidx.media3.exoplayer.trackselection.ExoTrackSelection;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.IdentityHashMap;
|
import java.util.IdentityHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import org.checkerframework.checker.nullness.compatqual.NullableType;
|
import org.checkerframework.checker.nullness.compatqual.NullableType;
|
||||||
@ -42,6 +48,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
|||||||
private final IdentityHashMap<SampleStream, Integer> streamPeriodIndices;
|
private final IdentityHashMap<SampleStream, Integer> streamPeriodIndices;
|
||||||
private final CompositeSequenceableLoaderFactory compositeSequenceableLoaderFactory;
|
private final CompositeSequenceableLoaderFactory compositeSequenceableLoaderFactory;
|
||||||
private final ArrayList<MediaPeriod> childrenPendingPreparation;
|
private final ArrayList<MediaPeriod> childrenPendingPreparation;
|
||||||
|
private final HashMap<TrackGroup, TrackGroup> childTrackGroupByMergedTrackGroup;
|
||||||
|
|
||||||
@Nullable private Callback callback;
|
@Nullable private Callback callback;
|
||||||
@Nullable private TrackGroupArray trackGroups;
|
@Nullable private TrackGroupArray trackGroups;
|
||||||
@ -55,6 +62,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
|||||||
this.compositeSequenceableLoaderFactory = compositeSequenceableLoaderFactory;
|
this.compositeSequenceableLoaderFactory = compositeSequenceableLoaderFactory;
|
||||||
this.periods = periods;
|
this.periods = periods;
|
||||||
childrenPendingPreparation = new ArrayList<>();
|
childrenPendingPreparation = new ArrayList<>();
|
||||||
|
childTrackGroupByMergedTrackGroup = new HashMap<>();
|
||||||
compositeSequenceableLoader =
|
compositeSequenceableLoader =
|
||||||
compositeSequenceableLoaderFactory.createCompositeSequenceableLoader();
|
compositeSequenceableLoaderFactory.createCompositeSequenceableLoader();
|
||||||
streamPeriodIndices = new IdentityHashMap<>();
|
streamPeriodIndices = new IdentityHashMap<>();
|
||||||
@ -113,9 +121,11 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
|||||||
streamChildIndices[i] = streamChildIndex == null ? C.INDEX_UNSET : streamChildIndex;
|
streamChildIndices[i] = streamChildIndex == null ? C.INDEX_UNSET : streamChildIndex;
|
||||||
selectionChildIndices[i] = C.INDEX_UNSET;
|
selectionChildIndices[i] = C.INDEX_UNSET;
|
||||||
if (selections[i] != null) {
|
if (selections[i] != null) {
|
||||||
TrackGroup trackGroup = selections[i].getTrackGroup();
|
TrackGroup mergedTrackGroup = selections[i].getTrackGroup();
|
||||||
|
TrackGroup childTrackGroup =
|
||||||
|
checkNotNull(childTrackGroupByMergedTrackGroup.get(mergedTrackGroup));
|
||||||
for (int j = 0; j < periods.length; j++) {
|
for (int j = 0; j < periods.length; j++) {
|
||||||
if (periods[j].getTrackGroups().indexOf(trackGroup) != C.INDEX_UNSET) {
|
if (periods[j].getTrackGroups().indexOf(childTrackGroup) != C.INDEX_UNSET) {
|
||||||
selectionChildIndices[i] = j;
|
selectionChildIndices[i] = j;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -131,7 +141,15 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
|||||||
for (int i = 0; i < periods.length; i++) {
|
for (int i = 0; i < periods.length; i++) {
|
||||||
for (int j = 0; j < selections.length; j++) {
|
for (int j = 0; j < selections.length; j++) {
|
||||||
childStreams[j] = streamChildIndices[j] == i ? streams[j] : null;
|
childStreams[j] = streamChildIndices[j] == i ? streams[j] : null;
|
||||||
childSelections[j] = selectionChildIndices[j] == i ? selections[j] : null;
|
if (selectionChildIndices[j] == i) {
|
||||||
|
ExoTrackSelection mergedTrackSelection = checkNotNull(selections[j]);
|
||||||
|
TrackGroup mergedTrackGroup = mergedTrackSelection.getTrackGroup();
|
||||||
|
TrackGroup childTrackGroup =
|
||||||
|
checkNotNull(childTrackGroupByMergedTrackGroup.get(mergedTrackGroup));
|
||||||
|
childSelections[j] = new ForwardingTrackSelection(mergedTrackSelection, childTrackGroup);
|
||||||
|
} else {
|
||||||
|
childSelections[j] = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
long selectPositionUs =
|
long selectPositionUs =
|
||||||
periods[i].selectTracks(
|
periods[i].selectTracks(
|
||||||
@ -270,11 +288,14 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
|||||||
}
|
}
|
||||||
TrackGroup[] trackGroupArray = new TrackGroup[totalTrackGroupCount];
|
TrackGroup[] trackGroupArray = new TrackGroup[totalTrackGroupCount];
|
||||||
int trackGroupIndex = 0;
|
int trackGroupIndex = 0;
|
||||||
for (MediaPeriod period : periods) {
|
for (int i = 0; i < periods.length; i++) {
|
||||||
TrackGroupArray periodTrackGroups = period.getTrackGroups();
|
TrackGroupArray periodTrackGroups = periods[i].getTrackGroups();
|
||||||
int periodTrackGroupCount = periodTrackGroups.length;
|
int periodTrackGroupCount = periodTrackGroups.length;
|
||||||
for (int j = 0; j < periodTrackGroupCount; j++) {
|
for (int j = 0; j < periodTrackGroupCount; j++) {
|
||||||
trackGroupArray[trackGroupIndex++] = periodTrackGroups.get(j);
|
TrackGroup childTrackGroup = periodTrackGroups.get(j);
|
||||||
|
TrackGroup mergedTrackGroup = childTrackGroup.copyWithId(i + ":" + childTrackGroup.id);
|
||||||
|
childTrackGroupByMergedTrackGroup.put(mergedTrackGroup, childTrackGroup);
|
||||||
|
trackGroupArray[trackGroupIndex++] = mergedTrackGroup;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
trackGroups = new TrackGroupArray(trackGroupArray);
|
trackGroups = new TrackGroupArray(trackGroupArray);
|
||||||
@ -455,4 +476,138 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
|||||||
return sampleStream.skipData(positionUs - timeOffsetUs);
|
return sampleStream.skipData(positionUs - timeOffsetUs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static final class ForwardingTrackSelection implements ExoTrackSelection {
|
||||||
|
|
||||||
|
private final ExoTrackSelection trackSelection;
|
||||||
|
private final TrackGroup trackGroup;
|
||||||
|
|
||||||
|
public ForwardingTrackSelection(ExoTrackSelection trackSelection, TrackGroup trackGroup) {
|
||||||
|
this.trackSelection = trackSelection;
|
||||||
|
this.trackGroup = trackGroup;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Type int getType() {
|
||||||
|
return trackSelection.getType();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TrackGroup getTrackGroup() {
|
||||||
|
return trackGroup;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int length() {
|
||||||
|
return trackSelection.length();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Format getFormat(int index) {
|
||||||
|
return trackSelection.getFormat(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getIndexInTrackGroup(int index) {
|
||||||
|
return trackSelection.getIndexInTrackGroup(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int indexOf(Format format) {
|
||||||
|
return trackSelection.indexOf(format);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int indexOf(int indexInTrackGroup) {
|
||||||
|
return trackSelection.indexOf(indexInTrackGroup);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void enable() {
|
||||||
|
trackSelection.enable();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void disable() {
|
||||||
|
trackSelection.disable();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Format getSelectedFormat() {
|
||||||
|
return trackSelection.getSelectedFormat();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getSelectedIndexInTrackGroup() {
|
||||||
|
return trackSelection.getSelectedIndexInTrackGroup();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getSelectedIndex() {
|
||||||
|
return trackSelection.getSelectedIndex();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getSelectionReason() {
|
||||||
|
return trackSelection.getSelectionReason();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public Object getSelectionData() {
|
||||||
|
return trackSelection.getSelectionData();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPlaybackSpeed(float playbackSpeed) {
|
||||||
|
trackSelection.onPlaybackSpeed(playbackSpeed);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDiscontinuity() {
|
||||||
|
trackSelection.onDiscontinuity();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onRebuffer() {
|
||||||
|
trackSelection.onRebuffer();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPlayWhenReadyChanged(boolean playWhenReady) {
|
||||||
|
trackSelection.onPlayWhenReadyChanged(playWhenReady);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateSelectedTrack(
|
||||||
|
long playbackPositionUs,
|
||||||
|
long bufferedDurationUs,
|
||||||
|
long availableDurationUs,
|
||||||
|
List<? extends MediaChunk> queue,
|
||||||
|
MediaChunkIterator[] mediaChunkIterators) {
|
||||||
|
trackSelection.updateSelectedTrack(
|
||||||
|
playbackPositionUs, bufferedDurationUs, availableDurationUs, queue, mediaChunkIterators);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int evaluateQueueSize(long playbackPositionUs, List<? extends MediaChunk> queue) {
|
||||||
|
return trackSelection.evaluateQueueSize(playbackPositionUs, queue);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean shouldCancelChunkLoad(
|
||||||
|
long playbackPositionUs, Chunk loadingChunk, List<? extends MediaChunk> queue) {
|
||||||
|
return trackSelection.shouldCancelChunkLoad(playbackPositionUs, loadingChunk, queue);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean blacklist(int index, long exclusionDurationMs) {
|
||||||
|
return trackSelection.blacklist(index, exclusionDurationMs);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isBlacklisted(int index, long nowMs) {
|
||||||
|
return trackSelection.isBlacklisted(index, nowMs);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -783,7 +783,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
trackFormat = trackFormat.copyWithCryptoType(drmSessionManager.getCryptoType(trackFormat));
|
trackFormat = trackFormat.copyWithCryptoType(drmSessionManager.getCryptoType(trackFormat));
|
||||||
trackArray[i] = new TrackGroup(trackFormat);
|
trackArray[i] = new TrackGroup(/* id= */ Integer.toString(i), trackFormat);
|
||||||
}
|
}
|
||||||
trackState = new TrackState(new TrackGroupArray(trackArray), trackIsAudioVideoFlags);
|
trackState = new TrackState(new TrackGroupArray(trackArray), trackIsAudioVideoFlags);
|
||||||
prepared = true;
|
prepared = true;
|
||||||
|
@ -277,7 +277,7 @@ public class EventLogger implements AnalyticsListener {
|
|||||||
trackGroup.length,
|
trackGroup.length,
|
||||||
mappedTrackInfo.getAdaptiveSupport(
|
mappedTrackInfo.getAdaptiveSupport(
|
||||||
rendererIndex, groupIndex, /* includeCapabilitiesExceededTracks= */ false));
|
rendererIndex, groupIndex, /* includeCapabilitiesExceededTracks= */ false));
|
||||||
logd(" Group:" + groupIndex + ", adaptive_supported=" + adaptiveSupport + " [");
|
logd(" Group:" + trackGroup.id + ", adaptive_supported=" + adaptiveSupport + " [");
|
||||||
for (int trackIndex = 0; trackIndex < trackGroup.length; trackIndex++) {
|
for (int trackIndex = 0; trackIndex < trackGroup.length; trackIndex++) {
|
||||||
String status = getTrackStatusString(trackSelection, trackGroup, trackIndex);
|
String status = getTrackStatusString(trackSelection, trackGroup, trackIndex);
|
||||||
String formatSupport =
|
String formatSupport =
|
||||||
|
@ -675,13 +675,17 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
|
|||||||
}
|
}
|
||||||
|
|
||||||
AdaptationSet firstAdaptationSet = adaptationSets.get(adaptationSetIndices[0]);
|
AdaptationSet firstAdaptationSet = adaptationSets.get(adaptationSetIndices[0]);
|
||||||
|
String trackGroupId =
|
||||||
|
firstAdaptationSet.id != AdaptationSet.ID_UNSET
|
||||||
|
? Integer.toString(firstAdaptationSet.id)
|
||||||
|
: ("unset:" + i);
|
||||||
int primaryTrackGroupIndex = trackGroupCount++;
|
int primaryTrackGroupIndex = trackGroupCount++;
|
||||||
int eventMessageTrackGroupIndex =
|
int eventMessageTrackGroupIndex =
|
||||||
primaryGroupHasEventMessageTrackFlags[i] ? trackGroupCount++ : C.INDEX_UNSET;
|
primaryGroupHasEventMessageTrackFlags[i] ? trackGroupCount++ : C.INDEX_UNSET;
|
||||||
int closedCaptionTrackGroupIndex =
|
int closedCaptionTrackGroupIndex =
|
||||||
primaryGroupClosedCaptionTrackFormats[i].length != 0 ? trackGroupCount++ : C.INDEX_UNSET;
|
primaryGroupClosedCaptionTrackFormats[i].length != 0 ? trackGroupCount++ : C.INDEX_UNSET;
|
||||||
|
|
||||||
trackGroups[primaryTrackGroupIndex] = new TrackGroup(formats);
|
trackGroups[primaryTrackGroupIndex] = new TrackGroup(trackGroupId, formats);
|
||||||
trackGroupInfos[primaryTrackGroupIndex] =
|
trackGroupInfos[primaryTrackGroupIndex] =
|
||||||
TrackGroupInfo.primaryTrack(
|
TrackGroupInfo.primaryTrack(
|
||||||
firstAdaptationSet.type,
|
firstAdaptationSet.type,
|
||||||
@ -690,18 +694,20 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
|
|||||||
eventMessageTrackGroupIndex,
|
eventMessageTrackGroupIndex,
|
||||||
closedCaptionTrackGroupIndex);
|
closedCaptionTrackGroupIndex);
|
||||||
if (eventMessageTrackGroupIndex != C.INDEX_UNSET) {
|
if (eventMessageTrackGroupIndex != C.INDEX_UNSET) {
|
||||||
|
String eventMessageTrackGroupId = trackGroupId + ":emsg";
|
||||||
Format format =
|
Format format =
|
||||||
new Format.Builder()
|
new Format.Builder()
|
||||||
.setId(firstAdaptationSet.id + ":emsg")
|
.setId(eventMessageTrackGroupId)
|
||||||
.setSampleMimeType(MimeTypes.APPLICATION_EMSG)
|
.setSampleMimeType(MimeTypes.APPLICATION_EMSG)
|
||||||
.build();
|
.build();
|
||||||
trackGroups[eventMessageTrackGroupIndex] = new TrackGroup(format);
|
trackGroups[eventMessageTrackGroupIndex] = new TrackGroup(eventMessageTrackGroupId, format);
|
||||||
trackGroupInfos[eventMessageTrackGroupIndex] =
|
trackGroupInfos[eventMessageTrackGroupIndex] =
|
||||||
TrackGroupInfo.embeddedEmsgTrack(adaptationSetIndices, primaryTrackGroupIndex);
|
TrackGroupInfo.embeddedEmsgTrack(adaptationSetIndices, primaryTrackGroupIndex);
|
||||||
}
|
}
|
||||||
if (closedCaptionTrackGroupIndex != C.INDEX_UNSET) {
|
if (closedCaptionTrackGroupIndex != C.INDEX_UNSET) {
|
||||||
|
String closedCaptionTrackGroupId = trackGroupId + ":cc";
|
||||||
trackGroups[closedCaptionTrackGroupIndex] =
|
trackGroups[closedCaptionTrackGroupIndex] =
|
||||||
new TrackGroup(primaryGroupClosedCaptionTrackFormats[i]);
|
new TrackGroup(closedCaptionTrackGroupId, primaryGroupClosedCaptionTrackFormats[i]);
|
||||||
trackGroupInfos[closedCaptionTrackGroupIndex] =
|
trackGroupInfos[closedCaptionTrackGroupIndex] =
|
||||||
TrackGroupInfo.embeddedClosedCaptionTrack(adaptationSetIndices, primaryTrackGroupIndex);
|
TrackGroupInfo.embeddedClosedCaptionTrack(adaptationSetIndices, primaryTrackGroupIndex);
|
||||||
}
|
}
|
||||||
@ -721,7 +727,8 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
|
|||||||
.setId(eventStream.id())
|
.setId(eventStream.id())
|
||||||
.setSampleMimeType(MimeTypes.APPLICATION_EMSG)
|
.setSampleMimeType(MimeTypes.APPLICATION_EMSG)
|
||||||
.build();
|
.build();
|
||||||
trackGroups[existingTrackGroupCount] = new TrackGroup(format);
|
String uniqueTrackGroupId = eventStream.id() + ":" + i;
|
||||||
|
trackGroups[existingTrackGroupCount] = new TrackGroup(uniqueTrackGroupId, format);
|
||||||
trackGroupInfos[existingTrackGroupCount++] = TrackGroupInfo.mpdEventTrack(i);
|
trackGroupInfos[existingTrackGroupCount++] = TrackGroupInfo.mpdEventTrack(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -80,12 +80,13 @@ public final class DashMediaPeriodTest {
|
|||||||
TrackGroupArray expectedTrackGroups =
|
TrackGroupArray expectedTrackGroups =
|
||||||
new TrackGroupArray(
|
new TrackGroupArray(
|
||||||
new TrackGroup(
|
new TrackGroup(
|
||||||
|
/* id= */ "0",
|
||||||
adaptationSets.get(0).representations.get(0).format,
|
adaptationSets.get(0).representations.get(0).format,
|
||||||
adaptationSets.get(0).representations.get(1).format,
|
adaptationSets.get(0).representations.get(1).format,
|
||||||
adaptationSets.get(2).representations.get(0).format,
|
adaptationSets.get(2).representations.get(0).format,
|
||||||
adaptationSets.get(2).representations.get(1).format,
|
adaptationSets.get(2).representations.get(1).format,
|
||||||
adaptationSets.get(3).representations.get(0).format),
|
adaptationSets.get(3).representations.get(0).format),
|
||||||
new TrackGroup(adaptationSets.get(1).representations.get(0).format));
|
new TrackGroup(/* id= */ "3", adaptationSets.get(1).representations.get(0).format));
|
||||||
|
|
||||||
MediaPeriodAsserts.assertTrackGroups(dashMediaPeriod, expectedTrackGroups);
|
MediaPeriodAsserts.assertTrackGroups(dashMediaPeriod, expectedTrackGroups);
|
||||||
}
|
}
|
||||||
@ -101,10 +102,12 @@ public final class DashMediaPeriodTest {
|
|||||||
TrackGroupArray expectedTrackGroups =
|
TrackGroupArray expectedTrackGroups =
|
||||||
new TrackGroupArray(
|
new TrackGroupArray(
|
||||||
new TrackGroup(
|
new TrackGroup(
|
||||||
|
/* id= */ "0",
|
||||||
adaptationSets.get(0).representations.get(0).format,
|
adaptationSets.get(0).representations.get(0).format,
|
||||||
adaptationSets.get(0).representations.get(1).format,
|
adaptationSets.get(0).representations.get(1).format,
|
||||||
adaptationSets.get(1).representations.get(0).format),
|
adaptationSets.get(1).representations.get(0).format),
|
||||||
new TrackGroup(
|
new TrackGroup(
|
||||||
|
/* id= */ "2",
|
||||||
adaptationSets.get(2).representations.get(0).format,
|
adaptationSets.get(2).representations.get(0).format,
|
||||||
adaptationSets.get(2).representations.get(1).format,
|
adaptationSets.get(2).representations.get(1).format,
|
||||||
adaptationSets.get(3).representations.get(0).format));
|
adaptationSets.get(3).representations.get(0).format));
|
||||||
@ -124,6 +127,7 @@ public final class DashMediaPeriodTest {
|
|||||||
TrackGroupArray expectedTrackGroups =
|
TrackGroupArray expectedTrackGroups =
|
||||||
new TrackGroupArray(
|
new TrackGroupArray(
|
||||||
new TrackGroup(
|
new TrackGroup(
|
||||||
|
/* id= */ "0",
|
||||||
adaptationSets.get(0).representations.get(0).format,
|
adaptationSets.get(0).representations.get(0).format,
|
||||||
adaptationSets.get(0).representations.get(1).format,
|
adaptationSets.get(0).representations.get(1).format,
|
||||||
adaptationSets.get(1).representations.get(0).format,
|
adaptationSets.get(1).representations.get(0).format,
|
||||||
@ -147,9 +151,11 @@ public final class DashMediaPeriodTest {
|
|||||||
TrackGroupArray expectedTrackGroups =
|
TrackGroupArray expectedTrackGroups =
|
||||||
new TrackGroupArray(
|
new TrackGroupArray(
|
||||||
new TrackGroup(
|
new TrackGroup(
|
||||||
|
/* id= */ "123",
|
||||||
adaptationSets.get(0).representations.get(0).format,
|
adaptationSets.get(0).representations.get(0).format,
|
||||||
adaptationSets.get(0).representations.get(1).format),
|
adaptationSets.get(0).representations.get(1).format),
|
||||||
new TrackGroup(
|
new TrackGroup(
|
||||||
|
/* id= */ "123:cc",
|
||||||
cea608FormatBuilder
|
cea608FormatBuilder
|
||||||
.setId("123:cea608:1")
|
.setId("123:cea608:1")
|
||||||
.setLanguage("eng")
|
.setLanguage("eng")
|
||||||
@ -177,9 +183,11 @@ public final class DashMediaPeriodTest {
|
|||||||
TrackGroupArray expectedTrackGroups =
|
TrackGroupArray expectedTrackGroups =
|
||||||
new TrackGroupArray(
|
new TrackGroupArray(
|
||||||
new TrackGroup(
|
new TrackGroup(
|
||||||
|
/* id= */ "123",
|
||||||
adaptationSets.get(0).representations.get(0).format,
|
adaptationSets.get(0).representations.get(0).format,
|
||||||
adaptationSets.get(0).representations.get(1).format),
|
adaptationSets.get(0).representations.get(1).format),
|
||||||
new TrackGroup(
|
new TrackGroup(
|
||||||
|
/* id= */ "123:cc",
|
||||||
cea608FormatBuilder
|
cea608FormatBuilder
|
||||||
.setId("123:cea708:1")
|
.setId("123:cea708:1")
|
||||||
.setLanguage("eng")
|
.setLanguage("eng")
|
||||||
|
@ -528,8 +528,10 @@ public final class HlsMediaPeriod
|
|||||||
// Subtitle stream wrappers. We can always use master playlist information to prepare these.
|
// Subtitle stream wrappers. We can always use master playlist information to prepare these.
|
||||||
for (int i = 0; i < subtitleRenditions.size(); i++) {
|
for (int i = 0; i < subtitleRenditions.size(); i++) {
|
||||||
Rendition subtitleRendition = subtitleRenditions.get(i);
|
Rendition subtitleRendition = subtitleRenditions.get(i);
|
||||||
|
String sampleStreamWrapperUid = "subtitle:" + i + ":" + subtitleRendition.name;
|
||||||
HlsSampleStreamWrapper sampleStreamWrapper =
|
HlsSampleStreamWrapper sampleStreamWrapper =
|
||||||
buildSampleStreamWrapper(
|
buildSampleStreamWrapper(
|
||||||
|
sampleStreamWrapperUid,
|
||||||
C.TRACK_TYPE_TEXT,
|
C.TRACK_TYPE_TEXT,
|
||||||
new Uri[] {subtitleRendition.url},
|
new Uri[] {subtitleRendition.url},
|
||||||
new Format[] {subtitleRendition.format},
|
new Format[] {subtitleRendition.format},
|
||||||
@ -540,7 +542,7 @@ public final class HlsMediaPeriod
|
|||||||
manifestUrlIndicesPerWrapper.add(new int[] {i});
|
manifestUrlIndicesPerWrapper.add(new int[] {i});
|
||||||
sampleStreamWrappers.add(sampleStreamWrapper);
|
sampleStreamWrappers.add(sampleStreamWrapper);
|
||||||
sampleStreamWrapper.prepareWithMasterPlaylistInfo(
|
sampleStreamWrapper.prepareWithMasterPlaylistInfo(
|
||||||
new TrackGroup[] {new TrackGroup(subtitleRendition.format)},
|
new TrackGroup[] {new TrackGroup(sampleStreamWrapperUid, subtitleRendition.format)},
|
||||||
/* primaryTrackGroupIndex= */ 0);
|
/* primaryTrackGroupIndex= */ 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -646,8 +648,10 @@ public final class HlsMediaPeriod
|
|||||||
!useVideoVariantsOnly && numberOfAudioCodecs > 0
|
!useVideoVariantsOnly && numberOfAudioCodecs > 0
|
||||||
? C.TRACK_TYPE_AUDIO
|
? C.TRACK_TYPE_AUDIO
|
||||||
: C.TRACK_TYPE_DEFAULT;
|
: C.TRACK_TYPE_DEFAULT;
|
||||||
|
String sampleStreamWrapperUid = "main";
|
||||||
HlsSampleStreamWrapper sampleStreamWrapper =
|
HlsSampleStreamWrapper sampleStreamWrapper =
|
||||||
buildSampleStreamWrapper(
|
buildSampleStreamWrapper(
|
||||||
|
sampleStreamWrapperUid,
|
||||||
trackType,
|
trackType,
|
||||||
selectedPlaylistUrls,
|
selectedPlaylistUrls,
|
||||||
selectedPlaylistFormats,
|
selectedPlaylistFormats,
|
||||||
@ -664,12 +668,13 @@ public final class HlsMediaPeriod
|
|||||||
for (int i = 0; i < videoFormats.length; i++) {
|
for (int i = 0; i < videoFormats.length; i++) {
|
||||||
videoFormats[i] = deriveVideoFormat(selectedPlaylistFormats[i]);
|
videoFormats[i] = deriveVideoFormat(selectedPlaylistFormats[i]);
|
||||||
}
|
}
|
||||||
muxedTrackGroups.add(new TrackGroup(videoFormats));
|
muxedTrackGroups.add(new TrackGroup(sampleStreamWrapperUid, videoFormats));
|
||||||
|
|
||||||
if (numberOfAudioCodecs > 0
|
if (numberOfAudioCodecs > 0
|
||||||
&& (masterPlaylist.muxedAudioFormat != null || masterPlaylist.audios.isEmpty())) {
|
&& (masterPlaylist.muxedAudioFormat != null || masterPlaylist.audios.isEmpty())) {
|
||||||
muxedTrackGroups.add(
|
muxedTrackGroups.add(
|
||||||
new TrackGroup(
|
new TrackGroup(
|
||||||
|
/* id= */ sampleStreamWrapperUid + ":audio",
|
||||||
deriveAudioFormat(
|
deriveAudioFormat(
|
||||||
selectedPlaylistFormats[0],
|
selectedPlaylistFormats[0],
|
||||||
masterPlaylist.muxedAudioFormat,
|
masterPlaylist.muxedAudioFormat,
|
||||||
@ -678,7 +683,8 @@ public final class HlsMediaPeriod
|
|||||||
List<Format> ccFormats = masterPlaylist.muxedCaptionFormats;
|
List<Format> ccFormats = masterPlaylist.muxedCaptionFormats;
|
||||||
if (ccFormats != null) {
|
if (ccFormats != null) {
|
||||||
for (int i = 0; i < ccFormats.size(); i++) {
|
for (int i = 0; i < ccFormats.size(); i++) {
|
||||||
muxedTrackGroups.add(new TrackGroup(ccFormats.get(i)));
|
String ccId = sampleStreamWrapperUid + ":cc:" + i;
|
||||||
|
muxedTrackGroups.add(new TrackGroup(ccId, ccFormats.get(i)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else /* numberOfAudioCodecs > 0 */ {
|
} else /* numberOfAudioCodecs > 0 */ {
|
||||||
@ -691,11 +697,12 @@ public final class HlsMediaPeriod
|
|||||||
masterPlaylist.muxedAudioFormat,
|
masterPlaylist.muxedAudioFormat,
|
||||||
/* isPrimaryTrackInVariant= */ true);
|
/* isPrimaryTrackInVariant= */ true);
|
||||||
}
|
}
|
||||||
muxedTrackGroups.add(new TrackGroup(audioFormats));
|
muxedTrackGroups.add(new TrackGroup(sampleStreamWrapperUid, audioFormats));
|
||||||
}
|
}
|
||||||
|
|
||||||
TrackGroup id3TrackGroup =
|
TrackGroup id3TrackGroup =
|
||||||
new TrackGroup(
|
new TrackGroup(
|
||||||
|
/* id= */ sampleStreamWrapperUid + ":id3",
|
||||||
new Format.Builder()
|
new Format.Builder()
|
||||||
.setId("ID3")
|
.setId("ID3")
|
||||||
.setSampleMimeType(MimeTypes.APPLICATION_ID3)
|
.setSampleMimeType(MimeTypes.APPLICATION_ID3)
|
||||||
@ -747,8 +754,10 @@ public final class HlsMediaPeriod
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String sampleStreamWrapperUid = "audio:" + name;
|
||||||
HlsSampleStreamWrapper sampleStreamWrapper =
|
HlsSampleStreamWrapper sampleStreamWrapper =
|
||||||
buildSampleStreamWrapper(
|
buildSampleStreamWrapper(
|
||||||
|
sampleStreamWrapperUid,
|
||||||
C.TRACK_TYPE_AUDIO,
|
C.TRACK_TYPE_AUDIO,
|
||||||
scratchPlaylistUrls.toArray(Util.castNonNullTypeArray(new Uri[0])),
|
scratchPlaylistUrls.toArray(Util.castNonNullTypeArray(new Uri[0])),
|
||||||
scratchPlaylistFormats.toArray(new Format[0]),
|
scratchPlaylistFormats.toArray(new Format[0]),
|
||||||
@ -762,12 +771,14 @@ public final class HlsMediaPeriod
|
|||||||
if (allowChunklessPreparation && codecStringsAllowChunklessPreparation) {
|
if (allowChunklessPreparation && codecStringsAllowChunklessPreparation) {
|
||||||
Format[] renditionFormats = scratchPlaylistFormats.toArray(new Format[0]);
|
Format[] renditionFormats = scratchPlaylistFormats.toArray(new Format[0]);
|
||||||
sampleStreamWrapper.prepareWithMasterPlaylistInfo(
|
sampleStreamWrapper.prepareWithMasterPlaylistInfo(
|
||||||
new TrackGroup[] {new TrackGroup(renditionFormats)}, /* primaryTrackGroupIndex= */ 0);
|
new TrackGroup[] {new TrackGroup(sampleStreamWrapperUid, renditionFormats)},
|
||||||
|
/* primaryTrackGroupIndex= */ 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private HlsSampleStreamWrapper buildSampleStreamWrapper(
|
private HlsSampleStreamWrapper buildSampleStreamWrapper(
|
||||||
|
String uid,
|
||||||
@C.TrackType int trackType,
|
@C.TrackType int trackType,
|
||||||
Uri[] playlistUrls,
|
Uri[] playlistUrls,
|
||||||
Format[] playlistFormats,
|
Format[] playlistFormats,
|
||||||
@ -787,6 +798,7 @@ public final class HlsMediaPeriod
|
|||||||
muxedCaptionFormats,
|
muxedCaptionFormats,
|
||||||
playerId);
|
playerId);
|
||||||
return new HlsSampleStreamWrapper(
|
return new HlsSampleStreamWrapper(
|
||||||
|
uid,
|
||||||
trackType,
|
trackType,
|
||||||
/* callback= */ this,
|
/* callback= */ this,
|
||||||
defaultChunkSource,
|
defaultChunkSource,
|
||||||
|
@ -125,6 +125,7 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
|
|||||||
new HashSet<>(
|
new HashSet<>(
|
||||||
Arrays.asList(C.TRACK_TYPE_AUDIO, C.TRACK_TYPE_VIDEO, C.TRACK_TYPE_METADATA)));
|
Arrays.asList(C.TRACK_TYPE_AUDIO, C.TRACK_TYPE_VIDEO, C.TRACK_TYPE_METADATA)));
|
||||||
|
|
||||||
|
private final String uid;
|
||||||
private final @C.TrackType int trackType;
|
private final @C.TrackType int trackType;
|
||||||
private final Callback callback;
|
private final Callback callback;
|
||||||
private final HlsChunkSource chunkSource;
|
private final HlsChunkSource chunkSource;
|
||||||
@ -185,6 +186,8 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
|
|||||||
@Nullable private HlsMediaChunk sourceChunk;
|
@Nullable private HlsMediaChunk sourceChunk;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* @param uid A identifier for this sample stream wrapper. Identifiers must be unique within the
|
||||||
|
* period.
|
||||||
* @param trackType The {@link C.TrackType track type}.
|
* @param trackType The {@link C.TrackType track type}.
|
||||||
* @param callback A callback for the wrapper.
|
* @param callback A callback for the wrapper.
|
||||||
* @param chunkSource A {@link HlsChunkSource} from which chunks to load are obtained.
|
* @param chunkSource A {@link HlsChunkSource} from which chunks to load are obtained.
|
||||||
@ -203,6 +206,7 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
|
|||||||
* events.
|
* events.
|
||||||
*/
|
*/
|
||||||
public HlsSampleStreamWrapper(
|
public HlsSampleStreamWrapper(
|
||||||
|
String uid,
|
||||||
@C.TrackType int trackType,
|
@C.TrackType int trackType,
|
||||||
Callback callback,
|
Callback callback,
|
||||||
HlsChunkSource chunkSource,
|
HlsChunkSource chunkSource,
|
||||||
@ -215,6 +219,7 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
|
|||||||
LoadErrorHandlingPolicy loadErrorHandlingPolicy,
|
LoadErrorHandlingPolicy loadErrorHandlingPolicy,
|
||||||
MediaSourceEventListener.EventDispatcher mediaSourceEventDispatcher,
|
MediaSourceEventListener.EventDispatcher mediaSourceEventDispatcher,
|
||||||
@HlsMediaSource.MetadataType int metadataType) {
|
@HlsMediaSource.MetadataType int metadataType) {
|
||||||
|
this.uid = uid;
|
||||||
this.trackType = trackType;
|
this.trackType = trackType;
|
||||||
this.callback = callback;
|
this.callback = callback;
|
||||||
this.chunkSource = chunkSource;
|
this.chunkSource = chunkSource;
|
||||||
@ -1416,7 +1421,7 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
|
|||||||
? sampleFormat.withManifestFormatInfo(playlistFormat)
|
? sampleFormat.withManifestFormatInfo(playlistFormat)
|
||||||
: deriveFormat(playlistFormat, sampleFormat, /* propagateBitrates= */ true);
|
: deriveFormat(playlistFormat, sampleFormat, /* propagateBitrates= */ true);
|
||||||
}
|
}
|
||||||
trackGroups[i] = new TrackGroup(formats);
|
trackGroups[i] = new TrackGroup(uid, formats);
|
||||||
primaryTrackGroupIndex = i;
|
primaryTrackGroupIndex = i;
|
||||||
} else {
|
} else {
|
||||||
@Nullable
|
@Nullable
|
||||||
@ -1425,8 +1430,10 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
|
|||||||
&& MimeTypes.isAudio(sampleFormat.sampleMimeType)
|
&& MimeTypes.isAudio(sampleFormat.sampleMimeType)
|
||||||
? muxedAudioFormat
|
? muxedAudioFormat
|
||||||
: null;
|
: null;
|
||||||
|
String muxedTrackGroupId = uid + ":muxed:" + (i < primaryExtractorTrackIndex ? i : i - 1);
|
||||||
trackGroups[i] =
|
trackGroups[i] =
|
||||||
new TrackGroup(
|
new TrackGroup(
|
||||||
|
muxedTrackGroupId,
|
||||||
deriveFormat(playlistFormat, sampleFormat, /* propagateBitrates= */ false));
|
deriveFormat(playlistFormat, sampleFormat, /* propagateBitrates= */ false));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1443,7 +1450,7 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
|
|||||||
Format format = trackGroup.getFormat(j);
|
Format format = trackGroup.getFormat(j);
|
||||||
exposedFormats[j] = format.copyWithCryptoType(drmSessionManager.getCryptoType(format));
|
exposedFormats[j] = format.copyWithCryptoType(drmSessionManager.getCryptoType(format));
|
||||||
}
|
}
|
||||||
trackGroups[i] = new TrackGroup(exposedFormats);
|
trackGroups[i] = new TrackGroup(trackGroup.id, exposedFormats);
|
||||||
}
|
}
|
||||||
return new TrackGroupArray(trackGroups);
|
return new TrackGroupArray(trackGroups);
|
||||||
}
|
}
|
||||||
|
@ -402,7 +402,9 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
|||||||
SampleQueue sampleQueue;
|
SampleQueue sampleQueue;
|
||||||
for (int i = 0; i < rtspLoaderWrappers.size(); i++) {
|
for (int i = 0; i < rtspLoaderWrappers.size(); i++) {
|
||||||
sampleQueue = rtspLoaderWrappers.get(i).sampleQueue;
|
sampleQueue = rtspLoaderWrappers.get(i).sampleQueue;
|
||||||
listBuilder.add(new TrackGroup(checkNotNull(sampleQueue.getUpstreamFormat())));
|
listBuilder.add(
|
||||||
|
new TrackGroup(
|
||||||
|
/* id= */ Integer.toString(i), checkNotNull(sampleQueue.getUpstreamFormat())));
|
||||||
}
|
}
|
||||||
return listBuilder.build();
|
return listBuilder.build();
|
||||||
}
|
}
|
||||||
|
@ -263,7 +263,7 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
|
|||||||
exposedFormats[j] =
|
exposedFormats[j] =
|
||||||
manifestFormat.copyWithCryptoType(drmSessionManager.getCryptoType(manifestFormat));
|
manifestFormat.copyWithCryptoType(drmSessionManager.getCryptoType(manifestFormat));
|
||||||
}
|
}
|
||||||
trackGroups[i] = new TrackGroup(exposedFormats);
|
trackGroups[i] = new TrackGroup(/* id= */ Integer.toString(i), exposedFormats);
|
||||||
}
|
}
|
||||||
return new TrackGroupArray(trackGroups);
|
return new TrackGroupArray(trackGroups);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user