HDR(ハイ ダイナミック レンジ)では、より幅広い色彩と 最も明るい白と最も暗いシャドウのコントラストをつけ、 人間の目で見たものによく似たものになります
アプリで HDR 動画再生を設定すると、HDR 動画のプレビューと再生ができます 説明します。
この記事は、基本的な動画再生サポートが 説明します。詳しくは、ExoPlayer のドキュメントをご覧ください。 再生に関する詳細が表示されます。
デバイスの前提条件
すべての Android デバイスが HDR 再生をサポートしているわけではありません。HDR 再生前 追加するには、デバイスが次の要件を満たしているかどうかを判断します。 前提条件:
- Android 7.0 以降(API レイヤ 24)をターゲットとする。
- HDR 対応デコーダと HDR 対応ディスプレイにアクセスできる。
HDR 再生のサポートを確認する
Display.getHdrCapabilities()
を使用して、ディスプレイの HDR 機能をクエリします。このメソッドは、ディスプレイでサポートされている HDR プロファイルと輝度範囲に関する情報を返します。
次のコードは、デバイスが HLG10 再生をサポートしているかどうかを確認します。Android 13 以降では、デバイスが HDR 再生に対応している場合に、デバイス メーカーがサポートする必要がある最小規格が HLG10 です。
Kotlin
// Check if display supports the HDR type val capabilities = display?.hdrCapabilities?.supportedHdrTypes ?: intArrayOf() if (!capabilities.contains(HDR_TYPE_HLG)) { throw RuntimeException("Display does not support desired HDR type"); }
Java
// Check if display supports the HDR type int[] list = getDisplay().getHdrCapabilities().getSupportedHdrTypes(); Listcapabilities = Arrays.stream(list).boxed().collect(Collectors.toList()); if (!capabilities.contains(HDR_TYPE_HLG)) { throw new RuntimeException("Display does not support desired HDR type"); }
アプリで HDR 再生を設定する
ExoPlayer を使用するアプリは、デフォルトで HDR 再生をサポートします。次のステップについては、HDR 再生のサポートを確認するをご覧ください。
アプリで ExoPlayer を使用していない場合は、SurfaceView
で MediaCodec
を使用して HDR 再生を設定します。
SurfaceView を使用して MediaCodec を設定する
SurfaceView
を使用して標準の MediaCodec
再生フローを設定します。これにより、HDR 再生の特別な処理を行うことなく、HDR 動画コンテンツを表示できます。
MediaCodec
: HDR 動画コンテンツをデコードします。SurfaceView
: HDR 動画コンテンツを表示します。
次のコードは、コーデックが HDR プロファイルをサポートしているかどうかを確認し、SurfaceView
を使用して MediaCodec
を設定します。
Kotlin
// Check if there's a codec that supports the specific HDR profile val list = MediaCodecList(MediaCodecList.REGULAR_CODECS) var format = MediaFormat() /* media format from the container */; format.setInteger(MediaFormat.KEY_PROFILE, MediaCodecInfo.CodecProfileLevel.AV1ProfileMain10) val codecName = list.findDecoderForFormat (format) ?: throw RuntimeException ("No codec supports the format") // Here is a standard MediaCodec playback flow val codec: MediaCodec = MediaCodec.createByCodecName(codecName); val surface: Surface = surfaceView.holder.surface val callback: MediaCodec.Callback = (object : MediaCodec.Callback() { override fun onInputBufferAvailable(codec: MediaCodec, index: Int) { queue.offer(index) } override fun onOutputBufferAvailable( codec: MediaCodec, index: Int, info: MediaCodec.BufferInfo ) { codec.releaseOutputBuffer(index, timestamp) } override fun onError(codec: MediaCodec, e: MediaCodec.CodecException) { // handle error } override fun onOutputFormatChanged( codec: MediaCodec, format: MediaFormat ) { // handle format change } }) codec.setCallback(callback) codec.configure(format, surface, crypto, 0 /* flags */) codec.start() while (/* until EOS */) { val index = queue.poll() val buffer = codec.getInputBuffer(index) buffer?.put(/* write bitstream */) codec.queueInputBuffer(index, offset, size, timestamp, flags) } codec.stop() codec.release()
Java
// Check if there's a codec that supports the specific HDR profile MediaCodecList list = new MediaCodecList(MediaCodecList.REGULAR_CODECS); MediaFormat format = /* media format from the container */; format.setInteger( MediaFormat.KEY_PROFILE, CodecProfileLevel.AV1ProfileMain10); String codecName = list.findDecoderForFormat(format); if (codecName == null) { throw new RuntimeException("No codec supports the format"); } // Below is a standard MediaCodec playback flow MediaCodec codec = MediaCodec.getCodecByName(codecName); Surface surface = surfaceView.getHolder().getSurface(); MediaCodec.Callback callback = new MediaCodec.Callback() { @Override void onInputBufferAvailable(MediaCodec codec, int index) { queue.offer(index); } @Override void onOutputBufferAvailable(MediaCodec codec, int index) { // release the buffer for render codec.releaseOutputBuffer(index, timestamp); } @Override void onOutputFormatChanged(MediaCodec codec, MediaFormat format) { // handle format change } @Override void onError(MediaCodec codec, MediaCodec.CodecException ex) { // handle error } }; codec.setCallback(callback); codec.configure(format, surface, crypto, 0 /* flags */); codec.start(); while (/* until EOS */) { int index = queue.poll(); ByteBuffer buffer = codec.getInputBuffer(index); buffer.put(/* write bitstream */); codec.queueInputBuffer(index, offset, size, timestamp, flags); } codec.stop(); codec.release();
SurfaceView
を使用したその他の MediaCodec
の実装については、Android カメラのサンプルをご覧ください。
リソース
HDR 再生について詳しくは、次のリソースをご覧ください。
HDR
- HDR 動画キャプチャ: Camera2 API を使用して HDR 動画キャプチャを設定する方法について説明します。
- GitHub の Camera2Video のサンプル: HDR のキャプチャと再生の機能を持つ動作中のアプリをご覧ください。
メディア
- Media API リファレンス: Media API の詳細を確認できます。
- ExoPlayer: ExoPlayer ライブラリを使用してアプリをセットアップする方法を学びます。