|
16 | 16 | package androidx.media3.extractor.mp4;
|
17 | 17 |
|
18 | 18 | import static androidx.media3.extractor.mp4.FragmentedMp4Extractor.FLAG_EMIT_RAW_SUBTITLE_DATA;
|
| 19 | +import static com.google.common.truth.Truth.assertThat; |
19 | 20 |
|
| 21 | +import androidx.media3.extractor.Extractor; |
| 22 | +import androidx.media3.extractor.PositionHolder; |
20 | 23 | import androidx.media3.extractor.text.DefaultSubtitleParserFactory;
|
21 | 24 | import androidx.media3.extractor.text.SubtitleParser;
|
22 | 25 | import androidx.media3.test.utils.ExtractorAsserts;
|
| 26 | +import androidx.media3.test.utils.FakeExtractorInput; |
| 27 | +import androidx.media3.test.utils.FakeExtractorOutput; |
| 28 | +import androidx.media3.test.utils.FakeTrackOutput; |
| 29 | +import androidx.media3.test.utils.TestUtil; |
| 30 | +import androidx.test.core.app.ApplicationProvider; |
| 31 | +import com.google.common.collect.ImmutableList; |
23 | 32 | import java.util.ArrayList;
|
24 | 33 | import java.util.List;
|
25 | 34 | import org.junit.Test;
|
@@ -226,6 +235,51 @@ public void mp4SampleWithEditList() throws Exception {
|
226 | 235 | simulationConfig);
|
227 | 236 | }
|
228 | 237 |
|
| 238 | + @Test |
| 239 | + public void mp4SampleWithEmptyTrack() throws Exception { |
| 240 | + ExtractorAsserts.assertBehavior( |
| 241 | + getExtractorFactory(subtitlesParsedDuringExtraction), |
| 242 | + "media/mp4/sample_empty_track.mp4", |
| 243 | + simulationConfig); |
| 244 | + } |
| 245 | + |
| 246 | + @Test |
| 247 | + public void getSeekPoints_withEmptyTracks_returnsValidInformation() throws Exception { |
| 248 | + Mp4Extractor extractor = |
| 249 | + (Mp4Extractor) getExtractorFactory(subtitlesParsedDuringExtraction).create(); |
| 250 | + FakeExtractorInput input = |
| 251 | + new FakeExtractorInput.Builder() |
| 252 | + .setData( |
| 253 | + TestUtil.getByteArray( |
| 254 | + ApplicationProvider.getApplicationContext(), |
| 255 | + "media/mp4/sample_empty_track.mp4")) |
| 256 | + .build(); |
| 257 | + FakeExtractorOutput output = |
| 258 | + new FakeExtractorOutput( |
| 259 | + (id, type) -> new FakeTrackOutput(/* deduplicateConsecutiveFormats= */ true)); |
| 260 | + PositionHolder seekPositionHolder = new PositionHolder(); |
| 261 | + extractor.init(output); |
| 262 | + int readResult = Extractor.RESULT_CONTINUE; |
| 263 | + while (readResult != Extractor.RESULT_END_OF_INPUT) { |
| 264 | + readResult = extractor.read(input, seekPositionHolder); |
| 265 | + if (readResult == Extractor.RESULT_SEEK) { |
| 266 | + long seekPosition = seekPositionHolder.position; |
| 267 | + input.setPosition((int) seekPosition); |
| 268 | + } |
| 269 | + } |
| 270 | + ImmutableList.Builder<Long> trackSeekTimesUs = ImmutableList.builder(); |
| 271 | + long testPositionUs = output.seekMap.getDurationUs() / 2; |
| 272 | + |
| 273 | + for (int i = 0; i < output.numberOfTracks; i++) { |
| 274 | + int trackId = output.trackOutputs.keyAt(i); |
| 275 | + trackSeekTimesUs.add(extractor.getSeekPoints(testPositionUs, trackId).first.timeUs); |
| 276 | + } |
| 277 | + long extractorSeekTimeUs = extractor.getSeekPoints(testPositionUs).first.timeUs; |
| 278 | + |
| 279 | + assertThat(output.numberOfTracks).isEqualTo(2); |
| 280 | + assertThat(extractorSeekTimeUs).isIn(trackSeekTimesUs.build()); |
| 281 | + } |
| 282 | + |
229 | 283 | private static ExtractorAsserts.ExtractorFactory getExtractorFactory(
|
230 | 284 | boolean subtitlesParsedDuringExtraction) {
|
231 | 285 | SubtitleParser.Factory subtitleParserFactory;
|
|
0 commit comments