ApsaraVideo Player SDK を使用すると、WebVTT、SRT、および ASS 形式の外部字幕ストリームを追加、解析、レンダリングできます。このソフトウェア開発キット (SDK) は、M3U8 ファイルに埋め込まれた字幕ストリームの解析とレンダリングもサポートしています。このトピックでは、Android および iOS プラットフォームでこの機能を実装する方法について説明します。
このトピックのすべてのコードと実装の詳細については、API-Example プロジェクトを参照し、ベストプラクティスに基づいて適応させてください。
具体的な実装については、このトピックのソリューションを使用し、対応する API-Example-Android および API-Example-iOS プロジェクトの ExternalSubtitle モジュールのソースコードを参照してください。
制限事項
WebVTT、SRT、および ASS 形式の外部字幕ファイルのみがサポートされています。
レンダリング例
レンダリングのために字幕ストリームをパッケージングするには、「複数字幕のトランスコーディングとパッケージングのベストプラクティス」をご参照ください。
Android での主要な実装
外部字幕のレンダリング
依存ライブラリをインポートします。
import com.aliyun.subtitle.SubTitleBase; import com.cicada.player.utils.webVtt.VttSubtitleView; import com.aliyun.player.IPlayer;表示ビューを設定します。
vttSubtitleView = new VttSubtitleView(getContext()); vttSubtitleView.setId(R.id.cicada_player_vtt_subtitle); // 字幕の表示位置を設定します。レイアウトの中央に追加します。 FrameLayout.LayoutParams params = new FrameLayout.LayoutParams( FrameLayout.LayoutParams.WRAP_CONTENT, FrameLayout.LayoutParams.WRAP_CONTENT ); params.gravity = Gravity.CENTER; // レイアウトの中央に追加します。 // VTT 字幕ビューをルートレイアウトビューに追加します。 mRootFrameLayout.addView(mVttSubtitleView, params);コールバックを設定します。
// 次の例では、mVideoListPlayer は listPlayer です。aliPlayer を使用する場合もプロセスは同じです。 // 1. OnSubtitleDisplayListener を設定します。 mVideoListPlayer.setOnSubtitleDisplayListener(new IPlayer.OnSubtitleDisplayListener() { @Override public void onSubtitleExtAdded(int trackIndex, String url) { // 単一の VTT ファイルの追加のみをテストしているため、VTT ファイルが追加された直後に字幕トラックを選択します。 mVideoListPlayer.selectExtSubtitle(trackIndex, true); } @Override public void onSubtitleShow(int trackIndex, long id, String data) { if (vttSubtitleView != null) { vttSubtitleView.show(id, data); } } @Override public void onSubtitleHide(int trackIndex, long id) { if (vttSubtitleView != null) { vttSubtitleView.dismiss(id); } } @Override public void onSubtitleHeader(int trackIndex, String header) { if (vttSubtitleView != null) { vttSubtitleView.setVttHeader(header); } } }); // 2. VideoSizeChangedListener を設定します。これは必須のステップです。データは vttSubtitleView に渡す必要があります。 mVideoListPlayer.setOnVideoSizeChangedListener(new IPlayer.OnVideoSizeChangedListener() { @Override public void onVideoSizeChanged(int width, int height) { int viewWidth = getWidth(); int viewHeight = getHeight(); IPlayer.ScaleMode mode = mVideoListPlayer.getScaleMode(); SubTitleBase.VideoDimensions videoDimensions = SubTitleBase.getVideoDimensionsWhenRenderChanged(width, height, viewWidth, viewHeight, mode); vttSubtitleView.setVideoRenderSize(videoDimensions.videoDisplayWidth, videoDimensions.videoDisplayHeight); } });プレーヤーが
prepare/moveTo/moveToNext/moveToPrev操作を実行した後、表示ビューをクリアします。source = getSource(someParams); // 擬似コード mVideoListPlayer.moveTo(mCurrentUUID + ""); if (vttSubtitleView != null) { vttSubtitleView.clearAll(); } if (!source.getExtSubtitleUrl().isEmpty()) { mCurrentExtSubtitle = source.getExtSubtitleUrl(); // 外部字幕の URL を取得します。 }プレーヤーの
onPreparedコールバックが呼び出された後、字幕ファイルを追加します。// 現在、addExtSubtitle はプレーヤーの onPrepared コールバックが呼び出された後にのみ呼び出すことができます。 mVideoListPlayer.addExtSubtitle(mCurrentExtSubtitle);
M3U8 パッケージ字幕のレンダリング
M3U8 パッケージ字幕と外部字幕を一緒にレンダリングしないでください。
依存ライブラリをインポートします。
import com.aliyun.subtitle.SubTitleBase; import com.cicada.player.utils.webVtt.VttSubtitleView; import com.aliyun.player.IPlayer;表示ビューを設定します。
vttSubtitleView = new VttSubtitleView(getContext()); vttSubtitleView.setId(R.id.cicada_player_vtt_subtitle); // 字幕の表示位置を設定します。レイアウトの中央に追加します。 FrameLayout.LayoutParams params = new FrameLayout.LayoutParams( FrameLayout.LayoutParams.WRAP_CONTENT, FrameLayout.LayoutParams.WRAP_CONTENT ); params.gravity = Gravity.CENTER; // レイアウトの中央に追加します。 // VTT 字幕ビューをルートレイアウトビューに追加します。 mRootFrameLayout.addView(mVttSubtitleView, params);コールバックを設定します。
// 次の例では、mVideoListPlayer は listPlayer です。aliPlayer を使用する場合もプロセスは同じです。 // 1. OnSubtitleDisplayListener を設定します。 mVideoListPlayer.setOnSubtitleDisplayListener(new IPlayer.OnSubtitleDisplayListener() { @Override public void onSubtitleExtAdded(int trackIndex, String url) { // 単一の VTT ファイルの追加のみをテストしているため、VTT ファイルが追加された直後に字幕トラックを選択します。 mVideoListPlayer.selectExtSubtitle(trackIndex, true); } @Override public void onSubtitleShow(int trackIndex, long id, String data) { if (vttSubtitleView != null) { vttSubtitleView.show(id, data); } } @Override public void onSubtitleHide(int trackIndex, long id) { if (vttSubtitleView != null) { vttSubtitleView.dismiss(id); } } @Override public void onSubtitleHeader(int trackIndex, String header) { if (vttSubtitleView != null) { vttSubtitleView.setVttHeader(header); } } }); // 2. VideoSizeChangedListener を設定します。これは必須のステップです。データは vttSubtitleView に渡す必要があります。 mVideoListPlayer.setOnVideoSizeChangedListener(new IPlayer.OnVideoSizeChangedListener() { @Override public void onVideoSizeChanged(int width, int height) { int viewWidth = getWidth(); int viewHeight = getHeight(); IPlayer.ScaleMode mode = mVideoListPlayer.getScaleMode(); SubTitleBase.VideoDimensions videoDimensions = SubTitleBase.getVideoDimensionsWhenRenderChanged(width, height, viewWidth, viewHeight, mode); vttSubtitleView.setVideoRenderSize(videoDimensions.videoDisplayWidth, videoDimensions.videoDisplayHeight); } });プレーヤーが
prepare/moveTo/moveToNext/moveToPrev操作を実行した後、表示ビューをクリアします。source = getSource(someParams); // 擬似コード mVideoListPlayer.moveTo(mCurrentUUID + ""); if (vttSubtitleView != null) { vttSubtitleView.clearAll(); } if (!source.getExtSubtitleUrl().isEmpty()) { mCurrentExtSubtitle = source.getExtSubtitleUrl(); // 外部字幕の URL を取得します。 }onTrackReadyコールバックを設定して、サブストリーム情報を取得します。mAliPlayer.setOnTrackReadyListener(new IPlayer.OnTrackReadyListener() { @Override public void onTrackReady(MediaInfo mediaInfo) { List<TrackInfo> trackInfos = mediaInfo.getTrackInfos(); for (TrackInfo trackInfo : trackInfos) { if (trackInfo.getType() == TrackInfo.Type.TYPE_SUBTITLE) { // TODO } } } });プレーヤーの
onPreparedコールバックが呼び出された後、selectTrackを呼び出して字幕トラックを切り替えます。// index はターゲット字幕ストリームの TrackIndex です。 mAliPlayer.selectTrack(index);
iOS での主要な実装
外部字幕のレンダリング
コールバックを設定します。
/** @brief 外部字幕が追加されます。 @param player プレーヤーポインター。 @param trackIndex 表示する字幕トラックのインデックス。 @param URL 字幕 URL。 */ - (void)onSubtitleExtAdded:(AliPlayer*)player trackIndex:(int)trackIndex URL:(NSString *)URL { NSLog(@"onSubtitleExtAdded: %@, trackIndex: %d", URL, trackIndex); [self.listPlayer selectExtSubtitle:trackIndex enable:YES]; }プレーヤーの
onPreparedコールバックが呼び出された後、字幕ファイルを追加します。if (self.currentModel.extSubtitleUrl != Nil) { [self.listPlayer addExtSubtitle:self.currentModel.extSubtitleUrl]; }
M3U8 パッケージ字幕のレンダリング
M3U8 パッケージ字幕と外部字幕を一緒にレンダリングしないでください。
コールバックを設定します。
/** @brief 外部字幕が追加されます。 @param player プレーヤーポインター。 @param trackIndex 表示する字幕トラックのインデックス。 @param URL 字幕 URL。 */ - (void)onSubtitleExtAdded:(AliPlayer*)player trackIndex:(int)trackIndex URL:(NSString *)URL { NSLog(@"onSubtitleExtAdded: %@, trackIndex: %d", URL, trackIndex); [self.listPlayer selectExtSubtitle:trackIndex enable:YES]; }onTrackReadyコールバックを設定して、サブストリーム情報を取得します。- (void)onTrackReady:(AliPlayer*)player info:(NSArray<AVPTrackInfo*>*)info { // }プレーヤーの
prepare doneコールバックが呼び出された後、selectTrackを呼び出して字幕トラックを切り替えます。// index はターゲット字幕ストリームの TrackIndex です。 [self.player selectTrack:index];
WebVTT ストリームに基づくカスタムレンダリングの実装
ApsaraVideo Player は、Android と iOS の両方で 標準 WebVTT ストリームの解析とレンダリングをサポートしています。プレーヤーは CSS スタイルを読み取り、両方のプラットフォームで統一された字幕スタイルを作成します。また、1 つのファイルで複数のテキストスタイルをサポートしているため、登場人物の対話を区別したり、重要なコンテンツを強調したり、特殊な視覚効果を作成したりするのに役立ちます。
次のコードは WebVTT ファイルの例を示しています:
REGION: 表示エリアを定義します。
STYLE: フォントスタイルを定義します。最初の項目はデフォルトのスタイルです。
WEBVTT
REGION
id:bottom
width:70.000000%
lines:3
viewportanchor:15.000000%,95.000000%
regionanchor:0.000000%,100.000000%
scroll:up
STYLE
::cue {
color: white;
font-size: 70%;
font-family: Noto Sans;
font-weight: bold;
background-color: rgba(0, 0, 0, 0.2);
}
::cue(.font1) {
color: rgba(255, 255, 255, 1);
font-weight: bold;
font-family: Noto Sans;
outline-width: 3px;
outline-color: rgba(0, 0, 0, 1);
}
::cue(.font2) {
color: rgba(252, 255, 101, 1);
font-style: bold;
font-family: Noto Sans;
outline-width: 3px;
outline-color: rgba(0, 0, 0, 1);
}
::cue(.font3) {
color: rgba(255, 191 23, 1);
font-style: bold;
font-family: Noto Sans;
outline-width: 3px;
outline-color: rgba(183, 28, 28, 1);
}
00:00:00.200 --> 00:00:01.800 region:bottom align:center
被告人 Bo Hanshi
00:00:01.800 --> 00:00:03.200 region:bottom align:center
他に何か言いたいことはありますか
00:00:04.100 --> 00:00:04.800 region:bottom align:center
私
00:00:11.200 --> 00:00:12.200 region:bottom align:center
<v.font1>何も言うことはありません</v.font1>
00:00:14.500 --> 00:00:16.200 region:bottom align:center
被告人 Bo Hanshi
...テキストセグメントにスタイルを指定するには、次の設定を使用します:
<v.font1>何も言うことはありません</v.font1>