diff --git a/constants.gradle b/constants.gradle index b932bf49d6..cbf2c5d208 100644 --- a/constants.gradle +++ b/constants.gradle @@ -12,8 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. project.ext { - releaseVersion = '1.4.1-dr6' - releaseVersionCode = 1_004_001_6_00 + releaseVersion = '1.4.1-dr7' + releaseVersionCode = 1_004_001_7_00 minSdkVersion = 19 // See https://developer.android.com/training/cars/media/automotive-os#automotive-module automotiveMinSdkVersion = 28 diff --git a/demos/main/src/main/assets/media.exolist.json b/demos/main/src/main/assets/media.exolist.json index 6e1c4e98b0..16dc8ef100 100644 --- a/demos/main/src/main/assets/media.exolist.json +++ b/demos/main/src/main/assets/media.exolist.json @@ -952,6 +952,28 @@ "subtitle_mime_type": "text/vtt", "subtitle_language": "en" }, + { + "name": "dash segmented webvtt", + "uri": "https://sample-videos-zyrkp2nj.s3.eu-west-1.amazonaws.com/white-60s/dash_fmp4_clear_subs/master_2_forced.mpd" + }, + { + "name": "hls segmented webvtt", + "uri": "https://sample-videos-zyrkp2nj.s3.eu-west-1.amazonaws.com/white-60s/hls_fmp4_clear_subs/master_2_forced.m3u8" + }, + { + "name": "dash sideload webvtt", + "uri": "https://storage.googleapis.com/wvmedia/clear/h264/tears/tears.mpd", + "subtitle_uri": "https://dve-subtitles.imggaming.com/560967/776847/vtt/subtitle-en-US-245273-1712171888041.vtt", + "subtitle_mime_type": "text/vtt", + "subtitle_language": "cn" + }, + { + "name": "hls sideload webvtt", + "uri": "https://devstreaming-cdn.apple.com/videos/streaming/examples/bipbop_16x9/bipbop_16x9_variant.m3u8", + "subtitle_uri": "https://dve-subtitles.imggaming.com/560967/776847/vtt/subtitle-en-US-245273-1712171888041.vtt", + "subtitle_mime_type": "text/vtt", + "subtitle_language": "cn" + }, { "name": "WebVTT Japanese features", "uri": "https://html5demos.com/assets/dizzy.mp4", diff --git a/libraries/extractor/src/main/java/androidx/media3/extractor/text/SubtitleExtractor.java b/libraries/extractor/src/main/java/androidx/media3/extractor/text/SubtitleExtractor.java index 9e5492f8c1..e8fcf4eb86 100644 --- a/libraries/extractor/src/main/java/androidx/media3/extractor/text/SubtitleExtractor.java +++ b/libraries/extractor/src/main/java/androidx/media3/extractor/text/SubtitleExtractor.java @@ -33,6 +33,7 @@ import androidx.media3.extractor.IndexSeekMap; import androidx.media3.extractor.PositionHolder; import androidx.media3.extractor.TrackOutput; +import androidx.media3.extractor.text.webvtt.WebvttParser; import com.google.common.primitives.Ints; import java.io.IOException; import java.lang.annotation.Documented; @@ -87,6 +88,8 @@ public class SubtitleExtractor implements Extractor { private final List samples; private final ParsableByteArray scratchSampleArray; + private final boolean useSegmentedSubtitleWorkaround; + private byte[] subtitleData; private @MonotonicNonNull TrackOutput trackOutput; private int bytesRead; @@ -117,6 +120,8 @@ public SubtitleExtractor(SubtitleParser subtitleParser, Format format) { state = STATE_CREATED; timestamps = Util.EMPTY_LONG_ARRAY; seekTimeUs = C.TIME_UNSET; + + useSegmentedSubtitleWorkaround = subtitleParser instanceof WebvttParser; } @Override @@ -159,6 +164,9 @@ public int read(ExtractorInput input, PositionHolder seekPosition) throws IOExce boolean inputFinished = readFromInput(input); if (inputFinished) { parseAndWriteToOutput(); + // We do not change the state to STATE_FINISHED, otherwise for segmented webvtt on dash + // we will show the subtitle in the first vtt file, and miss all subtitles in next vtt file. + if (useSegmentedSubtitleWorkaround) return RESULT_END_OF_INPUT; state = STATE_FINISHED; } }