mirror of
https://github.com/androidx/media.git
synced 2025-05-11 09:39:52 +08:00
Update SubtitleExtractor
to use SubtitleParser
directly
`SubtitleExtractor` used to rely on a `SubtitleDecoder`. However, now all SubtitleDecoders that are used for side-loaded subtitles have been migrated to a `SubtitleParser` interface. We can therefore refactor the extractor. The `SubtitleExtractor` is only used for side-loaded subtitles which means we do not require the migration of the CEA-608/708 `SubtitleDecoders`. PiperOrigin-RevId: 552471710
This commit is contained in:
parent
9e975b25d1
commit
b8e6f27caf
@ -38,7 +38,6 @@ import androidx.media3.datasource.DefaultDataSource;
|
|||||||
import androidx.media3.exoplayer.drm.DrmSessionManagerProvider;
|
import androidx.media3.exoplayer.drm.DrmSessionManagerProvider;
|
||||||
import androidx.media3.exoplayer.source.ads.AdsLoader;
|
import androidx.media3.exoplayer.source.ads.AdsLoader;
|
||||||
import androidx.media3.exoplayer.source.ads.AdsMediaSource;
|
import androidx.media3.exoplayer.source.ads.AdsMediaSource;
|
||||||
import androidx.media3.exoplayer.text.SubtitleDecoderFactory;
|
|
||||||
import androidx.media3.exoplayer.upstream.CmcdConfiguration;
|
import androidx.media3.exoplayer.upstream.CmcdConfiguration;
|
||||||
import androidx.media3.exoplayer.upstream.LoadErrorHandlingPolicy;
|
import androidx.media3.exoplayer.upstream.LoadErrorHandlingPolicy;
|
||||||
import androidx.media3.extractor.DefaultExtractorsFactory;
|
import androidx.media3.extractor.DefaultExtractorsFactory;
|
||||||
@ -49,6 +48,7 @@ import androidx.media3.extractor.ExtractorsFactory;
|
|||||||
import androidx.media3.extractor.PositionHolder;
|
import androidx.media3.extractor.PositionHolder;
|
||||||
import androidx.media3.extractor.SeekMap;
|
import androidx.media3.extractor.SeekMap;
|
||||||
import androidx.media3.extractor.TrackOutput;
|
import androidx.media3.extractor.TrackOutput;
|
||||||
|
import androidx.media3.extractor.text.DefaultSubtitleParserFactory;
|
||||||
import androidx.media3.extractor.text.SubtitleExtractor;
|
import androidx.media3.extractor.text.SubtitleExtractor;
|
||||||
import com.google.common.base.Supplier;
|
import com.google.common.base.Supplier;
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
@ -484,12 +484,12 @@ public final class DefaultMediaSourceFactory implements MediaSourceFactory {
|
|||||||
.setLabel(subtitleConfigurations.get(i).label)
|
.setLabel(subtitleConfigurations.get(i).label)
|
||||||
.setId(subtitleConfigurations.get(i).id)
|
.setId(subtitleConfigurations.get(i).id)
|
||||||
.build();
|
.build();
|
||||||
|
DefaultSubtitleParserFactory subtitleParserFactory = new DefaultSubtitleParserFactory();
|
||||||
ExtractorsFactory extractorsFactory =
|
ExtractorsFactory extractorsFactory =
|
||||||
() ->
|
() ->
|
||||||
new Extractor[] {
|
new Extractor[] {
|
||||||
SubtitleDecoderFactory.DEFAULT.supportsFormat(format)
|
subtitleParserFactory.supportsFormat(format)
|
||||||
? new SubtitleExtractor(
|
? new SubtitleExtractor(subtitleParserFactory.create(format), format)
|
||||||
SubtitleDecoderFactory.DEFAULT.createDecoder(format), format)
|
|
||||||
: new UnknownSubtitlesExtractor(format)
|
: new UnknownSubtitlesExtractor(format)
|
||||||
};
|
};
|
||||||
ProgressiveMediaSource.Factory progressiveMediaSourceFactory =
|
ProgressiveMediaSource.Factory progressiveMediaSourceFactory =
|
||||||
|
@ -15,17 +15,16 @@
|
|||||||
*/
|
*/
|
||||||
package androidx.media3.extractor.text;
|
package androidx.media3.extractor.text;
|
||||||
|
|
||||||
|
import static androidx.media3.common.util.Assertions.checkNotNull;
|
||||||
import static androidx.media3.common.util.Assertions.checkState;
|
import static androidx.media3.common.util.Assertions.checkState;
|
||||||
import static androidx.media3.common.util.Assertions.checkStateNotNull;
|
import static androidx.media3.common.util.Assertions.checkStateNotNull;
|
||||||
import static java.lang.annotation.ElementType.TYPE_USE;
|
import static java.lang.annotation.ElementType.TYPE_USE;
|
||||||
|
|
||||||
import androidx.annotation.IntDef;
|
import androidx.annotation.IntDef;
|
||||||
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.MimeTypes;
|
import androidx.media3.common.MimeTypes;
|
||||||
import androidx.media3.common.ParserException;
|
import androidx.media3.common.ParserException;
|
||||||
import androidx.media3.common.text.Cue;
|
|
||||||
import androidx.media3.common.util.ParsableByteArray;
|
import androidx.media3.common.util.ParsableByteArray;
|
||||||
import androidx.media3.common.util.UnstableApi;
|
import androidx.media3.common.util.UnstableApi;
|
||||||
import androidx.media3.common.util.Util;
|
import androidx.media3.common.util.Util;
|
||||||
@ -37,12 +36,12 @@ import androidx.media3.extractor.PositionHolder;
|
|||||||
import androidx.media3.extractor.TrackOutput;
|
import androidx.media3.extractor.TrackOutput;
|
||||||
import com.google.common.primitives.Ints;
|
import com.google.common.primitives.Ints;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InterruptedIOException;
|
|
||||||
import java.lang.annotation.Documented;
|
import java.lang.annotation.Documented;
|
||||||
import java.lang.annotation.Retention;
|
import java.lang.annotation.Retention;
|
||||||
import java.lang.annotation.RetentionPolicy;
|
import java.lang.annotation.RetentionPolicy;
|
||||||
import java.lang.annotation.Target;
|
import java.lang.annotation.Target;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||||
|
|
||||||
@ -82,28 +81,31 @@ public class SubtitleExtractor implements Extractor {
|
|||||||
|
|
||||||
private static final int DEFAULT_BUFFER_SIZE = 1024;
|
private static final int DEFAULT_BUFFER_SIZE = 1024;
|
||||||
|
|
||||||
private final SubtitleDecoder subtitleDecoder;
|
private final SubtitleParser subtitleParser;
|
||||||
private final CueEncoder cueEncoder;
|
private final CueEncoder cueEncoder;
|
||||||
private final ParsableByteArray subtitleData;
|
|
||||||
private final Format format;
|
private final Format format;
|
||||||
private final List<Long> timestamps;
|
private final List<Long> timestamps;
|
||||||
private final List<ParsableByteArray> samples;
|
private final List<byte[]> samples;
|
||||||
|
private final ParsableByteArray scratchSampleArray;
|
||||||
|
|
||||||
private @MonotonicNonNull ExtractorOutput extractorOutput;
|
private byte[] subtitleData;
|
||||||
private @MonotonicNonNull TrackOutput trackOutput;
|
private @MonotonicNonNull TrackOutput trackOutput;
|
||||||
private int bytesRead;
|
private int bytesRead;
|
||||||
private @State int state;
|
private @State int state;
|
||||||
private long seekTimeUs;
|
private long seekTimeUs;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param subtitleDecoder The decoder used for decoding the subtitle data. The extractor will
|
* Creates an instance.
|
||||||
* release the decoder in {@link SubtitleExtractor#release()}.
|
*
|
||||||
* @param format Format that describes subtitle data.
|
* @param subtitleParser The parser used for parsing the subtitle data. The extractor will reset
|
||||||
|
* the parser in {@link SubtitleExtractor#release()}.
|
||||||
|
* @param format {@link Format} that describes subtitle data.
|
||||||
*/
|
*/
|
||||||
public SubtitleExtractor(SubtitleDecoder subtitleDecoder, Format format) {
|
public SubtitleExtractor(SubtitleParser subtitleParser, Format format) {
|
||||||
this.subtitleDecoder = subtitleDecoder;
|
this.subtitleParser = subtitleParser;
|
||||||
cueEncoder = new CueEncoder();
|
cueEncoder = new CueEncoder();
|
||||||
subtitleData = new ParsableByteArray();
|
subtitleData = Util.EMPTY_BYTE_ARRAY;
|
||||||
|
scratchSampleArray = new ParsableByteArray();
|
||||||
this.format =
|
this.format =
|
||||||
format
|
format
|
||||||
.buildUpon()
|
.buildUpon()
|
||||||
@ -127,10 +129,9 @@ public class SubtitleExtractor implements Extractor {
|
|||||||
@Override
|
@Override
|
||||||
public void init(ExtractorOutput output) {
|
public void init(ExtractorOutput output) {
|
||||||
checkState(state == STATE_CREATED);
|
checkState(state == STATE_CREATED);
|
||||||
extractorOutput = output;
|
trackOutput = output.track(/* id= */ 0, C.TRACK_TYPE_TEXT);
|
||||||
trackOutput = extractorOutput.track(/* id= */ 0, C.TRACK_TYPE_TEXT);
|
output.endTracks();
|
||||||
extractorOutput.endTracks();
|
output.seekMap(
|
||||||
extractorOutput.seekMap(
|
|
||||||
new IndexSeekMap(
|
new IndexSeekMap(
|
||||||
/* positions= */ new long[] {0},
|
/* positions= */ new long[] {0},
|
||||||
/* timesUs= */ new long[] {0},
|
/* timesUs= */ new long[] {0},
|
||||||
@ -143,17 +144,20 @@ public class SubtitleExtractor implements Extractor {
|
|||||||
public int read(ExtractorInput input, PositionHolder seekPosition) throws IOException {
|
public int read(ExtractorInput input, PositionHolder seekPosition) throws IOException {
|
||||||
checkState(state != STATE_CREATED && state != STATE_RELEASED);
|
checkState(state != STATE_CREATED && state != STATE_RELEASED);
|
||||||
if (state == STATE_INITIALIZED) {
|
if (state == STATE_INITIALIZED) {
|
||||||
subtitleData.reset(
|
int length =
|
||||||
input.getLength() != C.LENGTH_UNSET
|
input.getLength() != C.LENGTH_UNSET
|
||||||
? Ints.checkedCast(input.getLength())
|
? Ints.checkedCast(input.getLength())
|
||||||
: DEFAULT_BUFFER_SIZE);
|
: DEFAULT_BUFFER_SIZE;
|
||||||
|
if (length > subtitleData.length) {
|
||||||
|
subtitleData = new byte[length];
|
||||||
|
}
|
||||||
bytesRead = 0;
|
bytesRead = 0;
|
||||||
state = STATE_EXTRACTING;
|
state = STATE_EXTRACTING;
|
||||||
}
|
}
|
||||||
if (state == STATE_EXTRACTING) {
|
if (state == STATE_EXTRACTING) {
|
||||||
boolean inputFinished = readFromInput(input);
|
boolean inputFinished = readFromInput(input);
|
||||||
if (inputFinished) {
|
if (inputFinished) {
|
||||||
decode();
|
parse();
|
||||||
writeToOutput();
|
writeToOutput();
|
||||||
state = STATE_FINISHED;
|
state = STATE_FINISHED;
|
||||||
}
|
}
|
||||||
@ -183,13 +187,13 @@ public class SubtitleExtractor implements Extractor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Releases the extractor's resources, including the {@link SubtitleDecoder}. */
|
/** Releases the extractor's resources, including resetting the {@link SubtitleParser}. */
|
||||||
@Override
|
@Override
|
||||||
public void release() {
|
public void release() {
|
||||||
if (state == STATE_RELEASED) {
|
if (state == STATE_RELEASED) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
subtitleDecoder.release();
|
subtitleParser.reset();
|
||||||
state = STATE_RELEASED;
|
state = STATE_RELEASED;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -204,11 +208,13 @@ public class SubtitleExtractor implements Extractor {
|
|||||||
|
|
||||||
/** Returns whether reading has been finished. */
|
/** Returns whether reading has been finished. */
|
||||||
private boolean readFromInput(ExtractorInput input) throws IOException {
|
private boolean readFromInput(ExtractorInput input) throws IOException {
|
||||||
if (subtitleData.capacity() == bytesRead) {
|
if (subtitleData.length == bytesRead) {
|
||||||
subtitleData.ensureCapacity(bytesRead + DEFAULT_BUFFER_SIZE);
|
subtitleData =
|
||||||
|
Arrays.copyOf(subtitleData, /* newLength= */ subtitleData.length + DEFAULT_BUFFER_SIZE);
|
||||||
}
|
}
|
||||||
int readResult =
|
int readResult =
|
||||||
input.read(subtitleData.getData(), bytesRead, subtitleData.capacity() - bytesRead);
|
input.read(
|
||||||
|
subtitleData, /* offset= */ bytesRead, /* length= */ subtitleData.length - bytesRead);
|
||||||
if (readResult != C.RESULT_END_OF_INPUT) {
|
if (readResult != C.RESULT_END_OF_INPUT) {
|
||||||
bytesRead += readResult;
|
bytesRead += readResult;
|
||||||
}
|
}
|
||||||
@ -217,45 +223,19 @@ public class SubtitleExtractor implements Extractor {
|
|||||||
|| readResult == C.RESULT_END_OF_INPUT;
|
|| readResult == C.RESULT_END_OF_INPUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Decodes the subtitle data and stores the samples in the memory of the extractor. */
|
/** Parses the subtitle data and stores the samples in the memory of the extractor. */
|
||||||
private void decode() throws IOException {
|
private void parse() throws IOException {
|
||||||
try {
|
try {
|
||||||
@Nullable SubtitleInputBuffer inputBuffer = subtitleDecoder.dequeueInputBuffer();
|
List<CuesWithTiming> cuesWithTimingList = checkNotNull(subtitleParser.parse(subtitleData));
|
||||||
while (inputBuffer == null) {
|
for (int i = 0; i < cuesWithTimingList.size(); i++) {
|
||||||
Thread.sleep(5);
|
CuesWithTiming cuesWithTiming = cuesWithTimingList.get(i);
|
||||||
inputBuffer = subtitleDecoder.dequeueInputBuffer();
|
long eventTimeUs = cuesWithTiming.startTimeUs;
|
||||||
}
|
byte[] cuesSample = cueEncoder.encode(cuesWithTiming.cues, cuesWithTiming.durationUs);
|
||||||
inputBuffer.ensureSpaceForWrite(bytesRead);
|
|
||||||
inputBuffer.data.put(subtitleData.getData(), /* offset= */ 0, bytesRead);
|
|
||||||
inputBuffer.data.limit(bytesRead);
|
|
||||||
subtitleDecoder.queueInputBuffer(inputBuffer);
|
|
||||||
@Nullable SubtitleOutputBuffer outputBuffer = subtitleDecoder.dequeueOutputBuffer();
|
|
||||||
while (outputBuffer == null) {
|
|
||||||
Thread.sleep(5);
|
|
||||||
outputBuffer = subtitleDecoder.dequeueOutputBuffer();
|
|
||||||
}
|
|
||||||
for (int i = 0; i < outputBuffer.getEventTimeCount(); i++) {
|
|
||||||
long eventTimeUs = outputBuffer.getEventTime(i);
|
|
||||||
List<Cue> cues = outputBuffer.getCues(eventTimeUs);
|
|
||||||
if (cues.isEmpty() && i != 0) {
|
|
||||||
// An empty cue list has already been implicitly encoded in the duration of the previous
|
|
||||||
// sample (unless there was no previous sample).
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
long durationUs =
|
|
||||||
i < outputBuffer.getEventTimeCount() - 1
|
|
||||||
? outputBuffer.getEventTime(i + 1) - eventTimeUs
|
|
||||||
: C.TIME_UNSET;
|
|
||||||
byte[] cuesSample = cueEncoder.encode(cues, durationUs);
|
|
||||||
timestamps.add(eventTimeUs);
|
timestamps.add(eventTimeUs);
|
||||||
samples.add(new ParsableByteArray(cuesSample));
|
samples.add(cuesSample);
|
||||||
}
|
}
|
||||||
outputBuffer.release();
|
} catch (RuntimeException e) {
|
||||||
} catch (InterruptedException e) {
|
throw ParserException.createForMalformedContainer("SubtitleParser failed.", e);
|
||||||
Thread.currentThread().interrupt();
|
|
||||||
throw new InterruptedIOException();
|
|
||||||
} catch (SubtitleDecoderException e) {
|
|
||||||
throw ParserException.createForMalformedContainer("SubtitleDecoder failed.", e);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -268,10 +248,10 @@ public class SubtitleExtractor implements Extractor {
|
|||||||
: Util.binarySearchFloor(
|
: Util.binarySearchFloor(
|
||||||
timestamps, seekTimeUs, /* inclusive= */ true, /* stayInBounds= */ true);
|
timestamps, seekTimeUs, /* inclusive= */ true, /* stayInBounds= */ true);
|
||||||
for (int i = index; i < samples.size(); i++) {
|
for (int i = index; i < samples.size(); i++) {
|
||||||
ParsableByteArray sample = samples.get(i);
|
byte[] sample = samples.get(i);
|
||||||
sample.setPosition(0);
|
int size = sample.length;
|
||||||
int size = sample.getData().length;
|
scratchSampleArray.reset(sample);
|
||||||
trackOutput.sampleData(sample, size);
|
trackOutput.sampleData(scratchSampleArray, size);
|
||||||
trackOutput.sampleMetadata(
|
trackOutput.sampleMetadata(
|
||||||
/* timeUs= */ timestamps.get(i),
|
/* timeUs= */ timestamps.get(i),
|
||||||
/* flags= */ C.BUFFER_FLAG_KEY_FRAME,
|
/* flags= */ C.BUFFER_FLAG_KEY_FRAME,
|
||||||
|
@ -21,7 +21,6 @@ import static org.junit.Assert.assertThrows;
|
|||||||
import androidx.media3.common.Format;
|
import androidx.media3.common.Format;
|
||||||
import androidx.media3.common.MimeTypes;
|
import androidx.media3.common.MimeTypes;
|
||||||
import androidx.media3.common.util.Util;
|
import androidx.media3.common.util.Util;
|
||||||
import androidx.media3.exoplayer.text.DelegatingSubtitleDecoder;
|
|
||||||
import androidx.media3.extractor.Extractor;
|
import androidx.media3.extractor.Extractor;
|
||||||
import androidx.media3.extractor.text.webvtt.WebvttParser;
|
import androidx.media3.extractor.text.webvtt.WebvttParser;
|
||||||
import androidx.media3.test.utils.FakeExtractorInput;
|
import androidx.media3.test.utils.FakeExtractorInput;
|
||||||
@ -65,9 +64,7 @@ public class SubtitleExtractorTest {
|
|||||||
.build();
|
.build();
|
||||||
SubtitleExtractor extractor =
|
SubtitleExtractor extractor =
|
||||||
new SubtitleExtractor(
|
new SubtitleExtractor(
|
||||||
new DelegatingSubtitleDecoder(
|
new WebvttParser(), new Format.Builder().setSampleMimeType(MimeTypes.TEXT_VTT).build());
|
||||||
"DelegatingSubtitleDecoderWithWebvttParser", new WebvttParser()),
|
|
||||||
new Format.Builder().setSampleMimeType(MimeTypes.TEXT_VTT).build());
|
|
||||||
extractor.init(output);
|
extractor.init(output);
|
||||||
|
|
||||||
while (extractor.read(input, null) != Extractor.RESULT_END_OF_INPUT) {}
|
while (extractor.read(input, null) != Extractor.RESULT_END_OF_INPUT) {}
|
||||||
@ -109,9 +106,7 @@ public class SubtitleExtractorTest {
|
|||||||
.build();
|
.build();
|
||||||
SubtitleExtractor extractor =
|
SubtitleExtractor extractor =
|
||||||
new SubtitleExtractor(
|
new SubtitleExtractor(
|
||||||
new DelegatingSubtitleDecoder(
|
new WebvttParser(), new Format.Builder().setSampleMimeType(MimeTypes.TEXT_VTT).build());
|
||||||
"DelegatingSubtitleDecoderWithWebvttParser", new WebvttParser()),
|
|
||||||
new Format.Builder().setSampleMimeType(MimeTypes.TEXT_VTT).build());
|
|
||||||
extractor.init(output);
|
extractor.init(output);
|
||||||
FakeTrackOutput trackOutput = output.trackOutputs.get(0);
|
FakeTrackOutput trackOutput = output.trackOutputs.get(0);
|
||||||
|
|
||||||
@ -152,9 +147,7 @@ public class SubtitleExtractorTest {
|
|||||||
.build();
|
.build();
|
||||||
SubtitleExtractor extractor =
|
SubtitleExtractor extractor =
|
||||||
new SubtitleExtractor(
|
new SubtitleExtractor(
|
||||||
new DelegatingSubtitleDecoder(
|
new WebvttParser(), new Format.Builder().setSampleMimeType(MimeTypes.TEXT_VTT).build());
|
||||||
"DelegatingSubtitleDecoderWithWebvttParser", new WebvttParser()),
|
|
||||||
new Format.Builder().setSampleMimeType(MimeTypes.TEXT_VTT).build());
|
|
||||||
extractor.init(output);
|
extractor.init(output);
|
||||||
FakeTrackOutput trackOutput = output.trackOutputs.get(0);
|
FakeTrackOutput trackOutput = output.trackOutputs.get(0);
|
||||||
|
|
||||||
@ -189,10 +182,7 @@ public class SubtitleExtractorTest {
|
|||||||
public void read_withoutInit_fails() {
|
public void read_withoutInit_fails() {
|
||||||
FakeExtractorInput input = new FakeExtractorInput.Builder().setData(new byte[0]).build();
|
FakeExtractorInput input = new FakeExtractorInput.Builder().setData(new byte[0]).build();
|
||||||
SubtitleExtractor extractor =
|
SubtitleExtractor extractor =
|
||||||
new SubtitleExtractor(
|
new SubtitleExtractor(new WebvttParser(), new Format.Builder().build());
|
||||||
new DelegatingSubtitleDecoder(
|
|
||||||
"DelegatingSubtitleDecoderWithWebvttParser", new WebvttParser()),
|
|
||||||
new Format.Builder().build());
|
|
||||||
|
|
||||||
assertThrows(IllegalStateException.class, () -> extractor.read(input, null));
|
assertThrows(IllegalStateException.class, () -> extractor.read(input, null));
|
||||||
}
|
}
|
||||||
@ -201,10 +191,7 @@ public class SubtitleExtractorTest {
|
|||||||
public void read_afterRelease_fails() {
|
public void read_afterRelease_fails() {
|
||||||
FakeExtractorInput input = new FakeExtractorInput.Builder().setData(new byte[0]).build();
|
FakeExtractorInput input = new FakeExtractorInput.Builder().setData(new byte[0]).build();
|
||||||
SubtitleExtractor extractor =
|
SubtitleExtractor extractor =
|
||||||
new SubtitleExtractor(
|
new SubtitleExtractor(new WebvttParser(), new Format.Builder().build());
|
||||||
new DelegatingSubtitleDecoder(
|
|
||||||
"DelegatingSubtitleDecoderWithWebvttParser", new WebvttParser()),
|
|
||||||
new Format.Builder().build());
|
|
||||||
FakeExtractorOutput output = new FakeExtractorOutput();
|
FakeExtractorOutput output = new FakeExtractorOutput();
|
||||||
|
|
||||||
extractor.init(output);
|
extractor.init(output);
|
||||||
@ -216,10 +203,7 @@ public class SubtitleExtractorTest {
|
|||||||
@Test
|
@Test
|
||||||
public void seek_withoutInit_fails() {
|
public void seek_withoutInit_fails() {
|
||||||
SubtitleExtractor extractor =
|
SubtitleExtractor extractor =
|
||||||
new SubtitleExtractor(
|
new SubtitleExtractor(new WebvttParser(), new Format.Builder().build());
|
||||||
new DelegatingSubtitleDecoder(
|
|
||||||
"DelegatingSubtitleDecoderWithWebvttParser", new WebvttParser()),
|
|
||||||
new Format.Builder().build());
|
|
||||||
|
|
||||||
assertThrows(IllegalStateException.class, () -> extractor.seek(0, 0));
|
assertThrows(IllegalStateException.class, () -> extractor.seek(0, 0));
|
||||||
}
|
}
|
||||||
@ -227,10 +211,7 @@ public class SubtitleExtractorTest {
|
|||||||
@Test
|
@Test
|
||||||
public void seek_afterRelease_fails() {
|
public void seek_afterRelease_fails() {
|
||||||
SubtitleExtractor extractor =
|
SubtitleExtractor extractor =
|
||||||
new SubtitleExtractor(
|
new SubtitleExtractor(new WebvttParser(), new Format.Builder().build());
|
||||||
new DelegatingSubtitleDecoder(
|
|
||||||
"DelegatingSubtitleDecoderWithWebvttParser", new WebvttParser()),
|
|
||||||
new Format.Builder().build());
|
|
||||||
FakeExtractorOutput output = new FakeExtractorOutput();
|
FakeExtractorOutput output = new FakeExtractorOutput();
|
||||||
|
|
||||||
extractor.init(output);
|
extractor.init(output);
|
||||||
@ -242,10 +223,7 @@ public class SubtitleExtractorTest {
|
|||||||
@Test
|
@Test
|
||||||
public void released_calledTwice() {
|
public void released_calledTwice() {
|
||||||
SubtitleExtractor extractor =
|
SubtitleExtractor extractor =
|
||||||
new SubtitleExtractor(
|
new SubtitleExtractor(new WebvttParser(), new Format.Builder().build());
|
||||||
new DelegatingSubtitleDecoder(
|
|
||||||
"DelegatingSubtitleDecoderWithWebvttParser", new WebvttParser()),
|
|
||||||
new Format.Builder().build());
|
|
||||||
FakeExtractorOutput output = new FakeExtractorOutput();
|
FakeExtractorOutput output = new FakeExtractorOutput();
|
||||||
|
|
||||||
extractor.init(output);
|
extractor.init(output);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user