google / ExoPlayer

This project is deprecated and stale. The latest ExoPlayer code is available in https://github.com/androidx/media
https://developer.android.com/media/media3/exoplayer
Apache License 2.0
21.67k stars 6k forks source link

I can't show subtitle #9157

Closed Pierluigi-Scotto closed 3 years ago

Pierluigi-Scotto commented 3 years ago

Hi there, Firstly sorry for my bad english. I'm programming in Kotlin.

I'm creating a simple player that runs a video and show subtitle.

I have a locally file .srt where are stored the subtitles and .mp4 where's the video that i need to show. In android they're stored in raw directory:

Project

This is my subtitle in format srt.

1
00:00:00,000 --> 01:00:00,000
This is an example of
a subtitle.

2
01:01:00,000 --> 02:00:00,000
This is an example of
2nd subtitle.

I parse the video and it runs correctly. This is how i parse video and subtitle:

  videoUri = Uri.parse("android.resource://" + packageName + "/"
                + R.raw.big_buck_bunny)
  subtitleUri = Uri.parse("android.resource://" + packageName + "/"
                + R.raw.simple_subtitle)

Now after i parsed the subtitle and used this guide https://exoplayer.dev/media-items.html to sideload subtitle tracks, when i run the video and selected the subtitle it won't show. This is how i create media item:

        val subtitle = MediaItem.Subtitle(
            subtitleUri,
            MimeTypes.TEXT_VTT,
            "en",
            C.SELECTION_FLAG_AUTOSELECT
        )

        val mediaItem = MediaItem.Builder()
            .setUri(videoUri)
            .setSubtitles(arrayListOf(subtitle))
            .build()

        player = SimpleExoPlayer.Builder(this)
            .build()
            .apply {
                playWhenReady = startAutoPlay
                seekTo(currentWindow, playbackPosition)
                setMediaItem(mediaItem)
                prepare()
            }

        playerView.player = player
        playerView.player!!.play()
    }

And these are variables:

 private lateinit var playerView: StyledPlayerView
    private lateinit var videoUri:Uri
    private lateinit var subtitleUri:Uri
    private var player: SimpleExoPlayer? = null
    private var startAutoPlay = false
    private var currentWindow = 0
    private var playbackPosition = 0L

I have tryed subtitles using vlc and they are working.

I see the app demo in the github (https://github.com/google/ExoPlayer/tree/release-v2/demos/main) but i didn't see in the snippet code where the subtitle is shown.

Anyone can help me? Thanks in advance.

icbaker commented 3 years ago

You're passing ExoPlayer an SRT subtitle file but telling us its WebVTT (MimeTypes.TEXT_VTT).

These formats are similar but not the same.

Your file is not a valid WebVTT file so parsing fails and no subtitles are displayed. You should see an error like this in logcat:

E/TextRenderer: Subtitle decoding failed. streamFormat=Format(null, null, null, text/vtt, null, -1, ja, [-1, -1, -1.0], [-1, -1])
      com.google.android.exoplayer2.text.SubtitleDecoderException: com.google.android.exoplayer2.ParserException: Expected WEBVTT. Got 1
        at com.google.android.exoplayer2.text.webvtt.WebvttDecoder.decode(WebvttDecoder.java:67)
        at com.google.android.exoplayer2.text.SimpleSubtitleDecoder.decode(SimpleSubtitleDecoder.java:73)
        at com.google.android.exoplayer2.text.SimpleSubtitleDecoder.decode(SimpleSubtitleDecoder.java:26)
        at com.google.android.exoplayer2.decoder.SimpleDecoder.decode(SimpleDecoder.java:238)
        at com.google.android.exoplayer2.decoder.SimpleDecoder.run(SimpleDecoder.java:202)
        at com.google.android.exoplayer2.decoder.SimpleDecoder.access$000(SimpleDecoder.java:31)
        at com.google.android.exoplayer2.decoder.SimpleDecoder$1.run(SimpleDecoder.java:74)
     Caused by: com.google.android.exoplayer2.ParserException: Expected WEBVTT. Got 1
        at com.google.android.exoplayer2.text.webvtt.WebvttParserUtil.validateWebvttHeaderLine(WebvttParserUtil.java:45)
        at com.google.android.exoplayer2.text.webvtt.WebvttDecoder.decode(WebvttDecoder.java:65)
        at com.google.android.exoplayer2.text.SimpleSubtitleDecoder.decode(SimpleSubtitleDecoder.java:73) 
        at com.google.android.exoplayer2.text.SimpleSubtitleDecoder.decode(SimpleSubtitleDecoder.java:26) 
        at com.google.android.exoplayer2.decoder.SimpleDecoder.decode(SimpleDecoder.java:238) 
        at com.google.android.exoplayer2.decoder.SimpleDecoder.run(SimpleDecoder.java:202) 
        at com.google.android.exoplayer2.decoder.SimpleDecoder.access$000(SimpleDecoder.java:31) 
        at com.google.android.exoplayer2.decoder.SimpleDecoder$1.run(SimpleDecoder.java:74) 

If you pass MimeTypes.APPLICATION_SUBRIP instead then it should work.

Pierluigi-Scotto commented 3 years ago

Sorry my bad, even if i change with MimeTypes.APPLICATION_SUBRIP when choosing subtitle not shown.

Edit: just tryed now in emulator working, but on my phone seems is bugged (Xiaomi Note 7). When choosing the subtitle the button of subtitle seems to be disappear

Edit2: i'm trying using different emulators but subtitle won't show This is logcat

W/SingleSampleMediaPeriod: Loading failed, treating as end-of-stream.
      com.google.android.exoplayer2.upstream.RawResourceDataSource$RawResourceDataSourceException: android.content.res.Resources$NotFoundException: File res/raw/simple_subtitle_srt.srt from resource ID #0x7f100002
        at com.google.android.exoplayer2.upstream.RawResourceDataSource.open(RawResourceDataSource.java:142)
        at com.google.android.exoplayer2.upstream.DefaultDataSource.open(DefaultDataSource.java:201)
        at com.google.android.exoplayer2.upstream.StatsDataSource.open(StatsDataSource.java:84)
        at com.google.android.exoplayer2.source.SingleSampleMediaPeriod$SourceLoadable.load(SingleSampleMediaPeriod.java:436)
        at com.google.android.exoplayer2.upstream.Loader$LoadTask.run(Loader.java:417)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
        at java.lang.Thread.run(Thread.java:923)
     Caused by: android.content.res.Resources$NotFoundException: File res/raw/simple_subtitle_srt.srt from resource ID #0x7f100002
        at android.content.res.ResourcesImpl.openRawResourceFd(ResourcesImpl.java:346)
        at android.content.res.Resources.openRawResourceFd(Resources.java:1405)
        at com.google.android.exoplayer2.upstream.RawResourceDataSource.open(RawResourceDataSource.java:140)
        at com.google.android.exoplayer2.upstream.DefaultDataSource.open(DefaultDataSource.java:201) 
        at com.google.android.exoplayer2.upstream.StatsDataSource.open(StatsDataSource.java:84) 
        at com.google.android.exoplayer2.source.SingleSampleMediaPeriod$SourceLoadable.load(SingleSampleMediaPeriod.java:436) 
        at com.google.android.exoplayer2.upstream.Loader$LoadTask.run(Loader.java:417) 
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167) 
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641) 
        at java.lang.Thread.run(Thread.java:923) 
     Caused by: java.io.FileNotFoundException: This file can not be opened as a file descriptor; it is probably compressed
        at android.content.res.AssetManager.nativeOpenNonAssetFd(Native Method)
        at android.content.res.AssetManager.openNonAssetFd(AssetManager.java:1031)
        at android.content.res.ResourcesImpl.openRawResourceFd(ResourcesImpl.java:343)
        at android.content.res.Resources.openRawResourceFd(Resources.java:1405) 
        at com.google.android.exoplayer2.upstream.RawResourceDataSource.open(RawResourceDataSource.java:140) 
        at com.google.android.exoplayer2.upstream.DefaultDataSource.open(DefaultDataSource.java:201) 
        at com.google.android.exoplayer2.upstream.StatsDataSource.open(StatsDataSource.java:84) 
        at com.google.android.exoplayer2.source.SingleSampleMediaPeriod$SourceLoadable.load(SingleSampleMediaPeriod.java:436) 
        at com.google.android.exoplayer2.upstream.Loader$LoadTask.run(Loader.java:417) 
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167) 
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641) 
        at java.lang.Thread.run(Thread.java:923) 

simple_subtitle_srt.srt:

1
00:00:00,000 --> 00:10:00,000
This is a subtitle

2
00:10:00,000 --> 00:30:00,000
This is a 2nd subtitle.

Parse and subtitle:

subtitleUri = Uri.parse("android.resource://" + packageName + "/"
                + R.raw.simple_subtitle_srt)

val subtitle = MediaItem.Subtitle(
            subtitleUri,
            MimeTypes.APPLICATION_SUBRIP,
            "en",
            C.SELECTION_FLAG_AUTOSELECT
        )
icbaker commented 3 years ago

Googling "This file can not be opened as a file descriptor; it is probably compressed" takes me here: https://stackoverflow.com/questions/6186866/java-io-filenotfoundexception-this-file-can-not-be-opened-as-a-file-descriptor

I think your options are:

Pierluigi-Scotto commented 3 years ago

Ok everything is working. Thanks!

Solution is: Put subtitle in assets folder

Immagine 2021-07-06 175721

Parse the file like this subtitleUri = Uri.parse("asset:///subtitle.srt")

Finally set it:

        val subtitle = MediaItem.Subtitle(
            subtitleUri,
            MimeTypes.APPLICATION_SUBRIP,
            "en",
            C.SELECTION_FLAG_AUTOSELECT
        )

        val mediaItem = MediaItem.Builder()
            .setUri(videoUri)
            .setSubtitles(arrayListOf(subtitle))
            .build()