Serenity for Google TV用户最常提出的问题之一就是可以播放电影字幕。 Plex确实会提供信息(如果有的话),但是直到Android 4.1(又名Jelly Bean),视频播放器才没有本机字幕支持。 即使这样,在读取字幕流时似乎还是有问题。 Google TV设备当前基于Android 3.2(Honeycomb),它没有可播放字幕的api。 在这种情况下,Plex通常会将字幕转换为视频流,但是,Serenity不支持转换。 那么该怎么办。 简单地转向开源软件以寻求帮助。
J.David Requejo撰写的subtitleConverter隐藏在GitHub上。 这是一个PHD研究项目,可以从一种字幕格式转换为另一种字幕格式。 不错的是,TimedTextObject包含字幕的通用格式。 一旦采用这种格式,就可以在树上导航并检查显示标题以及何时消失的时间偏移。
由于Google TV设备不支持显示字幕,因此我们该如何解决。 Serenity使用MediaController和SurfaceView的修改版本。 主要活动包含以下布局xml:
<?xml version='1.0' encoding='utf-8'?>
<RelativeLayout xmlns:android='http://schemas.android.com/apk/res/android'
android:layout_width='fill_parent'
android:layout_height='fill_parent'
android:orientation='vertical'
android:id='@+id/video_playeback'
android:background='#000000'
android:keepScreenOn='true' >
<SurfaceView android:id='@+id/surfaceView'
android:layout_width='wrap_content'
android:layout_height='wrap_content'
android:layout_centerInParent='true'
/>
<TextView android:id='@+id/txtSubtitles'
android:layout_alignParentBottom='true'
android:layout_height='wrap_content'
android:layout_width='wrap_content'
android:gravity='center'
android:layout_centerHorizontal='true'
android:visibility='invisible'
style='@android:style/TextAppearance.Large'/>
</RelativeLayout>
它包含要在其上绘制视频的Surfaceview,以及一个用于显示字幕的TextView。 为了知道何时在播放期间显示字幕,我们使用了处理时间短的处理程序。 第一次以可运行方式对其进行调用时,它将立即执行。 随后的每次执行都会延迟100毫秒。
private Handler subtitleDisplayHandler = new Handler();
private Runnable subtitle = new Runnable() {
public void run() {
if (isMediaPlayerStateValid() && mediaPlayer.isPlaying()) {
int currentPos = mediaPlayer.getCurrentPosition();
Collection<Caption> subtitles = srt.captions.values();
for(Caption caption : subtitles) {
if (currentPos >= caption.start.getMilliseconds() && currentPos <= caption.end.getMilliseconds()) {
onTimedText(caption);
break;
} else if (currentPos > caption.end.getMilliseconds()) {
onTimedText(null);
}
}
}
subtitleDisplayHandler.postDelayed(this, SUBTITLE_DISPLAY_CHECK);
};
};
postDelayed将以可运行时间(指定的毫秒数)重新执行Handler。 onTimedText是负责在播放期间显示或隐藏字幕的内容。
public void onTimedText(Caption text) {
TextView subtitles = (TextView) findViewById(R.id.txtSubtitles);
if (text == null) {
subtitles.setVisibility(View.INVISIBLE);
return;
}
subtitles.setText(Html.fromHtml(text.content));
subtitles.setVisibility(View.VISIBLE);
}
由于可以用HTML标记字幕以指定斜体,粗体或下划线,因此我们使用Html.fromHtml方法来适当设置文本并设置可见性。 如果文本为空,则视图将被隐藏。 整个过程由Async任务开始,该任务从Plex作为流检索字幕。
public class SubtitleAsyncTask extends AsyncTask<Void, Void, Void> {
@Override
protected Void doInBackground(Void... params) {
if (subtitleURL != null) {
try {
URL url = new URL(subtitleURL);
InputStream stream = url.openStream();
FormatSRT formatSRT = new FormatSRT();
srt = formatSRT.parseFile(stream);
subtitleDisplayHandler.post(subtitle);
} catch (Exception e) {
Log.e(getClass().getName(), e.getMessage(), e);
}
}
// TODO Auto-generated method stub
return null;
}
}
这只是读取流,并将SubRip(SRT)格式的字幕文件解析为TimedTextObject,然后启动处理程序。
重要的是要确保活动完成后,您要删除处理程序上的所有回调。 因此,请确保在您的onFinish方法中执行以下操作:
subtitleDisplayHandler.removeCallbacks(subtitle);
无论Android版本如何,它都可以正常工作。 它已经通过最新的JellyBean版本在Android 3.2上进行了测试。 如果您需要操纵字幕,使用它们或将其转换为其他格式,则可以尝试使用subtitleConverter项目。 希望通过Serenity for Google TV v1.1.0看到此支持。
翻译自: https://www.javacodegeeks.com/2013/04/android-google-tv-subtitle-support.html