Enable support for WebVTT and TTML subtitles for the player (#4377)
All subtitle formats used to be enabled by default in older versions of media3. After the media3 library was upgraded to 1.3.0, Extractors should specify a `SubtitleParser.Factory` explicitly. By default, no subtitle formats are supported when using the now deprecated empty constructor of Extractors. Limit support to **WebVTT** and **TTML** which are the only true web standards amongst all the subtitle formats supported by ExoPlayer. Note that only subtitles embedded in MP4 and WebM files are supported until Mastodon provides a way to upload subtitles separately.
This commit is contained in:
parent
4e822c9a0a
commit
72ee0b4292
|
@ -21,6 +21,8 @@ import android.content.Context
|
||||||
import android.os.Looper
|
import android.os.Looper
|
||||||
import androidx.annotation.OptIn
|
import androidx.annotation.OptIn
|
||||||
import androidx.media3.common.C
|
import androidx.media3.common.C
|
||||||
|
import androidx.media3.common.Format
|
||||||
|
import androidx.media3.common.MimeTypes
|
||||||
import androidx.media3.common.util.UnstableApi
|
import androidx.media3.common.util.UnstableApi
|
||||||
import androidx.media3.datasource.DataSource
|
import androidx.media3.datasource.DataSource
|
||||||
import androidx.media3.datasource.DefaultDataSource
|
import androidx.media3.datasource.DefaultDataSource
|
||||||
|
@ -44,6 +46,10 @@ import androidx.media3.extractor.mp3.Mp3Extractor
|
||||||
import androidx.media3.extractor.mp4.FragmentedMp4Extractor
|
import androidx.media3.extractor.mp4.FragmentedMp4Extractor
|
||||||
import androidx.media3.extractor.mp4.Mp4Extractor
|
import androidx.media3.extractor.mp4.Mp4Extractor
|
||||||
import androidx.media3.extractor.ogg.OggExtractor
|
import androidx.media3.extractor.ogg.OggExtractor
|
||||||
|
import androidx.media3.extractor.text.SubtitleParser
|
||||||
|
import androidx.media3.extractor.text.ttml.TtmlParser
|
||||||
|
import androidx.media3.extractor.text.webvtt.Mp4WebvttParser
|
||||||
|
import androidx.media3.extractor.text.webvtt.WebvttParser
|
||||||
import androidx.media3.extractor.wav.WavExtractor
|
import androidx.media3.extractor.wav.WavExtractor
|
||||||
import dagger.Module
|
import dagger.Module
|
||||||
import dagger.Provides
|
import dagger.Provides
|
||||||
|
@ -98,17 +104,50 @@ object PlayerModule {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
fun provideExtractorsFactory(): ExtractorsFactory {
|
fun providesSubtitleParserFactory(): SubtitleParser.Factory {
|
||||||
|
return object : SubtitleParser.Factory {
|
||||||
|
override fun supportsFormat(format: Format): Boolean {
|
||||||
|
return when (format.sampleMimeType) {
|
||||||
|
MimeTypes.TEXT_VTT,
|
||||||
|
MimeTypes.APPLICATION_MP4VTT,
|
||||||
|
MimeTypes.APPLICATION_TTML -> true
|
||||||
|
|
||||||
|
else -> false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getCueReplacementBehavior(format: Format): Int {
|
||||||
|
return when (val mimeType = format.sampleMimeType) {
|
||||||
|
MimeTypes.TEXT_VTT -> WebvttParser.CUE_REPLACEMENT_BEHAVIOR
|
||||||
|
MimeTypes.APPLICATION_MP4VTT -> Mp4WebvttParser.CUE_REPLACEMENT_BEHAVIOR
|
||||||
|
MimeTypes.APPLICATION_TTML -> TtmlParser.CUE_REPLACEMENT_BEHAVIOR
|
||||||
|
else -> throw IllegalArgumentException("Unsupported MIME type: $mimeType")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun create(format: Format): SubtitleParser {
|
||||||
|
return when (val mimeType = format.sampleMimeType) {
|
||||||
|
MimeTypes.TEXT_VTT -> WebvttParser()
|
||||||
|
MimeTypes.APPLICATION_MP4VTT -> Mp4WebvttParser()
|
||||||
|
MimeTypes.APPLICATION_TTML -> TtmlParser()
|
||||||
|
else -> throw IllegalArgumentException("Unsupported MIME type: $mimeType")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
fun provideExtractorsFactory(subtitleParserFactory: SubtitleParser.Factory): ExtractorsFactory {
|
||||||
// Extractors order is optimized according to
|
// Extractors order is optimized according to
|
||||||
// https://docs.google.com/document/d/1w2mKaWMxfz2Ei8-LdxqbPs1VLe_oudB-eryXXw9OvQQ
|
// https://docs.google.com/document/d/1w2mKaWMxfz2Ei8-LdxqbPs1VLe_oudB-eryXXw9OvQQ
|
||||||
return ExtractorsFactory {
|
return ExtractorsFactory {
|
||||||
arrayOf(
|
arrayOf(
|
||||||
FlacExtractor(),
|
FlacExtractor(),
|
||||||
WavExtractor(),
|
WavExtractor(),
|
||||||
Mp4Extractor(),
|
Mp4Extractor(subtitleParserFactory),
|
||||||
FragmentedMp4Extractor(),
|
FragmentedMp4Extractor(subtitleParserFactory),
|
||||||
OggExtractor(),
|
OggExtractor(),
|
||||||
MatroskaExtractor(),
|
MatroskaExtractor(subtitleParserFactory),
|
||||||
Mp3Extractor()
|
Mp3Extractor()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue