بازپخش ویدیو HDR

HDR یا «دامنه پویای بالا» طیف وسیع‌تری از رنگ‌ها و کنتراست بیشتری بین روشن‌ترین سفیدها و تاریک‌ترین سایه‌ها ارائه می‌دهد و درنتیجه کیفیت ویدیویی را ارائه می‌دهد که بیشتر شبیه به آنچه چشم غیرمسلح درک می‌کند است.

می‌توانید بازپخش ویدیو HDR را در برنامه‌تان راه‌اندازی کنید تا محتوای ویدیویی HDR را پیش‌نمایش و بازپخش کنید.

این مقاله فرض می‌کند که قبلاً پشتیبانی از بازپخش ویدیو پایه را به برنامه‌تان اضافه کرده‌اید. برای جزئیات بیشتر درباره بازپخش، به اسناد ExoPlayer مراجعه کنید.

پیش‌نیازهای دستگاه

همه دستگاه‌های Android از بازپخش HDR پشتیبانی نمی‌کنند. قبل‌از بازپخش محتوای ویدیویی HDR در برنامه‌تان، بررسی کنید که آیا دستگاهتان پیش‌نیازهای زیر را دارد یا نه:

  • Android نسخه ۷.۰ یا بالاتر (لایه میانای برنامه‌سازی کاربردی ۲۴) را هدف قرار می‌دهد.
  • رمزگشای سازگار با 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();
List capabilities = 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

بااستفاده از SurfaceView، جریان بازپخش استاندارد MediaCodec را راه‌اندازی کنید. این کار به شما امکان می‌دهد محتوای ویدیویی 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

رسانه

  • مرجع Media API: درباره Media API بیشتر بدانید.
  • ExoPlayer: با نحوه راه‌اندازی برنامه با کتابخانه ExoPlayer آشنا شوید.