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 影片擷取:瞭解如何使用 Camera2 API 設定 HDR 錄影功能。
- GitHub 上的 Camera2 影片範例:查看具備 HDR 擷取和播放功能的有效應用程式。
媒體
- 媒體 API 參考資料:進一步瞭解媒體 API。
- ExoPlayer:瞭解如何使用 ExoPlayer 程式庫設定應用程式。