ExoPlayer+CastPlayer使用MediaItem添加字幕(隐藏式字幕)

发布于 2025-01-09 03:17:41 字数 2643 浏览 3 评论 0原文

我正在尝试配置 SimpleExoPlayer 和 CastPlayer 以在设备/电视上显示字幕。 我创建 MediaItem 如下:

private fun createMediaItem(url: String, type: PlayerViewSourceType): MediaItem {
        val uri = Uri.parse(url)
        val mediaItemBuilder = MediaItem.Builder()
            .setUri(uri)
        if (type == PlayerViewSourceType.HLS) {
            val subtitle = MediaItem.Subtitle(uri, MimeTypes.TEXT_VTT, "en", C.SELECTION_FLAG_AUTOSELECT)
            mediaItemBuilder.apply {
                setMimeType(MimeTypes.APPLICATION_M3U8)
                setSubtitles(listOf(subtitle))
            }
        } else {
            val subtitle = MediaItem.Subtitle(uri, MimeTypes.TEXT_VTT, "en", C.SELECTION_FLAG_AUTOSELECT)
            mediaItemBuilder.apply {
                setMimeType(MimeTypes.APPLICATION_MP4)
                setSubtitles(listOf(subtitle))
            }
        }

        return mediaItemBuilder.build()
    }

我使用相同的 url,因为字幕随视频一起提供,并且在 iOS 端以这种方式工作。另外, Subtitles 对象对于这两种情况都是相同的,因此可以在 if-else 之前创建,但我尝试了不同的参数集,所以我将其保留原样。事情不是这样的。不幸的是 addTextOutput {} 已被弃用,所以我一直在进一步搜索,我发现我可以将其添加为 Player.Listener 实现,所以我创建了一个类

private inner class SubtitlesListener() : Player.Listener, TextOutput {
        override fun onCues(cues: MutableList<Cue>) {
            subtitleView.onCues(cues)
        }
    }

:在这个类中,我为我的播放器添加了另一个侦听器:

playerStorage.simpleExoPlayer.addListener(SubtitlesListener())
playerStorage.castPlayer.addListener(SubtitlesListener())

为了将其全部压缩在一起,我添加了 CC 按钮的点击侦听器:

private fun setupSubtitlesClickListener() {
        ccButton.setOnClickListener {
            when (playerStorage.isDisplayingSubtitles) {
                true -> {
                    playerStorage.showSubtitles(false)
                    ccButton.setImageResource(R.drawable.ic_closed_caption_inactive_24_px)
                    subtitleView.gone()
                }
                else -> {
                    playerStorage.showSubtitles(true)
                    ccButton.setImageResource(R.drawable.ic_closed_caption_white_16_px)
                    subtitleView.visible()
                }
            }
        }
    }

目前应用程序中只有一个视频具有用于测试目的的字幕,它是 .mp4 视频文件。不幸的是这个解决方案不起作用。
我发现了很多字幕的实现,但最新的是 2020 年的,在这里不适用。另外,我无法使用 MergingMediaSource,因为 CastPlayer 仅接受 MediaItemSimpleExoPlayer 也可以使用它,因此我可以为两个玩家创建一种类型的对象。即使我仅将 MediaSource 用于 SimpleExoPlayer,我仍然无法为 `CastPlayer 添加字幕。

我可以在所有情况下使用 m3u8,因此我不需要从单独的文件中读取文件。

I am trying to configure both SimpleExoPlayer and CastPlayer to display subtitles on device/TV.
I create MediaItem as follows:

private fun createMediaItem(url: String, type: PlayerViewSourceType): MediaItem {
        val uri = Uri.parse(url)
        val mediaItemBuilder = MediaItem.Builder()
            .setUri(uri)
        if (type == PlayerViewSourceType.HLS) {
            val subtitle = MediaItem.Subtitle(uri, MimeTypes.TEXT_VTT, "en", C.SELECTION_FLAG_AUTOSELECT)
            mediaItemBuilder.apply {
                setMimeType(MimeTypes.APPLICATION_M3U8)
                setSubtitles(listOf(subtitle))
            }
        } else {
            val subtitle = MediaItem.Subtitle(uri, MimeTypes.TEXT_VTT, "en", C.SELECTION_FLAG_AUTOSELECT)
            mediaItemBuilder.apply {
                setMimeType(MimeTypes.APPLICATION_MP4)
                setSubtitles(listOf(subtitle))
            }
        }

        return mediaItemBuilder.build()
    }

I use same url, because subtitles are coming with video and it works this way on iOS side. Also Subtitles object is the same for both cases so could be created before if-else but I tried different sets of parameters so I left it as it is. It didn't work this way. Unfortunatelly addTextOutput {} is deprecated so I've been searching further and I found out that I can add it as Player.Listener implementation, so I created a class:

private inner class SubtitlesListener() : Player.Listener, TextOutput {
        override fun onCues(cues: MutableList<Cue>) {
            subtitleView.onCues(cues)
        }
    }

And with this class I added another listeners for my players:

playerStorage.simpleExoPlayer.addListener(SubtitlesListener())
playerStorage.castPlayer.addListener(SubtitlesListener())

And to zip it all together I added click listener for CC button:

private fun setupSubtitlesClickListener() {
        ccButton.setOnClickListener {
            when (playerStorage.isDisplayingSubtitles) {
                true -> {
                    playerStorage.showSubtitles(false)
                    ccButton.setImageResource(R.drawable.ic_closed_caption_inactive_24_px)
                    subtitleView.gone()
                }
                else -> {
                    playerStorage.showSubtitles(true)
                    ccButton.setImageResource(R.drawable.ic_closed_caption_white_16_px)
                    subtitleView.visible()
                }
            }
        }
    }

For now only one video in app has subtitles for testing purposes and it is .mp4 video file. Unfortunately this solution doesn't work.
I have found plenty implementations for subtitles, but the latest is from 2020 and it is not applicable here. Also I can't use MergingMediaSource because CastPlayer accepts only MediaItem. SimpleExoPlayer can use it too, so I can create one type of object for both players. Even if I would use MediaSource just for SimpleExoPlayer I still couldn't add subtitles for `CastPlayer.

I can use m3u8 for all cases, so I don't need to read files from separate file.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文