HDR, czyli High Dynamic Range, zapewnia szerszy zakres kolorów i większy kontrast między najjaśniejszymi bielami a najciemniejszymi cieniami, co przekłada się na jakość filmu, która bardziej przypomina to, co widzi ludzkie oko.
W aplikacji możesz skonfigurować odtwarzanie filmów HDR, aby wyświetlać podgląd i odtwarzać treści HDR.
W tym artykule zakładamy, że masz już w aplikacji podstawową obsługę odtwarzania filmów. Więcej informacji o odtwarzaniu znajdziesz w dokumentacji ExoPlayer.
Wymagania wstępne dotyczące urządzenia
Nie wszystkie urządzenia z Androidem obsługują odtwarzanie w HDR. Zanim odtworzysz treści wideo HDR w aplikacji, sprawdź, czy Twoje urządzenie spełnia te wymagania wstępne:
- kierowana na Androida 7.0 lub nowszego (poziom interfejsu API 24);
- ma dekoder obsługujący HDR i dostęp do wyświetlacza obsługującego HDR;
Sprawdzanie obsługi odtwarzania w jakości HDR
Aby sprawdzić, czy wyświetlacz obsługuje HDR, użyj zapytania Display.getHdrCapabilities()
. Metoda zwraca informacje o obsługiwanych profilach HDR i zakresie luminancji wyświetlacza.
Poniższy kod sprawdza, czy urządzenie obsługuje odtwarzanie HLG10. Od Androida 13 standard HLG10 jest minimalnym standardem, który producenci urządzeń muszą obsługiwać, jeśli urządzenie umożliwia odtwarzanie HDR:
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"); }
Konfigurowanie odtwarzania w jakości HDR w aplikacji
Jeśli Twoja aplikacja korzysta z ExoPlayera, domyślnie obsługuje odtwarzanie w HDR. Aby dowiedzieć się, co należy zrobić, gdy odtwarzanie w HDR nie działa, przeczytaj artykuł Sprawdzanie obsługi odtwarzania w HDR.
Jeśli Twoja aplikacja nie korzysta z ExoPlayera, skonfiguruj odtwarzanie HDR za pomocą MediaCodec
przez SurfaceView
.
Konfigurowanie MediaCodec za pomocą SurfaceView
Skonfiguruj standardowy proces odtwarzania MediaCodec
za pomocą SurfaceView
. Pozwala to wyświetlać treści wideo HDR bez specjalnego obsługiwania odtwarzania HDR:
MediaCodec
: dekoduje zawartość wideo HDR.SurfaceView
: wyświetla treści wideo HDR.
Ten kod sprawdza, czy kodek obsługuje profil HDR, a następnie konfiguruje MediaCodec
za pomocą SurfaceView
:
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();
Więcej informacji o implementacjach MediaCodec
, które korzystają z SurfaceView
, znajdziesz w próbkach aplikacji Aparat na Androida.
Materiały
Więcej informacji o odtwarzaniu HDR znajdziesz w tych materiałach:
HDR
- Nagrywanie filmów HDR: dowiedz się, jak skonfigurować nagrywanie filmów HDR za pomocą interfejsów API Camera2.
- Przykład Camera2Video na GitHub: możesz zobaczyć działającą aplikację z funkcją nagrywania i odtwarzania HDR.
Multimedia
- Dokumentacja interfejsu Media API: dowiedz się więcej o interfejsach Media API.
- ExoPlayer: dowiedz się, jak skonfigurować aplikację z biblioteką ExoPlayer.