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,
enableEventMessageTrack,
closedCaptionFormats,
playerEmsgTrackOutput) -> {
playerEmsgTrackOutput,
playerId) -> {
@Nullable String containerMimeType = format.containerMimeType;
Extractor extractor;
if (MimeTypes.isText(containerMimeType)) {

View File

@ -19,6 +19,7 @@ import androidx.annotation.Nullable;
import androidx.media3.common.C;
import androidx.media3.common.Format;
import androidx.media3.common.util.UnstableApi;
import androidx.media3.exoplayer.analytics.PlayerId;
import androidx.media3.extractor.ChunkIndex;
import androidx.media3.extractor.ExtractorInput;
import androidx.media3.extractor.TrackOutput;
@ -44,6 +45,8 @@ public interface ChunkExtractor {
* @param representationFormat The format of the representation to extract from.
* @param enableEventMessageTrack Whether to enable the event message track.
* @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.
*/
@Nullable
@ -52,7 +55,8 @@ public interface ChunkExtractor {
Format representationFormat,
boolean enableEventMessageTrack,
List<Format> closedCaptionFormats,
@Nullable TrackOutput playerEmsgTrackOutput);
@Nullable TrackOutput playerEmsgTrackOutput,
PlayerId playerId);
}
/** 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.Log;
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.MediaParserUtil;
import androidx.media3.exoplayer.source.mediaparser.OutputConsumerAdapterV30;
@ -60,10 +62,12 @@ public final class MediaParserChunkExtractor implements ChunkExtractor {
format,
enableEventMessageTrack,
closedCaptionFormats,
playerEmsgTrackOutput) -> {
playerEmsgTrackOutput,
playerId) -> {
if (!MimeTypes.isText(format.containerMimeType)) {
// Container is either Matroska or Fragmented MP4.
return new MediaParserChunkExtractor(primaryTrackType, format, closedCaptionFormats);
return new MediaParserChunkExtractor(
primaryTrackType, format, closedCaptionFormats, playerId);
} else {
// This is either RAWCC (unsupported) or a text track that does not require an extractor.
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 closedCaptionFormats A list containing the {@link Format Formats} of the closed-caption
* tracks in the chunks.
* @param playerId The {@link PlayerId} of the player this chunk extractor is used for.
*/
@SuppressLint("WrongConstant")
public MediaParserChunkExtractor(
@C.TrackType int primaryTrackType, Format manifestFormat, List<Format> closedCaptionFormats) {
@C.TrackType int primaryTrackType,
Format manifestFormat,
List<Format> closedCaptionFormats,
PlayerId playerId) {
outputConsumerAdapter =
new OutputConsumerAdapterV30(
manifestFormat, primaryTrackType, /* expectDummySeekMap= */ true);
@ -116,6 +124,9 @@ public final class MediaParserChunkExtractor implements ChunkExtractor {
MediaParserUtil.toCaptionsMediaFormat(closedCaptionFormats.get(i)));
}
mediaParser.setParameter(PARAMETER_EXPOSE_CAPTION_FORMATS, closedCaptionMediaFormats);
if (Util.SDK_INT >= 31) {
MediaParserUtil.setLogSessionIdOnMediaParser(mediaParser, playerId);
}
outputConsumerAdapter.setMuxedCaptionFormats(closedCaptionFormats);
trackOutputProviderAdapter = new TrackOutputProviderAdapter();
dummyTrackOutput = new DummyTrackOutput();

View File

@ -21,6 +21,7 @@ import androidx.media3.common.C;
import androidx.media3.common.Format;
import androidx.media3.common.util.UnstableApi;
import androidx.media3.datasource.TransferListener;
import androidx.media3.exoplayer.analytics.PlayerId;
import androidx.media3.exoplayer.dash.PlayerEmsgHandler.PlayerTrackEmsgHandler;
import androidx.media3.exoplayer.dash.manifest.DashManifest;
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 transferListener The transfer listener which should be informed of any data transfers.
* 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}.
*/
DashChunkSource createDashChunkSource(
@ -65,7 +67,8 @@ public interface DashChunkSource extends ChunkSource {
boolean enableEventMessageTrack,
List<Format> closedCaptionFormats,
@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.datasource.TransferListener;
import androidx.media3.exoplayer.SeekParameters;
import androidx.media3.exoplayer.analytics.PlayerId;
import androidx.media3.exoplayer.dash.PlayerEmsgHandler.PlayerEmsgCallback;
import androidx.media3.exoplayer.dash.PlayerEmsgHandler.PlayerTrackEmsgHandler;
import androidx.media3.exoplayer.dash.manifest.AdaptationSet;
@ -96,6 +97,7 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
trackEmsgHandlerBySampleStream;
private final MediaSourceEventListener.EventDispatcher mediaSourceEventDispatcher;
private final DrmSessionEventListener.EventDispatcher drmEventDispatcher;
private final PlayerId playerId;
@Nullable private Callback callback;
private ChunkSampleStream<DashChunkSource>[] sampleStreams;
@ -120,7 +122,8 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
LoaderErrorThrower manifestLoaderErrorThrower,
Allocator allocator,
CompositeSequenceableLoaderFactory compositeSequenceableLoaderFactory,
PlayerEmsgCallback playerEmsgCallback) {
PlayerEmsgCallback playerEmsgCallback,
PlayerId playerId) {
this.id = id;
this.manifest = manifest;
this.baseUrlExclusionList = baseUrlExclusionList;
@ -135,6 +138,7 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
this.manifestLoaderErrorThrower = manifestLoaderErrorThrower;
this.allocator = allocator;
this.compositeSequenceableLoaderFactory = compositeSequenceableLoaderFactory;
this.playerId = playerId;
playerEmsgHandler = new PlayerEmsgHandler(manifest, playerEmsgCallback, allocator);
sampleStreams = newSampleStreamArray(0);
eventSampleStreams = new EventSampleStream[0];
@ -777,7 +781,8 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
enableEventMessageTrack,
embeddedClosedCaptionTrackFormats,
trackPlayerEmsgHandler,
transferListener);
transferListener,
playerId);
ChunkSampleStream<DashChunkSource> stream =
new ChunkSampleStream<>(
trackGroupInfo.trackType,

View File

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

View File

@ -31,6 +31,7 @@ import androidx.media3.datasource.DataSpec;
import androidx.media3.datasource.HttpDataSource.InvalidResponseCodeException;
import androidx.media3.datasource.TransferListener;
import androidx.media3.exoplayer.SeekParameters;
import androidx.media3.exoplayer.analytics.PlayerId;
import androidx.media3.exoplayer.dash.PlayerEmsgHandler.PlayerTrackEmsgHandler;
import androidx.media3.exoplayer.dash.manifest.AdaptationSet;
import androidx.media3.exoplayer.dash.manifest.BaseUrl;
@ -112,7 +113,8 @@ public class DefaultDashChunkSource implements DashChunkSource {
boolean enableEventMessageTrack,
List<Format> closedCaptionFormats,
@Nullable PlayerTrackEmsgHandler playerEmsgHandler,
@Nullable TransferListener transferListener) {
@Nullable TransferListener transferListener,
PlayerId playerId) {
DataSource dataSource = dataSourceFactory.createDataSource();
if (transferListener != null) {
dataSource.addTransferListener(transferListener);
@ -131,7 +133,8 @@ public class DefaultDashChunkSource implements DashChunkSource {
maxSegmentsPerLoad,
enableEventMessageTrack,
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 playerTrackEmsgHandler The {@link PlayerTrackEmsgHandler} instance to handle emsg
* 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(
ChunkExtractor.Factory chunkExtractorFactory,
@ -188,7 +192,8 @@ public class DefaultDashChunkSource implements DashChunkSource {
int maxSegmentsPerLoad,
boolean enableEventMessageTrack,
List<Format> closedCaptionFormats,
@Nullable PlayerTrackEmsgHandler playerTrackEmsgHandler) {
@Nullable PlayerTrackEmsgHandler playerTrackEmsgHandler,
PlayerId playerId) {
this.manifestLoaderErrorThrower = manifestLoaderErrorThrower;
this.manifest = manifest;
this.baseUrlExclusionList = baseUrlExclusionList;
@ -219,7 +224,8 @@ public class DefaultDashChunkSource implements DashChunkSource {
representation.format,
enableEventMessageTrack,
closedCaptionFormats,
playerTrackEmsgHandler),
playerTrackEmsgHandler,
playerId),
/* segmentNumShift= */ 0,
representation.getIndex());
}

View File

@ -23,6 +23,7 @@ import androidx.media3.common.MimeTypes;
import androidx.media3.common.TrackGroup;
import androidx.media3.common.TrackGroupArray;
import androidx.media3.datasource.TransferListener;
import androidx.media3.exoplayer.analytics.PlayerId;
import androidx.media3.exoplayer.dash.PlayerEmsgHandler.PlayerEmsgCallback;
import androidx.media3.exoplayer.dash.manifest.AdaptationSet;
import androidx.media3.exoplayer.dash.manifest.DashManifest;
@ -212,7 +213,8 @@ public final class DashMediaPeriodTest {
mock(LoaderErrorThrower.class),
mock(Allocator.class),
mock(CompositeSequenceableLoaderFactory.class),
mock(PlayerEmsgCallback.class));
mock(PlayerEmsgCallback.class),
PlayerId.UNSET);
}
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.datasource.DataSpec;
import androidx.media3.datasource.HttpDataSource;
import androidx.media3.exoplayer.analytics.PlayerId;
import androidx.media3.exoplayer.dash.manifest.DashManifest;
import androidx.media3.exoplayer.dash.manifest.DashManifestParser;
import androidx.media3.exoplayer.source.LoadEventInfo;
@ -95,7 +96,8 @@ public class DefaultDashChunkSourceTest {
/* maxSegmentsPerLoad= */ 1,
/* enableEventMessageTrack= */ false,
/* closedCaptionFormats */ ImmutableList.of(),
/* playerTrackEmsgHandler= */ null);
/* playerTrackEmsgHandler= */ null,
PlayerId.UNSET);
long nowInPeriodUs = Util.msToUs(nowMs - manifest.availabilityStartTimeMs);
ChunkHolder output = new ChunkHolder();
@ -143,7 +145,8 @@ public class DefaultDashChunkSourceTest {
/* maxSegmentsPerLoad= */ 1,
/* enableEventMessageTrack= */ false,
/* closedCaptionFormats */ ImmutableList.of(),
/* playerTrackEmsgHandler= */ null);
/* playerTrackEmsgHandler= */ null,
PlayerId.UNSET);
ChunkHolder output = new ChunkHolder();
chunkSource.getNextChunk(
@ -326,7 +329,8 @@ public class DefaultDashChunkSourceTest {
/* maxSegmentsPerLoad= */ 1,
/* enableEventMessageTrack= */ false,
/* closedCaptionFormats */ ImmutableList.of(),
/* playerTrackEmsgHandler= */ null);
/* playerTrackEmsgHandler= */ null,
PlayerId.UNSET);
}
private LoadErrorHandlingPolicy.LoadErrorInfo createFakeLoadErrorInfo(