mirror of
https://github.com/samsonjs/media.git
synced 2026-04-12 12:25:47 +00:00
Introduce ChunkExtractor.Factory for dependency injection
PiperOrigin-RevId: 360175031
This commit is contained in:
parent
aa2dc4c511
commit
ef1d797681
4 changed files with 89 additions and 65 deletions
|
|
@ -29,8 +29,12 @@ import com.google.android.exoplayer2.extractor.ExtractorOutput;
|
|||
import com.google.android.exoplayer2.extractor.PositionHolder;
|
||||
import com.google.android.exoplayer2.extractor.SeekMap;
|
||||
import com.google.android.exoplayer2.extractor.TrackOutput;
|
||||
import com.google.android.exoplayer2.extractor.mkv.MatroskaExtractor;
|
||||
import com.google.android.exoplayer2.extractor.mp4.FragmentedMp4Extractor;
|
||||
import com.google.android.exoplayer2.extractor.rawcc.RawCcExtractor;
|
||||
import com.google.android.exoplayer2.upstream.DataReader;
|
||||
import com.google.android.exoplayer2.util.Assertions;
|
||||
import com.google.android.exoplayer2.util.MimeTypes;
|
||||
import com.google.android.exoplayer2.util.ParsableByteArray;
|
||||
import java.io.IOException;
|
||||
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||
|
|
@ -41,6 +45,41 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
|||
*/
|
||||
public final class BundledChunkExtractor implements ExtractorOutput, ChunkExtractor {
|
||||
|
||||
/** {@link ChunkExtractor.Factory} for instances of this class. */
|
||||
public static final ChunkExtractor.Factory FACTORY =
|
||||
(primaryTrackType,
|
||||
format,
|
||||
enableEventMessageTrack,
|
||||
closedCaptionFormats,
|
||||
playerEmsgTrackOutput) -> {
|
||||
@Nullable String containerMimeType = format.containerMimeType;
|
||||
Extractor extractor;
|
||||
if (MimeTypes.isText(containerMimeType)) {
|
||||
if (MimeTypes.APPLICATION_RAWCC.equals(containerMimeType)) {
|
||||
// RawCC is special because it's a text specific container format.
|
||||
extractor = new RawCcExtractor(format);
|
||||
} else {
|
||||
// All other text types are raw formats that do not need an extractor.
|
||||
return null;
|
||||
}
|
||||
} else if (MimeTypes.isMatroska(containerMimeType)) {
|
||||
extractor = new MatroskaExtractor(MatroskaExtractor.FLAG_DISABLE_SEEK_FOR_CUES);
|
||||
} else {
|
||||
int flags = 0;
|
||||
if (enableEventMessageTrack) {
|
||||
flags |= FragmentedMp4Extractor.FLAG_ENABLE_EMSG_TRACK;
|
||||
}
|
||||
extractor =
|
||||
new FragmentedMp4Extractor(
|
||||
flags,
|
||||
/* timestampAdjuster= */ null,
|
||||
/* sideloadedTrack= */ null,
|
||||
closedCaptionFormats,
|
||||
playerEmsgTrackOutput);
|
||||
}
|
||||
return new BundledChunkExtractor(extractor, primaryTrackType, format);
|
||||
};
|
||||
|
||||
private static final PositionHolder POSITION_HOLDER = new PositionHolder();
|
||||
|
||||
private final Extractor extractor;
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ import com.google.android.exoplayer2.extractor.ChunkIndex;
|
|||
import com.google.android.exoplayer2.extractor.ExtractorInput;
|
||||
import com.google.android.exoplayer2.extractor.TrackOutput;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Extracts samples and track {@link Format Formats} from chunks.
|
||||
|
|
@ -31,6 +32,27 @@ import java.io.IOException;
|
|||
*/
|
||||
public interface ChunkExtractor {
|
||||
|
||||
/** Creates {@link ChunkExtractor} instances. */
|
||||
interface Factory {
|
||||
|
||||
/**
|
||||
* Returns a new {@link ChunkExtractor} instance.
|
||||
*
|
||||
* @param primaryTrackType The type of the primary track. One of {@link C C.TRACK_TYPE_*}.
|
||||
* @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.
|
||||
* @return A new {@link ChunkExtractor} instance, or null if not applicable.
|
||||
*/
|
||||
@Nullable
|
||||
ChunkExtractor createProgressiveMediaExtractor(
|
||||
int primaryTrackType,
|
||||
Format representationFormat,
|
||||
boolean enableEventMessageTrack,
|
||||
List<Format> closedCaptionFormats,
|
||||
@Nullable TrackOutput playerEmsgTrackOutput);
|
||||
}
|
||||
|
||||
/** Provides {@link TrackOutput} instances to be written to during extraction. */
|
||||
interface TrackOutputProvider {
|
||||
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ import static com.google.android.exoplayer2.source.mediaparser.MediaParserUtil.P
|
|||
import android.annotation.SuppressLint;
|
||||
import android.media.MediaFormat;
|
||||
import android.media.MediaParser;
|
||||
import android.util.Log;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.RequiresApi;
|
||||
import com.google.android.exoplayer2.C;
|
||||
|
|
@ -49,6 +50,25 @@ import java.util.List;
|
|||
@RequiresApi(30)
|
||||
public final class MediaParserChunkExtractor implements ChunkExtractor {
|
||||
|
||||
// Maximum TAG length is 23 characters.
|
||||
private static final String TAG = "MediaPrsrChunkExtractor";
|
||||
|
||||
public static final ChunkExtractor.Factory FACTORY =
|
||||
(primaryTrackType,
|
||||
format,
|
||||
enableEventMessageTrack,
|
||||
closedCaptionFormats,
|
||||
playerEmsgTrackOutput) -> {
|
||||
if (!MimeTypes.isText(format.containerMimeType)) {
|
||||
// Container is either Matroska or Fragmented MP4.
|
||||
return new MediaParserChunkExtractor(primaryTrackType, format, closedCaptionFormats);
|
||||
} else {
|
||||
// This is either RAWCC (unsupported) or a text track that does not require an extractor.
|
||||
Log.w(TAG, "Ignoring an unsupported text track.");
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
private final OutputConsumerAdapterV30 outputConsumerAdapter;
|
||||
private final InputReaderAdapterV30 inputReaderAdapter;
|
||||
private final MediaParser mediaParser;
|
||||
|
|
|
|||
|
|
@ -26,11 +26,6 @@ import com.google.android.exoplayer2.C;
|
|||
import com.google.android.exoplayer2.Format;
|
||||
import com.google.android.exoplayer2.SeekParameters;
|
||||
import com.google.android.exoplayer2.extractor.ChunkIndex;
|
||||
import com.google.android.exoplayer2.extractor.Extractor;
|
||||
import com.google.android.exoplayer2.extractor.TrackOutput;
|
||||
import com.google.android.exoplayer2.extractor.mkv.MatroskaExtractor;
|
||||
import com.google.android.exoplayer2.extractor.mp4.FragmentedMp4Extractor;
|
||||
import com.google.android.exoplayer2.extractor.rawcc.RawCcExtractor;
|
||||
import com.google.android.exoplayer2.source.BehindLiveWindowException;
|
||||
import com.google.android.exoplayer2.source.chunk.BaseMediaChunkIterator;
|
||||
import com.google.android.exoplayer2.source.chunk.BundledChunkExtractor;
|
||||
|
|
@ -53,7 +48,6 @@ import com.google.android.exoplayer2.upstream.DataSpec;
|
|||
import com.google.android.exoplayer2.upstream.HttpDataSource.InvalidResponseCodeException;
|
||||
import com.google.android.exoplayer2.upstream.LoaderErrorThrower;
|
||||
import com.google.android.exoplayer2.upstream.TransferListener;
|
||||
import com.google.android.exoplayer2.util.MimeTypes;
|
||||
import com.google.android.exoplayer2.util.Util;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
|
|
@ -180,11 +174,15 @@ public class DefaultDashChunkSource implements DashChunkSource {
|
|||
representationHolders[i] =
|
||||
new RepresentationHolder(
|
||||
periodDurationUs,
|
||||
trackType,
|
||||
representation,
|
||||
enableEventMessageTrack,
|
||||
closedCaptionFormats,
|
||||
playerTrackEmsgHandler);
|
||||
BundledChunkExtractor.FACTORY.createProgressiveMediaExtractor(
|
||||
trackType,
|
||||
representation.format,
|
||||
enableEventMessageTrack,
|
||||
closedCaptionFormats,
|
||||
playerTrackEmsgHandler),
|
||||
/* segmentNumShift= */ 0,
|
||||
representation.getIndex());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -665,26 +663,6 @@ public class DefaultDashChunkSource implements DashChunkSource {
|
|||
private final long segmentNumShift;
|
||||
|
||||
/* package */ RepresentationHolder(
|
||||
long periodDurationUs,
|
||||
int trackType,
|
||||
Representation representation,
|
||||
boolean enableEventMessageTrack,
|
||||
List<Format> closedCaptionFormats,
|
||||
@Nullable TrackOutput playerEmsgTrackOutput) {
|
||||
this(
|
||||
periodDurationUs,
|
||||
representation,
|
||||
createChunkExtractor(
|
||||
trackType,
|
||||
representation,
|
||||
enableEventMessageTrack,
|
||||
closedCaptionFormats,
|
||||
playerEmsgTrackOutput),
|
||||
/* segmentNumShift= */ 0,
|
||||
representation.getIndex());
|
||||
}
|
||||
|
||||
private RepresentationHolder(
|
||||
long periodDurationUs,
|
||||
Representation representation,
|
||||
@Nullable ChunkExtractor chunkExtractor,
|
||||
|
|
@ -800,40 +778,5 @@ public class DefaultDashChunkSource implements DashChunkSource {
|
|||
public boolean isSegmentAvailableAtFullNetworkSpeed(long segmentNum, long nowPeriodTimeUs) {
|
||||
return nowPeriodTimeUs == C.TIME_UNSET || getSegmentEndTimeUs(segmentNum) <= nowPeriodTimeUs;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static ChunkExtractor createChunkExtractor(
|
||||
int trackType,
|
||||
Representation representation,
|
||||
boolean enableEventMessageTrack,
|
||||
List<Format> closedCaptionFormats,
|
||||
@Nullable TrackOutput playerEmsgTrackOutput) {
|
||||
String containerMimeType = representation.format.containerMimeType;
|
||||
Extractor extractor;
|
||||
if (MimeTypes.isText(containerMimeType)) {
|
||||
if (MimeTypes.APPLICATION_RAWCC.equals(containerMimeType)) {
|
||||
// RawCC is special because it's a text specific container format.
|
||||
extractor = new RawCcExtractor(representation.format);
|
||||
} else {
|
||||
// All other text types are raw formats that do not need an extractor.
|
||||
return null;
|
||||
}
|
||||
} else if (MimeTypes.isMatroska(containerMimeType)) {
|
||||
extractor = new MatroskaExtractor(MatroskaExtractor.FLAG_DISABLE_SEEK_FOR_CUES);
|
||||
} else {
|
||||
int flags = 0;
|
||||
if (enableEventMessageTrack) {
|
||||
flags |= FragmentedMp4Extractor.FLAG_ENABLE_EMSG_TRACK;
|
||||
}
|
||||
extractor =
|
||||
new FragmentedMp4Extractor(
|
||||
flags,
|
||||
/* timestampAdjuster= */ null,
|
||||
/* sideloadedTrack= */ null,
|
||||
closedCaptionFormats,
|
||||
playerEmsgTrackOutput);
|
||||
}
|
||||
return new BundledChunkExtractor(extractor, trackType, representation.format);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue