使用 CastPlayer 更改字幕
Change subtitle using CastPlayer
我有一个 HLS 直播,它由指向清单文件的 URI 表示。
清单文件确实另外定义了字幕。
使用 ExoPlayer 时,我可以使用 TrackSelector,将其附加到 ExoPlayer,这样我就可以选择向用户显示可用的字幕(并通过 TrackSelector 进行更改)。
我只想对 CastPlayer 执行相同的操作。这是我能想到的最简单的 Activity:
public class PlayerActivity extends AppCompatActivity implements SessionAvailabilityListener {
private MediaRouteButton castButton;
private CastPlayer castPlayer;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.player_activity);
castButton = findViewById(R.id.castButton);
CastButtonFactory.setUpMediaRouteButton(this, castButton);
CastContext castContext = CastContext.getSharedInstance(this);
castPlayer = new CastPlayer(castContext);
castPlayer.setSessionAvailabilityListener(this);
}
@Override
public void onCastSessionAvailable() {
MediaMetadata movieMetadata = new MediaMetadata(MediaMetadata.MEDIA_TYPE_MOVIE);
MediaInfo mediaInfo = new MediaInfo.Builder("https://myuri.ch/video.m3u8")
.setStreamType(MediaInfo.STREAM_TYPE_BUFFERED)
.setMetadata(movieMetadata)
.build();
MediaQueueItem mediaItem = new MediaQueueItem.Builder(mediaInfo).build();
castPlayer.loadItems(new MediaQueueItem[]{mediaItem}, 0, 0, Player.REPEAT_MODE_OFF);
}
@Override
public void onCastSessionUnavailable() {
}
}
布局如下所示:
<androidx.mediarouter.app.MediaRouteButton
android:id="@+id/castButton"
android:layout_alignParentEnd="true"
android:layout_alignParentTop="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</androidx.mediarouter.app.MediaRouteButton>
此 activity 启动,当我按下 castButton 时,它会将“https://myuri.ch/video.m3u8”后面的电影流式传输到投射设备。完美运行:)
但我不知道如何让用户从我的应用程序中选择字幕。我们应该如何实现这样的想法?
我已经发现的要点:
- 我无法将 TrackSelector 之类的东西附加到 CastPlayer
- 文档指出我们可以为 MediaInfo 对象提供 MediaTrack。但是我没有这个信息,它分别隐藏在 m3u8 文件中。
作为附加信息,我的 CastOptions 如下所示:
public class CastOptionsProvider implements OptionsProvider {
@Override
public CastOptions getCastOptions(Context appContext) {
return new CastOptions.Builder()
.setReceiverApplicationId(CastMediaControlIntent.DEFAULT_MEDIA_RECEIVER_APPLICATION_ID)
.build();
}
@Override
public List<SessionProvider> getAdditionalSessionProviders(Context context) {
return null;
}
}
这是我发现的:
- CastPlayer 不能使用 TrackSelector。
- 在将 MediaItems 加载到 CastPlayer 之前,所有可用的字幕都必须 available/known
- DefaultMediaReceiver 需要一个 public 可用的 link *.vtt 文件。不同的东西不起作用(没有 .webvtt 也没有 .m3u8)
- 在 ExoPlayer 上更新字幕的最简单方法似乎是这样的:
DefaultTrackSelector.ParametersBuilder parametersBuilder = trackSelector.getParameters()
.buildUpon()
.setRendererDisabled(getRendererIndex(C.TRACK_TYPE_TEXT), !hasSubtitles);
if (hasSubtitles) {
parametersBuilder.setPreferredTextLanguage("en").build();
}
getRendererIndex 在哪里:
public int getRendererIndex(final int trackType) {
for (int t = 0; t < exoPlayer.getRendererCount(); t++) {
if (exoPlayer.getRendererType(t) == trackType) {
return t;
}
}
return -1;
}
- 要select CastPlayer 上的字幕,您可以使用 RemoteMediaClient
remoteMediaClient.setActiveMediaTracks(selectedSubtitleTracks);
所以我的解决方案是这样的:
- 在开始任何流(本地或演员)之前获取我需要的 MediaItem 的所有信息(url、字幕、...)
- 根据 Cast-Session 的可用性,我将 MediaItems 加载到 CastPlayer 或 ExoPlayer
- 自定义字幕对话框让用户可以选择 select 字幕
- 当用户select播放字幕时,我使用上述方法select正确播放字幕。
我有一个 HLS 直播,它由指向清单文件的 URI 表示。 清单文件确实另外定义了字幕。
使用 ExoPlayer 时,我可以使用 TrackSelector,将其附加到 ExoPlayer,这样我就可以选择向用户显示可用的字幕(并通过 TrackSelector 进行更改)。
我只想对 CastPlayer 执行相同的操作。这是我能想到的最简单的 Activity:
public class PlayerActivity extends AppCompatActivity implements SessionAvailabilityListener {
private MediaRouteButton castButton;
private CastPlayer castPlayer;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.player_activity);
castButton = findViewById(R.id.castButton);
CastButtonFactory.setUpMediaRouteButton(this, castButton);
CastContext castContext = CastContext.getSharedInstance(this);
castPlayer = new CastPlayer(castContext);
castPlayer.setSessionAvailabilityListener(this);
}
@Override
public void onCastSessionAvailable() {
MediaMetadata movieMetadata = new MediaMetadata(MediaMetadata.MEDIA_TYPE_MOVIE);
MediaInfo mediaInfo = new MediaInfo.Builder("https://myuri.ch/video.m3u8")
.setStreamType(MediaInfo.STREAM_TYPE_BUFFERED)
.setMetadata(movieMetadata)
.build();
MediaQueueItem mediaItem = new MediaQueueItem.Builder(mediaInfo).build();
castPlayer.loadItems(new MediaQueueItem[]{mediaItem}, 0, 0, Player.REPEAT_MODE_OFF);
}
@Override
public void onCastSessionUnavailable() {
}
}
布局如下所示:
<androidx.mediarouter.app.MediaRouteButton
android:id="@+id/castButton"
android:layout_alignParentEnd="true"
android:layout_alignParentTop="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</androidx.mediarouter.app.MediaRouteButton>
此 activity 启动,当我按下 castButton 时,它会将“https://myuri.ch/video.m3u8”后面的电影流式传输到投射设备。完美运行:)
但我不知道如何让用户从我的应用程序中选择字幕。我们应该如何实现这样的想法?
我已经发现的要点:
- 我无法将 TrackSelector 之类的东西附加到 CastPlayer
- 文档指出我们可以为 MediaInfo 对象提供 MediaTrack。但是我没有这个信息,它分别隐藏在 m3u8 文件中。
作为附加信息,我的 CastOptions 如下所示:
public class CastOptionsProvider implements OptionsProvider {
@Override
public CastOptions getCastOptions(Context appContext) {
return new CastOptions.Builder()
.setReceiverApplicationId(CastMediaControlIntent.DEFAULT_MEDIA_RECEIVER_APPLICATION_ID)
.build();
}
@Override
public List<SessionProvider> getAdditionalSessionProviders(Context context) {
return null;
}
}
这是我发现的:
- CastPlayer 不能使用 TrackSelector。
- 在将 MediaItems 加载到 CastPlayer 之前,所有可用的字幕都必须 available/known
- DefaultMediaReceiver 需要一个 public 可用的 link *.vtt 文件。不同的东西不起作用(没有 .webvtt 也没有 .m3u8)
- 在 ExoPlayer 上更新字幕的最简单方法似乎是这样的:
DefaultTrackSelector.ParametersBuilder parametersBuilder = trackSelector.getParameters()
.buildUpon()
.setRendererDisabled(getRendererIndex(C.TRACK_TYPE_TEXT), !hasSubtitles);
if (hasSubtitles) {
parametersBuilder.setPreferredTextLanguage("en").build();
}
getRendererIndex 在哪里:
public int getRendererIndex(final int trackType) {
for (int t = 0; t < exoPlayer.getRendererCount(); t++) {
if (exoPlayer.getRendererType(t) == trackType) {
return t;
}
}
return -1;
}
- 要select CastPlayer 上的字幕,您可以使用 RemoteMediaClient
remoteMediaClient.setActiveMediaTracks(selectedSubtitleTracks);
所以我的解决方案是这样的:
- 在开始任何流(本地或演员)之前获取我需要的 MediaItem 的所有信息(url、字幕、...)
- 根据 Cast-Session 的可用性,我将 MediaItems 加载到 CastPlayer 或 ExoPlayer
- 自定义字幕对话框让用户可以选择 select 字幕
- 当用户select播放字幕时,我使用上述方法select正确播放字幕。