تشغيل فيديوهات بتنسيق HDR

توفّر تكنولوجيا HDR، أو النطاق العالي الديناميكية، نطاقًا أوسع من الألوان وتباينًا أكبر بين الألوان البيضاء الأكثر سطوعًا والظلال الداكنة، ما يؤدي إلى جودة فيديو تشبه إلى حد كبير ما تراه العين المجردة.

يمكنك إعداد تشغيل الفيديوهات بتكنولوجيا HDR في تطبيقك لمعاينة محتوى الفيديو المعروض بهذه التكنولوجيا وتشغيله.

تفترض هذه المقالة أنّك أضفت إلى تطبيقك مسبقًا إمكانية تشغيل الفيديوهات الأساسية. يمكنك الاطّلاع على مستندات ExoPlayer لمزيد من التفاصيل حول التشغيل.

المتطلبات الأساسية للجهاز

لا تتيح جميع أجهزة Android تشغيل الفيديوهات بتكنولوجيا HDR. قبل تشغيل محتوى الفيديو المعروض بهذه التكنولوجيا في تطبيقك، تأكَّد من استيفاء جهازك للمتطلبات الأساسية التالية:

  • استهداف الإصدار Android 7.0 أو الإصدارات الأحدث (المستوى 24 من واجهة برمجة التطبيقات)
  • توفُّر برنامج ترميز متوافق مع تكنولوجيا HDR وإمكانية الوصول إلى شاشة عرض متوافقة مع هذه التكنولوجيا

التحقّق من إمكانية تشغيل الفيديوهات بتكنولوجيا HDR

استخدِم Display.getHdrCapabilities() للاطّلاع على إمكانات HDR لشاشة العرض. تعرض هذه الطريقة معلومات عن ملفات تعريف HDR المتوافقة ونطاق الإضاءة لشاشة العرض.

يتحقّق الرمز البرمجي التالي مما إذا كان الجهاز يتيح تشغيل HLG10. اعتبارًا من Android 13، يمثّل HLG10 الحد الأدنى للمعيار الذي يجب أن يتيحه مصنّعو الأجهزة إذا كان الجهاز قادرًا على تشغيل الفيديوهات بتكنولوجيا 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();
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 بدون أي معالجة خاصة لتشغيل الفيديوهات بهذه التكنولوجيا:

  • MediaCodec: لفك ترميز محتوى الفيديو المعروض بتكنولوجيا HDR
  • SurfaceView: لعرض محتوى الفيديو المعروض بتكنولوجيا HDR

يتحقّق الرمز البرمجي التالي مما إذا كان برنامج الترميز يتيح ملف تعريف HDR، ثم يتم إعداد MediaCodec باستخدام 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();

لمزيد من عمليات تنفيذ MediaCodec باستخدام SurfaceView، يمكنك الاطّلاع على نماذج Android Camera.

الموارد

لمزيد من المعلومات ذات الصلة بتشغيل الفيديوهات بتكنولوجيا HDR، يمكنك الاطّلاع على الموارد التالية:

نطاق عالي الديناميكية

الوسائط