MediaPlayer とデジタル著作権管理(DRM)を使用する

Android 8.0(API レベル 26)以降の MediaPlayer には、DRM で保護された素材の再生をサポートする API が含まれています。MediaPlayer DRM API は、MediaDrm で提供される低レベル API に似ていますが、より高いレベルで動作し、基礎となる Extractor オブジェクト、DRM オブジェクト、Crypto オブジェクトは公開されません。

MediaPlayer DRM API は、MediaDrm の機能をすべて提供するわけではありませんが、一般的な用途はサポートしています。現在の実装では、次のコンテンツ タイプを処理できます。

  • Widevine で保護されたローカル メディア ファイル
  • Widevine で保護されたリモートまたはストリーミング メディア ファイル

次のコード スニペットは、同期実装で新しい DRM MediaPlayer メソッドを使用する方法を示しています。

DRM で保護されたメディアを管理するには、次の例に示すように、MediaPlayer 呼び出しの通常のフローに新しいメソッドを含める必要があります。

Kotlin

mediaPlayer?.apply {
    setDataSource()
    setOnDrmConfigHelper() // optional, for custom configuration
    prepare()
    drmInfo?.also {
        prepareDrm()
        getKeyRequest()
        provideKeyResponse()
    }

    // MediaPlayer is now ready to use
    start()
    // ...play/pause/resume...
    stop()
    releaseDrm()
}

Java

setDataSource();
setOnDrmConfigHelper(); // optional, for custom configuration
prepare();
if (getDrmInfo() != null) {
  prepareDrm();
  getKeyRequest();
  provideKeyResponse();
}

// MediaPlayer is now ready to use
start();
// ...play/pause/resume...
stop();
releaseDrm();

まず、通常どおり setDataSource() を使用してソースの設定を行い、MediaPlayer オブジェクトを初期化します。次に、DRM を使用するため、以下の手順を行います。

  1. アプリでカスタム設定を使用する場合は、OnDrmConfigHelper インターフェースを定義し、これを setOnDrmConfigHelper() を使用してプレーヤーにアタッチします。
  2. prepare() を呼び出します。
  3. getDrmInfo() を呼び出します。ソースに DRM コンテンツが含まれる場合、このメソッドから null 以外の MediaPlayer.DrmInfo 値が返されます。

MediaPlayer.DrmInfo が存在する場合:

  1. 使用可能な UUID のマップを調べ、1 つを選択します。
  2. prepareDrm() を呼び出して、現在のソースに対する DRM 設定を準備します。
    • OnDrmConfigHelper コールバックを作成して登録した場合は、prepareDrm() の実行中にこのコールバックが呼び出されます。これにより、DRM セッションが開かれる前に DRM プロパティのカスタム設定を行えます。このコールバックは、prepareDrm() を呼び出したスレッドで同期的に呼び出されます。DRM プロパティにアクセスするには、getDrmPropertyString()setDrmPropertyString() を呼び出します。長時間の操作は避けてください。
    • デバイスがまだプロビジョニングされていない場合、prepareDrm() はプロビジョニング サーバーにアクセスしてデバイスのプロビジョニングを行います。これにかかる時間は、ネットワーク接続に依存します。
  3. ライセンス サーバーに送信する不透明なキーリクエスト バイト配列を取得するには、getKeyRequest() を呼び出します。
  4. ライセンス サーバーから受信したキーレスポンスについて DRM エンジンに通知するには、provideKeyResponse() を呼び出します。結果はキーリクエストのタイプによって異なります。
    • オフライン キーリクエストに対するレスポンスの場合、結果はキーセット ID になります。このキーセット ID を使用して restoreKeys() を呼び出すことにより、キーを新しいセッションに復元できます。
    • ストリーミングまたは解放のリクエストに対するレスポンスの場合、結果は null になります。

DRM を非同期で準備する

デフォルトでは、prepareDrm() は同期的に実行され、準備が完了するまで他はブロックされます。ただし、新しいデバイスにおける最初の DRM の準備では、prepareDrm() 内部でプロビジョニングの処理も必要になる場合があり、関連するネットワーク オペレーションによっては終了まで時間がかかる可能性があります。MediaPlayer.OnDrmPreparedListener を定義して設定することで、prepareDrm() でのブロックを回避できます。

OnDrmPreparedListener を設定します。prepareDrm() は、プロビジョニング(必要な場合)と準備をバックグラウンドで実行します。プロビジョニングと準備が完了すると、システムはリスナーを呼び出します。呼び出しの順序やリスナーが実行されるスレッドについては、いかなる想定もしないでください(リスナーをハンドラ スレッドに登録した場合を除く)。システムは、prepareDrm() が返される前または後にリスナーを呼び出すことができます。

DRM を非同期で設定する

DRM の準備には MediaPlayer.OnDrmInfoListener を、またプレーヤーの起動には MediaPlayer.OnDrmPreparedListener を作成して登録することにより、DRM を非同期で初期化できます。次の例に示すように、これらは prepareAsync() と連携して動作します。

Kotlin

setOnPreparedListener()
setOnDrmInfoListener()
setDataSource()
prepareAsync()
// ...

// If the data source content is protected you receive a call to the onDrmInfo() callback.
override fun onDrmInfo(mediaPlayer: MediaPlayer, drmInfo: MediaPlayer.DrmInfo) {
    mediaPlayer.apply {
        prepareDrm()
        getKeyRequest()
        provideKeyResponse()
    }
}

// When prepareAsync() finishes, you receive a call to the onPrepared() callback.
// If there is a DRM, onDrmInfo() sets it up before executing this callback,
// so you can start the player.
override fun onPrepared(mediaPlayer: MediaPlayer) {
    mediaPlayer.start()
}

Java

setOnPreparedListener();
setOnDrmInfoListener();
setDataSource();
prepareAsync();
// ...

// If the data source content is protected you receive a call to the onDrmInfo() callback.
onDrmInfo() {
  prepareDrm();
  getKeyRequest();
  provideKeyResponse();
}

// When prepareAsync() finishes, you receive a call to the onPrepared() callback.
// If there is a DRM, onDrmInfo() sets it up before executing this callback,
// so you can start the player.
onPrepared() {

start();
}

暗号化されたメディアを処理する

Android 8.0(API レベル 26)以降の MediaPlayer では、共通暗号化スキーム(CENC)と、基本的なストリーミング タイプである H.264 および AAC 用の HLS サンプルレベル暗号化メディア(METHOD=SAMPLE-AES)の復号も可能です。以前は、フルセグメント暗号化メディア(METHOD=AES-128)がサポートされていました。

詳細

アプリでのメディア再生には、Jetpack Media3 が推奨されるソリューションです。詳しくは、こちらをご覧ください。

以下は音声と動画の録音、録画、保存、再生に関するトピックを扱うページです。