2. ストリーミング再生
JWT URL を使用してコンテンツをデバイスに直接リアルタイムストリーミング再生する方法を説明します。 ローカルにダウンロードされたコンテンツの再生とは異なり、ストリーミング時には再生のたびにお客様のサーバーから新たに発行された一回限り(One-time)の URL を使用します。
このドキュメントのすべてのサンプルコードは、公式サンプルアプリ kollus_player_v2_android をもとに作成されています。
コンテンツ配信方式
Kollus サービスはチャンネル設定に応じて、3 つの配信方式のいずれかでコンテンツを提供します。
アプリケーションクライア ントレイヤーでは、同じ JWT URL を受け取り setDataSourceByUrl メソッドで再生するため、別途のコード分岐を実装する必要はありません。
ただし、配信方式によって ABR の動作方式や DRM 検証・ライセンス発行フローが異なるため、インフラのチャンネル構成を把握しておくとデバッグと最適化に役立ちます。
| 配信方式 | デフォルト | 説明 | チャンネル設定 |
|---|---|---|---|
| MP4 Progressive Download | ◯ | 単一の MP4 ファイルをリアルタイムでダウンロードしながら同時に再生します。可変ビットレート(ABR)をサポートしない単一品質方式です。 | 別途設定なし(デフォルトチャンネル) |
| HLS ストリーミング | - | マニフェスト(.m3u8)とセグメントファイルで構成されます。ネットワーク帯域幅の変化に応じてリアルタイムでビットレート品質が自動切り替え(ABR)されます。 | コンソールのチャンネル設定で HLS 出力を有効化 |
| Multi-DRM (Widevine/PlayReady) | - | HLS または DASH 構造に DRM セキュリティライセンス発行フローを組み合わせた形式です。Widevine L1 / L3 デバイスセキュリティレベルを検証します。 | コンソールのチャンネル設定で DRM ポリシーを登録 |
アプリケーションのソースコードでは、mMediaPlayer.setDataSourceByUrl(jwtUrl, null) メソッドを呼び出すだけで 3 つの方式すべてを再生できます。
実際のストリーミング配信方式は Kollus サーバー側がチャンネル設定に基づいて決定し、クライアントに配信します。
配信方式の詳細比較
| 比較項目 | MP4 Progressive Download | HLS ストリーミング | Multi-DRM |
|---|---|---|---|
| ABR オプション制御 | 帯域幅設定の影響なし | setInitialBandwidth などの調整オプションが正常適用 | setInitialBandwidth などの調整オプションが正常適用 |
| シーク動作 | HTTP Byte-Range リクエストベースの制御 | セグメント単位の位置シーク | セグメント単位の位置シーク |
| デバイスレベル検証 | ハードウェアセキュリティ検証ステップなし | ハードウェアセキュリティ検証ステップなし | デバイスセキュリティレベル検証(Widevine L1 仕様が必須適用のコンテンツ運用が 可能) |
extraDrmParam 指定 | null で渡す | null で渡す | 通常は null を指定(トークン内部の DRM ポリシーが優先。動的パラメーターが必要な特殊環境でのみ渡す) |
ほとんどのお客様はサービス初期段階で MP4 Progressive 方式から始め、トラフィックが増加する際や可変ビットレート(ABR)環境が必要な際に HLS ストリーミングに移行します。 その後、著作権保護および DRM セキュリティが必須のコンテンツに限り Multi-DRM チャンネルを追加で分離して運用するパターンが一般的です。
基本ストリーミング再生
KollusPlayer SDK の MediaPlayer インスタンスにレンダリングする画面(Surface)を指定し、発行された JWT URL を設定してリアルタイムストリーミング再生を開始します。
// Example streaming implementation inside VideoView.openVideo()
mMediaPlayer.setScreenOnWhilePlaying(true);
// 1. Surface binding based on screen component type (TextureView or SurfaceView)
if (mSurfaceView instanceof TextureView) {
TextureView tv = (TextureView) mSurfaceView;
Surface surface = new Surface(tv.getSurfaceTexture());
mMediaPlayer.setSurface(surface);
} else if (mSurfaceView instanceof SurfaceView) {
mMediaPlayer.setDisplay(((SurfaceView) mSurfaceView).getHolder());
}
// 2. Set detailed ABR control options (specify if needed)
mMediaPlayer.setInitialBandwidth(0); // 0: auto-estimate initial bandwidth
mMediaPlayer.setMinDurationForQualityIncreaseMs(1000); // Minimum stable duration (ms) required before increasing ABR bitrate quality
// 3. Set data source (JWT URL)
String extraDrmParam = null;
mMediaPlayer.setDataSourceByUrl(jwtUrl, extraDrmParam); // jwtUrl example: https://v.jp.kollus.com/s?jwt=...
mMediaPlayer.prepareAsync();
prepareAsync() メソッドが呼び出されると、プレイヤー内部の状態が STATE_PREPARING に移行し、ストリーミングの初期バッファ準備が完了した時点で OnPreparedListener.onPrepared() が呼び出されます。
レンダリング Surface の設定
| 種類 | 特徴 | 推奨シナリオ |
|---|---|---|
SurfaceView | 軽量な出力パス、低い GPU 合成コスト | 一般的な全画面再生 |
TextureView | 回転・透明度・ブレンディングなど View 変換が可能 | UI 上のオーバーレイ再生、PIP など |
// SurfaceView
mMediaPlayer.setDisplay(((SurfaceView) view).getHolder());
// TextureView
Surface surface = new Surface(((TextureView) view).getSurfaceTexture());
mMediaPlayer.setSurface(surface);
DRM コンテンツのストリーミング
受け取った JWT URL 内に DRM 制約ポリシーが含まれている場合、SDK が DRM ライセンスの検証および更新プロセスを自動的に実行します。
開発レイヤーでの別途パラメーター設定なしに setDataSourceByUrl(jwtUrl, null) メソッドの呼び出しだけで DRM ストリーミングが開始されます。
アダプティブビットレート(ABR)調整オプション
ABR オプションは HLS ストリーミングおよび Multi-DRM チャンネルでのみ有効です。デフォルトの MP4 Progressive Download チャンネルでは単一の固定ビットレートでメディアが配信されるため、以下の設定値はすべて無視されます。
| API | 説明 |
|---|---|
setInitialBandwidth(bps) | 初期マニフェストロード時点の帯域幅推定値(bps)を指定します。0 を指定すると SDK が自動的に推定します。 |
setMinDurationForQualityIncreaseMs(ms) | 上位品質に切り替えるために現在の帯域幅が安定して維持される必要がある時間(ms)です。一般的な環境では 1000ms を推奨します。 |
公式サンプルアプリは、前回の再生セッションの平均ネットワーク帯域幅データを SharedPreferences に記録しておき、
次回のストリーミング初期化時に setInitialBandwidth メソッドのパラメーターとして渡すことで、初期バッファリングの待ち時間を最適化するパターンを使用しています。
プレイヤーイベントリスナー
メディア状態変化イベントおよびプレイヤー制御シグナルを受信するために、MediaPlayer インスタンスにリスナーオブジェクトを登録します。
mMediaPlayer.setOnPreparedListener(mPreparedListener);
mMediaPlayer.setOnCompletionListener(mCompletionListener);
mMediaPlayer.setOnErrorListener(mErrorListener);
mMediaPlayer.setOnInfoListener(mInfoListener);
mMediaPlayer.setOnBufferingUpdateListener(mBufferingUpdateListener);
mMediaPlayer.setOnSeekCompleteListener(mSeekCompleteListener);
mMediaPlayer.setOnVideoSizeChangedListener(mSizeChangedListener);
mMediaPlayer.setOnTimedTextDetectListener(mOnTimedTextDetectListener);
mMediaPlayer.setOnTimedTextListener(mOnTimedTextListener);
mMediaPlayer.setOnExternalDisplayDetectListener(mOnExternalDisplayDetectListener);
mMediaPlayer.setKollusPlayerBookmarkListener(mKollusPlayerBookmarkListener);
mMediaPlayer.setCaptureDetectListener(mCaptureDetectListener);
mMediaPlayer.setEmulatorCheckerListener(mEmulatorCheckListener);
| リスナー | 役割 |
|---|---|
OnPreparedListener | ストリーミング準備完了(start() を安全に呼び出せるタイミング) |
OnCompletionListener | コンテンツ末尾まで再生完了 |
OnErrorListener | 再生中にエラー発生(what および extra コードで原因分析) |
OnInfoListener | 付随的な状態情報の変化(バッファリング開始・終了、メディア情報変更など) |
OnBufferingUpdateListener | バッファリング進捗(0〜100) |
OnSeekCompleteListener | シーク完了 |
OnVideoSizeChangedListener | 映像解像度変更 |
OnTimedTextDetectListener / OnTimedTextListener | 字幕トラック検出 / 字幕表示 |
OnExternalDisplayDetectListener |