MediaTrack
はメディア トラックを表します。これは、音声ストリーム、動画ストリーム、テキスト(字幕など)のいずれかです。メディア トラックのグループ化、スタイル設定、有効化を行えます。
トラックを設定する
トラックを設定して一意の ID を割り当てることができます。次のコードは、英語のテキスト トラック、フランス語のテキスト トラック、フランス語の音声トラックをそれぞれ固有の ID で作成します。
val englishSubtitle = MediaTrack.Builder(1 /* ID */, MediaTrack.TYPE_TEXT) .setName("English Subtitle") .setSubtype(MediaTrack.SUBTYPE_SUBTITLES) .setContentId("https://some-url/caption_en.vtt") /* language is required for subtitle type but optional otherwise */ .setLanguage("en-US") .build() val frenchSubtitle = MediaTrack.Builder(2, MediaTrack.TYPE_TEXT) .setName("French Subtitle") .setSubtype(MediaTrack.SUBTYPE_SUBTITLES) .setContentId("https://some-url/caption_fr.vtt") .setLanguage("fr") .build() val frenchAudio = MediaTrack.Builder(3, MediaTrack.TYPE_AUDIO) .setName("French Audio") .setContentId("trk0001") .setLanguage("fr") .build()
MediaTrack englishSubtitle = new MediaTrack.Builder(1 /* ID */, MediaTrack.TYPE_TEXT) .setName("English Subtitle") .setSubtype(MediaTrack.SUBTYPE_SUBTITLES) .setContentId("https://some-url/caption_en.vtt") /* language is required for subtitle type but optional otherwise */ .setLanguage("en-US") .build(); MediaTrack frenchSubtitle = new MediaTrack.Builder(2, MediaTrack.TYPE_TEXT) .setName("French Subtitle") .setSubtype(MediaTrack.SUBTYPE_SUBTITLES) .setContentId("https://some-url/caption_fr.vtt") .setLanguage("fr") .build(); MediaTrack frenchAudio = new MediaTrack.Builder(3, MediaTrack.TYPE_AUDIO) .setName("French Audio") .setContentId("trk0001") .setLanguage("fr") .build();
グループ トラック
複数のトラックを MediaInfo
で表されるメディア アイテムにグループ化できます。MediaInfo
のインスタンスはトラックの配列を受け取り、メディア アイテムに関するその他の情報を集約します。この例に基づいて、アプリは 3 つのメディア トラックのリストを MediaInfo.Builder.setMediaTracks(List)
に渡すことで、これら 3 つのメディア トラックのリストをメディア アイテムに追加できます。アプリは、レシーバーにメディアを読み込む前に、この方法でトラックを MediaInfo
に関連付ける必要があります。
val tracks: MutableList<MediaTrack> = ArrayList<MediaTrack>() tracks.add(englishSubtitle) tracks.add(frenchSubtitle) tracks.add(frenchAudio) val mediaInfo = MediaInfo.Builder(url) .setStreamType(MediaInfo.STREAM_TYPE_BUFFERED) .setContentType(getContentType()) .setMetadata(getMetadata()) .setMediaTracks(tracks) .build()
List tracks = new ArrayList(); tracks.add(englishSubtitle); tracks.add(frenchSubtitle); tracks.add(frenchAudio); MediaInfo mediaInfo = MediaInfo.Builder(url) .setStreamType(MediaInfo.STREAM_TYPE_BUFFERED) .setContentType(getContentType()) .setMetadata(getMetadata()) .setMediaTracks(tracks) .build();
トラックを削除
現在のメディアからすべてのトラックを削除するには(この例で 3 つの字幕をオフにするなど)、MediaInfo.Builder.setMediaTracks(List)
を呼び出して、ID の空のリストを渡します。
トラックを更新
アプリでは、RemoteMediaClient.setActiveMediaTracks(long[])
を呼び出して有効にするトラックの ID を渡すことで、メディア アイテムに関連付けられた 1 つ以上のトラックを有効にできます(メディアが読み込まれた後)。以下のサンプルでは、フランス語のサブタイトルとフランス語の音声を有効にしています。
// the ID for the French subtitle is '2' and for the French audio '3' remoteMediaClient.setActiveMediaTracks(longArrayOf(2, 3)) .setResultCallback(ResultCallback { mediaChannelResult: RemoteMediaClient.MediaChannelResult -> if (!mediaChannelResult.status.isSuccess) { Log.e(TAG, "Failed with status code:" + mediaChannelResult.status.statusCode ) } })
// the ID for the French subtitle is '2' and for the French audio '3' remoteMediaClient.setActiveMediaTracks(new long[]{2, 3}) .setResultCallback(mediaChannelResult -> { if (!mediaChannelResult.getStatus().isSuccess()) { Log.e(TAG, "Failed with status code:" + mediaChannelResult.getStatus().getStatusCode()); } });
テキスト トラックのスタイルを設定する
TextTrackStyle
は、テキスト トラックのスタイル情報をカプセル化します。既存の TextTrackStyle を作成または更新した後、次のように RemoteMediaClient.setTextTrackStyle
を呼び出すことで、現在再生中のメディア アイテムにそのスタイルを適用できます。
// the ID for the French subtitle is '2' and for the French audio '3' remoteMediaClient.setTextTrackStyle(style) .setResultCallback(ResultCallback { mediaChannelResult: RemoteMediaClient.MediaChannelResult -> if (!mediaChannelResult.status.isSuccess) { Log.e(TAG, "Failed to set the style, status code: " + mediaChannelResult.status.statusCode ) } })
remoteMediaClient.setTextTrackStyle(style) .setResultCallback(mediaChannelResult -> { if (!mediaChannelResult.getStatus().isSuccess()) { Log.e(TAG, "Failed to set the style, status code: " + mediaChannelResult.getStatus().getStatusCode()); } });
アプリでは、システムが提供する設定またはアプリ自体の設定を使用して、ユーザーがテキスト トラックのスタイルを更新できるようにする必要があります。Android KitKat 以降では、フレームワークにより提供されるシステム全体の字幕設定を使用できます。
val textTrackStyle = TextTrackStyle.fromSystemSettings(context)
TextTrackStyle textTrackStyle = TextTrackStyle.fromSystemSettings(context);
KitKat より前のバージョンの場合、上記の呼び出しはフィールドが未定義のオブジェクトを返すため、ユーザーの選択と一部のデフォルト値に基づいて、アプリのフィールドに入力する必要があります。次のテキスト トラックのスタイル要素を設定できます。
- 前景(テキスト)の色と不透明度
- 背景の色と透明度
- エッジの種類
- エッジの色
- フォント スケール
- フォント ファミリー
- フォント スタイル
たとえば、次のようにテキストの色を赤(FF)、不透明度 50%(80)に設定します。
textTrackStyle.foregroundColor = Color.parseColor("#80FF0000")
textTrackStyle.setForegroundColor(Color.parseColor("#80FF0000"));
KitKat 以降のバージョンでは、システム全体の字幕設定が更新されたときに通知されるようにアプリを登録する必要があります。そのためには、アプリに CaptioningManager.CaptioningChangeListener
を実装し、以下を呼び出してこのリスナーを登録する必要があります。
CaptioningManager.addCaptioningChangeListener(yourChangeListener)
CaptioningManager.addCaptioningChangeListener(yourChangeListener);
字幕設定の変更に関するコールバックをアプリが受け取ったら、新しい設定を抽出し、RemoteMediaClient.setTextTrackStyle
を呼び出して新しいスタイルを渡して、現在再生中のメディアのテキスト キャプションのスタイルを更新する必要があります。
最新ステータスの受信
複数のセンダーが同じレシーバに接続されている場合、他のセンダーから変更が開始されたとしても、各センダーがレシーバの変更を認識することが重要です。
そのためには、アプリで RemoteMediaClient.Listener
と RemoteMediaClient.ProgressListener
を登録する必要があります。
現在のメディアの TextTrackStyle
が変更されると、接続されているすべてのセンダーが、上記の両方の登録済みリスナーを通じて通知されます。この場合、レシーバ SDK は新しいスタイルが以前のスタイルと異なるかどうかを検証せず、接続されているすべての送信者に通知します。ただし、アクティブなトラックのステータスが変化すると、接続されている送信者の RemoteMediaClient.ProgressListener
のみが通知されます。
CORS 要件を満たす
アダプティブなメディア ストリーミングの場合、Google Cast には CORS ヘッダーの存在が必要ですが、シンプルな mp4 メディア ストリームであっても Tracks が含まれている場合は CORS が必要です。メディアに対してトラックを有効にするには、トラック ストリームとメディア ストリームの両方で CORS を有効にする必要があります。そのため、サーバーでシンプルな mp4 メディアで使用できる CORS ヘッダーがなく、その後に単純な字幕トラックを追加した場合、適切な CORS ヘッダーを含めるようにサーバーを更新しない限り、メディアをストリーミングできません。少なくとも Content-Type、Accept-Encoding、Range の各ヘッダーを許可する必要があります。最後の 2 つのヘッダーは、以前は必要でなかった追加のヘッダーです。