Set LogSessionId on MediaParser for DASH sources.

This requires some plumbing through DashMediaPeriod and DashChunkSource.

PiperOrigin-RevId: 411012115
This commit is contained in:
tonihei 2021-11-19 10:33:51 +00:00 committed by Ian Baker
parent 74fb54a60f
commit 48118f3c87
9 changed files with 54 additions and 17 deletions

View File

@ -53,7 +53,8 @@ public final class BundledChunkExtractor implements ExtractorOutput, ChunkExtrac
format, format,
enableEventMessageTrack, enableEventMessageTrack,
closedCaptionFormats, closedCaptionFormats,
playerEmsgTrackOutput) -> { playerEmsgTrackOutput,
playerId) -> {
@Nullable String containerMimeType = format.containerMimeType; @Nullable String containerMimeType = format.containerMimeType;
Extractor extractor; Extractor extractor;
if (MimeTypes.isText(containerMimeType)) { if (MimeTypes.isText(containerMimeType)) {

View File

@ -19,6 +19,7 @@ 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.util.UnstableApi; import androidx.media3.common.util.UnstableApi;
import androidx.media3.exoplayer.analytics.PlayerId;
import androidx.media3.extractor.ChunkIndex; import androidx.media3.extractor.ChunkIndex;
import androidx.media3.extractor.ExtractorInput; import androidx.media3.extractor.ExtractorInput;
import androidx.media3.extractor.TrackOutput; import androidx.media3.extractor.TrackOutput;
@ -44,6 +45,8 @@ public interface ChunkExtractor {
* @param representationFormat The format of the representation to extract from. * @param representationFormat The format of the representation to extract from.
* @param enableEventMessageTrack Whether to enable the event message track. * @param enableEventMessageTrack Whether to enable the event message track.
* @param closedCaptionFormats The {@link Format Formats} of the Closed-Caption tracks. * @param closedCaptionFormats The {@link Format Formats} of the Closed-Caption tracks.
* @param playerEmsgTrackOutput The {@link TrackOutput} for extracted EMSG messages, or null.
* @param playerId The {@link PlayerId} of the player using this chunk extractor.
* @return A new {@link ChunkExtractor} instance, or null if not applicable. * @return A new {@link ChunkExtractor} instance, or null if not applicable.
*/ */
@Nullable @Nullable
@ -52,7 +55,8 @@ public interface ChunkExtractor {
Format representationFormat, Format representationFormat,
boolean enableEventMessageTrack, boolean enableEventMessageTrack,
List<Format> closedCaptionFormats, List<Format> closedCaptionFormats,
@Nullable TrackOutput playerEmsgTrackOutput); @Nullable TrackOutput playerEmsgTrackOutput,
PlayerId playerId);
} }
/** Provides {@link TrackOutput} instances to be written to during extraction. */ /** Provides {@link TrackOutput} instances to be written to during extraction. */

View File

@ -34,6 +34,8 @@ import androidx.media3.common.MimeTypes;
import androidx.media3.common.util.Assertions; import androidx.media3.common.util.Assertions;
import androidx.media3.common.util.Log; import androidx.media3.common.util.Log;
import androidx.media3.common.util.UnstableApi; import androidx.media3.common.util.UnstableApi;
import androidx.media3.common.util.Util;
import androidx.media3.exoplayer.analytics.PlayerId;
import androidx.media3.exoplayer.source.mediaparser.InputReaderAdapterV30; import androidx.media3.exoplayer.source.mediaparser.InputReaderAdapterV30;
import androidx.media3.exoplayer.source.mediaparser.MediaParserUtil; import androidx.media3.exoplayer.source.mediaparser.MediaParserUtil;
import androidx.media3.exoplayer.source.mediaparser.OutputConsumerAdapterV30; import androidx.media3.exoplayer.source.mediaparser.OutputConsumerAdapterV30;
@ -60,10 +62,12 @@ public final class MediaParserChunkExtractor implements ChunkExtractor {
format, format,
enableEventMessageTrack, enableEventMessageTrack,
closedCaptionFormats, closedCaptionFormats,
playerEmsgTrackOutput) -> { playerEmsgTrackOutput,
playerId) -> {
if (!MimeTypes.isText(format.containerMimeType)) { if (!MimeTypes.isText(format.containerMimeType)) {
// Container is either Matroska or Fragmented MP4. // Container is either Matroska or Fragmented MP4.
return new MediaParserChunkExtractor(primaryTrackType, format, closedCaptionFormats); return new MediaParserChunkExtractor(
primaryTrackType, format, closedCaptionFormats, playerId);
} else { } else {
// This is either RAWCC (unsupported) or a text track that does not require an extractor. // This is either RAWCC (unsupported) or a text track that does not require an extractor.
Log.w(TAG, "Ignoring an unsupported text track."); Log.w(TAG, "Ignoring an unsupported text track.");
@ -88,10 +92,14 @@ public final class MediaParserChunkExtractor implements ChunkExtractor {
* @param manifestFormat The chunks {@link Format} as obtained from the manifest. * @param manifestFormat The chunks {@link Format} as obtained from the manifest.
* @param closedCaptionFormats A list containing the {@link Format Formats} of the closed-caption * @param closedCaptionFormats A list containing the {@link Format Formats} of the closed-caption
* tracks in the chunks. * tracks in the chunks.
* @param playerId The {@link PlayerId} of the player this chunk extractor is used for.
*/ */
@SuppressLint("WrongConstant") @SuppressLint("WrongConstant")
public MediaParserChunkExtractor( public MediaParserChunkExtractor(
@C.TrackType int primaryTrackType, Format manifestFormat, List<Format> closedCaptionFormats) { @C.TrackType int primaryTrackType,
Format manifestFormat,
List<Format> closedCaptionFormats,
PlayerId playerId) {
outputConsumerAdapter = outputConsumerAdapter =
new OutputConsumerAdapterV30( new OutputConsumerAdapterV30(
manifestFormat, primaryTrackType, /* expectDummySeekMap= */ true); manifestFormat, primaryTrackType, /* expectDummySeekMap= */ true);
@ -116,6 +124,9 @@ public final class MediaParserChunkExtractor implements ChunkExtractor {
MediaParserUtil.toCaptionsMediaFormat(closedCaptionFormats.get(i))); MediaParserUtil.toCaptionsMediaFormat(closedCaptionFormats.get(i)));
} }
mediaParser.setParameter(PARAMETER_EXPOSE_CAPTION_FORMATS, closedCaptionMediaFormats); mediaParser.setParameter(PARAMETER_EXPOSE_CAPTION_FORMATS, closedCaptionMediaFormats);
if (Util.SDK_INT >= 31) {
MediaParserUtil.setLogSessionIdOnMediaParser(mediaParser, playerId);
}
outputConsumerAdapter.setMuxedCaptionFormats(closedCaptionFormats); outputConsumerAdapter.setMuxedCaptionFormats(closedCaptionFormats);
trackOutputProviderAdapter = new TrackOutputProviderAdapter(); trackOutputProviderAdapter = new TrackOutputProviderAdapter();
dummyTrackOutput = new DummyTrackOutput(); dummyTrackOutput = new DummyTrackOutput();

View File

@ -21,6 +21,7 @@ import androidx.media3.common.C;
import androidx.media3.common.Format; import androidx.media3.common.Format;
import androidx.media3.common.util.UnstableApi; import androidx.media3.common.util.UnstableApi;
import androidx.media3.datasource.TransferListener; import androidx.media3.datasource.TransferListener;
import androidx.media3.exoplayer.analytics.PlayerId;
import androidx.media3.exoplayer.dash.PlayerEmsgHandler.PlayerTrackEmsgHandler; import androidx.media3.exoplayer.dash.PlayerEmsgHandler.PlayerTrackEmsgHandler;
import androidx.media3.exoplayer.dash.manifest.DashManifest; import androidx.media3.exoplayer.dash.manifest.DashManifest;
import androidx.media3.exoplayer.source.chunk.ChunkSource; import androidx.media3.exoplayer.source.chunk.ChunkSource;
@ -51,6 +52,7 @@ public interface DashChunkSource extends ChunkSource {
* @param closedCaptionFormats The {@link Format Formats} of closed caption tracks to be output. * @param closedCaptionFormats The {@link Format Formats} of closed caption tracks to be output.
* @param transferListener The transfer listener which should be informed of any data transfers. * @param transferListener The transfer listener which should be informed of any data transfers.
* May be null if no listener is available. * May be null if no listener is available.
* @param playerId The {@link PlayerId} of the player using this chunk source.
* @return The created {@link DashChunkSource}. * @return The created {@link DashChunkSource}.
*/ */
DashChunkSource createDashChunkSource( DashChunkSource createDashChunkSource(
@ -65,7 +67,8 @@ public interface DashChunkSource extends ChunkSource {
boolean enableEventMessageTrack, boolean enableEventMessageTrack,
List<Format> closedCaptionFormats, List<Format> closedCaptionFormats,
@Nullable PlayerTrackEmsgHandler playerEmsgHandler, @Nullable PlayerTrackEmsgHandler playerEmsgHandler,
@Nullable TransferListener transferListener); @Nullable TransferListener transferListener,
PlayerId playerId);
} }
/** /**

View File

@ -31,6 +31,7 @@ import androidx.media3.common.TrackGroupArray;
import androidx.media3.common.util.Util; import androidx.media3.common.util.Util;
import androidx.media3.datasource.TransferListener; import androidx.media3.datasource.TransferListener;
import androidx.media3.exoplayer.SeekParameters; import androidx.media3.exoplayer.SeekParameters;
import androidx.media3.exoplayer.analytics.PlayerId;
import androidx.media3.exoplayer.dash.PlayerEmsgHandler.PlayerEmsgCallback; import androidx.media3.exoplayer.dash.PlayerEmsgHandler.PlayerEmsgCallback;
import androidx.media3.exoplayer.dash.PlayerEmsgHandler.PlayerTrackEmsgHandler; import androidx.media3.exoplayer.dash.PlayerEmsgHandler.PlayerTrackEmsgHandler;
import androidx.media3.exoplayer.dash.manifest.AdaptationSet; import androidx.media3.exoplayer.dash.manifest.AdaptationSet;
@ -96,6 +97,7 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
trackEmsgHandlerBySampleStream; trackEmsgHandlerBySampleStream;
private final MediaSourceEventListener.EventDispatcher mediaSourceEventDispatcher; private final MediaSourceEventListener.EventDispatcher mediaSourceEventDispatcher;
private final DrmSessionEventListener.EventDispatcher drmEventDispatcher; private final DrmSessionEventListener.EventDispatcher drmEventDispatcher;
private final PlayerId playerId;
@Nullable private Callback callback; @Nullable private Callback callback;
private ChunkSampleStream<DashChunkSource>[] sampleStreams; private ChunkSampleStream<DashChunkSource>[] sampleStreams;
@ -120,7 +122,8 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
LoaderErrorThrower manifestLoaderErrorThrower, LoaderErrorThrower manifestLoaderErrorThrower,
Allocator allocator, Allocator allocator,
CompositeSequenceableLoaderFactory compositeSequenceableLoaderFactory, CompositeSequenceableLoaderFactory compositeSequenceableLoaderFactory,
PlayerEmsgCallback playerEmsgCallback) { PlayerEmsgCallback playerEmsgCallback,
PlayerId playerId) {
this.id = id; this.id = id;
this.manifest = manifest; this.manifest = manifest;
this.baseUrlExclusionList = baseUrlExclusionList; this.baseUrlExclusionList = baseUrlExclusionList;
@ -135,6 +138,7 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
this.manifestLoaderErrorThrower = manifestLoaderErrorThrower; this.manifestLoaderErrorThrower = manifestLoaderErrorThrower;
this.allocator = allocator; this.allocator = allocator;
this.compositeSequenceableLoaderFactory = compositeSequenceableLoaderFactory; this.compositeSequenceableLoaderFactory = compositeSequenceableLoaderFactory;
this.playerId = playerId;
playerEmsgHandler = new PlayerEmsgHandler(manifest, playerEmsgCallback, allocator); playerEmsgHandler = new PlayerEmsgHandler(manifest, playerEmsgCallback, allocator);
sampleStreams = newSampleStreamArray(0); sampleStreams = newSampleStreamArray(0);
eventSampleStreams = new EventSampleStream[0]; eventSampleStreams = new EventSampleStream[0];
@ -777,7 +781,8 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
enableEventMessageTrack, enableEventMessageTrack,
embeddedClosedCaptionTrackFormats, embeddedClosedCaptionTrackFormats,
trackPlayerEmsgHandler, trackPlayerEmsgHandler,
transferListener); transferListener,
playerId);
ChunkSampleStream<DashChunkSource> stream = ChunkSampleStream<DashChunkSource> stream =
new ChunkSampleStream<>( new ChunkSampleStream<>(
trackGroupInfo.trackType, trackGroupInfo.trackType,

View File

@ -600,7 +600,8 @@ public final class DashMediaSource extends BaseMediaSource {
manifestLoadErrorThrower, manifestLoadErrorThrower,
allocator, allocator,
compositeSequenceableLoaderFactory, compositeSequenceableLoaderFactory,
playerEmsgCallback); playerEmsgCallback,
getPlayerId());
periodsById.put(mediaPeriod.id, mediaPeriod); periodsById.put(mediaPeriod.id, mediaPeriod);
return mediaPeriod; return mediaPeriod;
} }

View File

@ -31,6 +31,7 @@ import androidx.media3.datasource.DataSpec;
import androidx.media3.datasource.HttpDataSource.InvalidResponseCodeException; import androidx.media3.datasource.HttpDataSource.InvalidResponseCodeException;
import androidx.media3.datasource.TransferListener; import androidx.media3.datasource.TransferListener;
import androidx.media3.exoplayer.SeekParameters; import androidx.media3.exoplayer.SeekParameters;
import androidx.media3.exoplayer.analytics.PlayerId;
import androidx.media3.exoplayer.dash.PlayerEmsgHandler.PlayerTrackEmsgHandler; import androidx.media3.exoplayer.dash.PlayerEmsgHandler.PlayerTrackEmsgHandler;
import androidx.media3.exoplayer.dash.manifest.AdaptationSet; import androidx.media3.exoplayer.dash.manifest.AdaptationSet;
import androidx.media3.exoplayer.dash.manifest.BaseUrl; import androidx.media3.exoplayer.dash.manifest.BaseUrl;
@ -112,7 +113,8 @@ public class DefaultDashChunkSource implements DashChunkSource {
boolean enableEventMessageTrack, boolean enableEventMessageTrack,
List<Format> closedCaptionFormats, List<Format> closedCaptionFormats,
@Nullable PlayerTrackEmsgHandler playerEmsgHandler, @Nullable PlayerTrackEmsgHandler playerEmsgHandler,
@Nullable TransferListener transferListener) { @Nullable TransferListener transferListener,
PlayerId playerId) {
DataSource dataSource = dataSourceFactory.createDataSource(); DataSource dataSource = dataSourceFactory.createDataSource();
if (transferListener != null) { if (transferListener != null) {
dataSource.addTransferListener(transferListener); dataSource.addTransferListener(transferListener);
@ -131,7 +133,8 @@ public class DefaultDashChunkSource implements DashChunkSource {
maxSegmentsPerLoad, maxSegmentsPerLoad,
enableEventMessageTrack, enableEventMessageTrack,
closedCaptionFormats, closedCaptionFormats,
playerEmsgHandler); playerEmsgHandler,
playerId);
} }
} }
@ -173,6 +176,7 @@ public class DefaultDashChunkSource implements DashChunkSource {
* @param closedCaptionFormats The {@link Format Formats} of closed caption tracks to be output. * @param closedCaptionFormats The {@link Format Formats} of closed caption tracks to be output.
* @param playerTrackEmsgHandler The {@link PlayerTrackEmsgHandler} instance to handle emsg * @param playerTrackEmsgHandler The {@link PlayerTrackEmsgHandler} instance to handle emsg
* messages targeting the player. Maybe null if this is not necessary. * messages targeting the player. Maybe null if this is not necessary.
* @param playerId The {@link PlayerId} of the player using this chunk source.
*/ */
public DefaultDashChunkSource( public DefaultDashChunkSource(
ChunkExtractor.Factory chunkExtractorFactory, ChunkExtractor.Factory chunkExtractorFactory,
@ -188,7 +192,8 @@ public class DefaultDashChunkSource implements DashChunkSource {
int maxSegmentsPerLoad, int maxSegmentsPerLoad,
boolean enableEventMessageTrack, boolean enableEventMessageTrack,
List<Format> closedCaptionFormats, List<Format> closedCaptionFormats,
@Nullable PlayerTrackEmsgHandler playerTrackEmsgHandler) { @Nullable PlayerTrackEmsgHandler playerTrackEmsgHandler,
PlayerId playerId) {
this.manifestLoaderErrorThrower = manifestLoaderErrorThrower; this.manifestLoaderErrorThrower = manifestLoaderErrorThrower;
this.manifest = manifest; this.manifest = manifest;
this.baseUrlExclusionList = baseUrlExclusionList; this.baseUrlExclusionList = baseUrlExclusionList;
@ -219,7 +224,8 @@ public class DefaultDashChunkSource implements DashChunkSource {
representation.format, representation.format,
enableEventMessageTrack, enableEventMessageTrack,
closedCaptionFormats, closedCaptionFormats,
playerTrackEmsgHandler), playerTrackEmsgHandler,
playerId),
/* segmentNumShift= */ 0, /* segmentNumShift= */ 0,
representation.getIndex()); representation.getIndex());
} }

View File

@ -23,6 +23,7 @@ import androidx.media3.common.MimeTypes;
import androidx.media3.common.TrackGroup; import androidx.media3.common.TrackGroup;
import androidx.media3.common.TrackGroupArray; import androidx.media3.common.TrackGroupArray;
import androidx.media3.datasource.TransferListener; import androidx.media3.datasource.TransferListener;
import androidx.media3.exoplayer.analytics.PlayerId;
import androidx.media3.exoplayer.dash.PlayerEmsgHandler.PlayerEmsgCallback; import androidx.media3.exoplayer.dash.PlayerEmsgHandler.PlayerEmsgCallback;
import androidx.media3.exoplayer.dash.manifest.AdaptationSet; import androidx.media3.exoplayer.dash.manifest.AdaptationSet;
import androidx.media3.exoplayer.dash.manifest.DashManifest; import androidx.media3.exoplayer.dash.manifest.DashManifest;
@ -212,7 +213,8 @@ public final class DashMediaPeriodTest {
mock(LoaderErrorThrower.class), mock(LoaderErrorThrower.class),
mock(Allocator.class), mock(Allocator.class),
mock(CompositeSequenceableLoaderFactory.class), mock(CompositeSequenceableLoaderFactory.class),
mock(PlayerEmsgCallback.class)); mock(PlayerEmsgCallback.class),
PlayerId.UNSET);
} }
private static DashManifest parseManifest(String fileName) throws IOException { private static DashManifest parseManifest(String fileName) throws IOException {

View File

@ -29,6 +29,7 @@ import androidx.media3.common.util.Assertions;
import androidx.media3.common.util.Util; import androidx.media3.common.util.Util;
import androidx.media3.datasource.DataSpec; import androidx.media3.datasource.DataSpec;
import androidx.media3.datasource.HttpDataSource; import androidx.media3.datasource.HttpDataSource;
import androidx.media3.exoplayer.analytics.PlayerId;
import androidx.media3.exoplayer.dash.manifest.DashManifest; import androidx.media3.exoplayer.dash.manifest.DashManifest;
import androidx.media3.exoplayer.dash.manifest.DashManifestParser; import androidx.media3.exoplayer.dash.manifest.DashManifestParser;
import androidx.media3.exoplayer.source.LoadEventInfo; import androidx.media3.exoplayer.source.LoadEventInfo;
@ -95,7 +96,8 @@ public class DefaultDashChunkSourceTest {
/* maxSegmentsPerLoad= */ 1, /* maxSegmentsPerLoad= */ 1,
/* enableEventMessageTrack= */ false, /* enableEventMessageTrack= */ false,
/* closedCaptionFormats */ ImmutableList.of(), /* closedCaptionFormats */ ImmutableList.of(),
/* playerTrackEmsgHandler= */ null); /* playerTrackEmsgHandler= */ null,
PlayerId.UNSET);
long nowInPeriodUs = Util.msToUs(nowMs - manifest.availabilityStartTimeMs); long nowInPeriodUs = Util.msToUs(nowMs - manifest.availabilityStartTimeMs);
ChunkHolder output = new ChunkHolder(); ChunkHolder output = new ChunkHolder();
@ -143,7 +145,8 @@ public class DefaultDashChunkSourceTest {
/* maxSegmentsPerLoad= */ 1, /* maxSegmentsPerLoad= */ 1,
/* enableEventMessageTrack= */ false, /* enableEventMessageTrack= */ false,
/* closedCaptionFormats */ ImmutableList.of(), /* closedCaptionFormats */ ImmutableList.of(),
/* playerTrackEmsgHandler= */ null); /* playerTrackEmsgHandler= */ null,
PlayerId.UNSET);
ChunkHolder output = new ChunkHolder(); ChunkHolder output = new ChunkHolder();
chunkSource.getNextChunk( chunkSource.getNextChunk(
@ -326,7 +329,8 @@ public class DefaultDashChunkSourceTest {
/* maxSegmentsPerLoad= */ 1, /* maxSegmentsPerLoad= */ 1,
/* enableEventMessageTrack= */ false, /* enableEventMessageTrack= */ false,
/* closedCaptionFormats */ ImmutableList.of(), /* closedCaptionFormats */ ImmutableList.of(),
/* playerTrackEmsgHandler= */ null); /* playerTrackEmsgHandler= */ null,
PlayerId.UNSET);
} }
private LoadErrorHandlingPolicy.LoadErrorInfo createFakeLoadErrorInfo( private LoadErrorHandlingPolicy.LoadErrorInfo createFakeLoadErrorInfo(