我有一个基于 Google Android TV 示例存储库的 Android TV 应用程序,但无法显示字幕。我的应用程序没有发生任何崩溃,字幕根本没有显示,据我从调查中了解到,没有 Android 视图可以渲染它们。
我的 playback 片段(播放视频的片段)实现了
VideoSupportFragment
,这是一个 Android Leanback 片段,其中将 Surface
集成到布局中以渲染视频。
这就是我创建字幕的方式:
val subtitles = videoRepository.listSubtitles("m" + video.id).mapIndexed { index, it ->
val builder = MediaItem.SubtitleConfiguration.Builder(
Uri.parse("http://192.168.129.9:3000/api/subtitles/${it.id}")
)
.setMimeType(MimeTypes.TEXT_VTT)
.setLanguage(it.lang)
.setId(it.id.toString())
if (index == 0) {
builder.setSelectionFlags(C.SELECTION_FLAG_DEFAULT)
}
builder.build()
}
val mediaItem = MediaItem.Builder()
.setUri(video.videoUri)
.setSubtitleConfigurations(subtitles)
.build()
这就是我将 ExoPlayer 连接(我认为至少......)到包含视频表面的片段的地方:
private fun prepareGlue(localExoplayer: ExoPlayer) {
ProgressTransportControlGlue(
requireContext(),
LeanbackPlayerAdapter(
requireContext(),
localExoplayer,
PLAYER_UPDATE_INTERVAL_MILLIS.toInt()
),
onProgressUpdate
).apply {
host = VideoSupportFragmentGlueHost(this@PlaybackFragment)
title = video.name
subtitle = video.year.toString()
// Enable seek manually since PlaybackTransportControlGlue.getSeekProvider() is null,
// so that PlayerAdapter.seekTo(long) will be called during user seeking.
// TODO(gargsahil@): Add a PlaybackSeekDataProvider to support video scrubbing.
isSeekEnabled = true
}
}
完整代码在这里(它是一个开源项目):PlaybackFragment.kt#L125
并且基于此 AndroidTV 示例: https://github.com/android/tv-samples/blob/main/ReferenceAppKotlin/app/src/main/java/com/android/tv/reference/playback/PlaybackFragment.kt
靠背
VideoSupportFragment
充气 lb_playback_fragment.xml
,不包括外放器 SubtitleView
。正如这个问题中所讨论的,最简单的方法是覆盖lb_playback_fragment.xml
并在其中包含SubtitleView
。从问题中复制的文件:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/playback_fragment_root"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:transitionGroup="false">
<androidx.leanback.widget.NonOverlappingFrameLayout
android:id="@+id/playback_fragment_background"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:transitionGroup="false" />
<androidx.leanback.widget.NonOverlappingFrameLayout
android:id="@+id/playback_controls_dock"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:transitionGroup="true" />
<com.google.android.exoplayer2.ui.AspectRatioFrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center">
<com.google.android.exoplayer2.ui.SubtitleView
android:id="@+id/leanback_subtitles"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</com.google.android.exoplayer2.ui.AspectRatioFrameLayout>
</FrameLayout>
然后在片段代码中,您可以使用
SubtitleView
作为文本输出来显示字幕。
这是带有media3的更新版本
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/playback_fragment_root"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:transitionGroup="false">
<androidx.leanback.widget.NonOverlappingFrameLayout
android:id="@+id/playback_fragment_background"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:transitionGroup="false" />
<androidx.leanback.widget.NonOverlappingFrameLayout
android:id="@+id/playback_controls_dock"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:transitionGroup="true" />
<androidx.media3.ui.AspectRatioFrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center">
<androidx.media3.ui.SubtitleView
android:id="@+id/leanback_subtitles"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</androidx.media3.ui.AspectRatioFrameLayout>
</FrameLayout>