پخش فیلم HDR

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

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

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

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

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

  • اندروید 7.0 یا بالاتر (لایه API 24) را هدف قرار می دهد.
  • دارای رسیور با قابلیت HDR و دسترسی به صفحه نمایش با قابلیت HDR.

پشتیبانی از پخش HDR را بررسی کنید

از Display.getHdrCapabilities() برای پرس و جو در مورد قابلیت های HDR نمایشگر استفاده کنید. این روش اطلاعات مربوط به نمایه های HDR پشتیبانی شده و محدوده روشنایی نمایشگر را برمی گرداند.

کد زیر بررسی می کند که آیا دستگاه از پخش HLG10 پشتیبانی می کند یا خیر. در اندروید 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 تنظیم کنید

یک جریان پخش استاندارد 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

رسانه ها

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