HDR, или расширенный динамический диапазон, обеспечивает более широкий диапазон цветов и большую контрастность между самыми яркими белыми и самыми темными тенями, в результате чего качество видео больше соответствует тому, что воспринимает невооруженный глаз.
Вы можете настроить воспроизведение видео HDR в своем приложении для предварительного просмотра и воспроизведения видеоконтента HDR.
В этой статье предполагается, что вы уже добавили в свое приложение базовую поддержку воспроизведения видео. Дополнительную информацию о воспроизведении см. в документации ExoPlayer .
Предварительные требования к устройству
Не все устройства Android поддерживают воспроизведение HDR. Прежде чем воспроизводить видеоконтент HDR в приложении, определите, соответствует ли ваше устройство следующим предварительным требованиям:
- Предназначен для Android 7.0 или более поздней версии (уровень API 24).
- Имеет декодер с поддержкой HDR и доступ к дисплею с поддержкой HDR.
Проверьте поддержку воспроизведения HDR
Используйте Display.getHdrCapabilities()
для запроса возможностей HDR дисплея. Метод возвращает информацию о поддерживаемых профилях HDR и диапазоне яркости дисплея.
Следующий код проверяет, поддерживает ли устройство воспроизведение HLG10. Начиная с Android 13, HLG10 является минимальным стандартом, который производители устройств должны поддерживать, если устройство поддерживает воспроизведение HDR:
Котлин
// 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"); }
Ява
// 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, настройте воспроизведение HDR с помощью MediaCodec
через SurfaceView
.
Настройте MediaCodec с помощью SurfaceView.
Настройте стандартный процесс воспроизведения MediaCodec
с помощью SurfaceView
. Это позволяет отображать видеоконтент HDR без какой-либо специальной обработки для воспроизведения HDR:
-
MediaCodec
: декодирует видеоконтент HDR. -
SurfaceView
: отображает видеоконтент HDR.
Следующий код проверяет, поддерживает ли кодек профиль HDR, а затем настраивает MediaCodec
с помощью SurfaceView
:
Котлин
// 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()
Ява
// 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();
Дополнительные реализации MediaCodec
с использованием SurfaceView
см. в примерах камеры Android .
Ресурсы
Дополнительную информацию о воспроизведении HDR см. на следующих ресурсах:
HDR
- Захват видео HDR : узнайте, как настроить захват видео HDR с помощью API-интерфейсов Camera2.
- Пример Camera2Video на Github : посмотрите работающее приложение с функцией захвата и воспроизведения HDR.
СМИ
- Справочник по Media API : узнайте больше о Media API.
- ExoPlayer : узнайте, как настроить свое приложение с помощью библиотеки ExoPlayer.