تحديد المشاكل وحلّها


إصلاح أخطاء "لا يُسمح بزيارات HTTP غير المرمّزة"

سيحدث هذا الخطأ إذا طلب تطبيقك زيارات HTTP غير مرمّزة (أي http:// بدلاً من https://) عندما لا تسمح إعدادات أمان الشبكة بذلك. إذا كان تطبيقك يستهدف الإصدار 9 من نظام التشغيل Android (مستوى واجهة برمجة التطبيقات 28) أو الإصدارات الأحدث، سيتم إيقاف حركة بيانات HTTP للنص غير المرمّز من خلال الإعدادات التلقائية.

إذا كان تطبيقك يحتاج إلى العمل مع زيارات HTTP للنص غير المرمّز، عليك استخدام إعدادات أمان الشبكة التي تسمح بذلك. لمزيد من التفاصيل، يُرجى الاطّلاع على مستندات أمان الشبكة في Android. لتفعيل جميع زيارات HTTP غير المرمّزة، يمكنك ببساطة إضافة android:usesCleartextTraffic="true" إلى عنصر application في ملف AndroidManifest.xml الخاص بتطبيقك.

يستخدم تطبيق ExoPlayer التجريبي إعدادات أمان الشبكة التلقائية، وبالتالي لا يسمح بزيارات HTTP غير المرمّزة. يمكنك تفعيلها باتّباع التعليمات أعلاه.

إصلاح الأخطاء "SSLHandshakeException" و"CertPathValidatorException" و "ERR_CERT_AUTHORITY_INVALID"

SSLHandshakeException وCertPathValidatorException وERR_CERT_AUTHORITY_INVALID تشير جميعها إلى مشكلة في شهادة طبقة المقابس الآمنة (SSL) الخاصة بالخادم. هذه الأخطاء ليست خاصة بـ ExoPlayer. لمزيد من التفاصيل، يُرجى الاطّلاع على مستندات SSL لنظام التشغيل Android.

لماذا لا يمكن البحث في بعض ملفات الوسائط؟

لا تتيح ExoPlayer تلقائيًا البحث في الوسائط التي تكون الطريقة الوحيدة فيها لإجراء عمليات بحث دقيقة هي أن يفحص المشغّل الملف بأكمله ويفهرسه. يعتبر ExoPlayer هذه الملفات غير قابلة للبحث. تتضمّن معظم تنسيقات حاويات الوسائط الحديثة بيانات وصفية للبحث (مثل فهرس العيّنات)، أو تتضمّن خوارزمية بحث محدّدة جيدًا (مثل البحث الثنائي المقرَّب لملفات Ogg)، أو تشير إلى أنّ المحتوى الخاص بها ذو معدل نقل بيانات ثابت. ويمكن إجراء عمليات البحث الفعّالة ويدعمها ExoPlayer في هذه الحالات.

إذا كنت بحاجة إلى البحث ولكن لديك وسائط غير قابلة للبحث، نقترح عليك تحويل المحتوى الخاص بك لاستخدام تنسيق حاوية أكثر ملاءمة. بالنسبة إلى ملفات MP3 وADTS وAMR، يمكنك أيضًا تفعيل البحث على افتراض أنّ الملفات لها معدل نقل بيانات ثابت، كما هو موضّح هنا.

لماذا يكون البحث غير دقيق في بعض ملفات MP3؟

ملفات MP3 ذات معدل نقل البيانات المتغيّر (VBR) غير مناسبة بشكل أساسي لحالات الاستخدام التي تتطلب البحث الدقيق. هناك سببان لذلك:

  1. For exact seeking, a container format will ideally provide a precise time-to-byte mapping in a header. تتيح عملية الربط هذه للاعب ربط وقت البحث المطلوب بإزاحة البايت المقابلة، وبدء طلب الوسائط وتحليلها وتشغيلها من تلك الإزاحة. إنّ الرؤوس المتاحة لتحديد عملية الربط هذه في ملفات MP3 (مثل رؤوس XING) غالبًا ما تكون غير دقيقة.
  2. بالنسبة إلى تنسيقات الحاويات التي لا توفّر تعيينًا دقيقًا للوقت إلى البايت (أو أي تعيين للوقت إلى البايت على الإطلاق)، لا يزال من الممكن إجراء بحث دقيق إذا كانت الحاوية تتضمّن طوابع زمنية مطلقة للعيّنات في البث. في هذه الحالة، يمكن للمشغّل ربط وقت البحث بأفضل تخمين لإزاحة البايت المقابلة، وبدء طلب الوسائط من تلك الإزاحة، وتحليل الطابع الزمني للعينة المطلقة الأولى، وإجراء بحث ثنائي موجّه بشكل فعال في الوسائط حتى يجد العينة الصحيحة. للأسف، لا يتضمّن MP3 طوابع زمنية مطلقة للعيّنات في البث، لذا لا يمكن استخدام هذا النهج.

لهذه الأسباب، الطريقة الوحيدة لإجراء بحث دقيق في ملف MP3 بمعدل نقل بيانات متغيّر هي فحص الملف بأكمله وإنشاء عملية ربط بين الوقت ووحدات البايت يدويًا في المشغّل. يمكن تفعيل هذه الاستراتيجية باستخدام FLAG_ENABLE_INDEX_SEEKING، والتي يمكن ضبطها على DefaultExtractorsFactory باستخدام setMp3ExtractorFlags. يُرجى العِلم أنّ هذه الطريقة لا تتوافق مع ملفات MP3 الكبيرة، خاصةً إذا حاول المستخدم الانتقال إلى نهاية البث بعد وقت قصير من بدء التشغيل، ما يتطلّب من المشغّل الانتظار حتى يتم تنزيل البث بالكامل وفهرسته قبل تنفيذ عملية الانتقال. في ExoPlayer، قررنا تحسين السرعة على حساب الدقة في هذه الحالة، وبالتالي تم إيقاف FLAG_ENABLE_INDEX_SEEKING تلقائيًا.

إذا كنت تتحكّم في الوسائط التي تشغّلها، ننصحك بشدة باستخدام تنسيق حاوية أكثر ملاءمة، مثل MP4. لا توجد حالات استخدام نعرفها حيث يكون MP3 هو الخيار الأفضل لتنسيق الوسائط.

لماذا يستغرق البحث في الفيديو وقتًا طويلاً؟

عندما ينتقل المشغّل إلى موضع تشغيل جديد في فيديو، عليه تنفيذ أمرين:

  1. تحميل البيانات المقابلة لموضع التشغيل الجديد في المخزن المؤقت (قد لا يكون ذلك ضروريًا إذا كانت هذه البيانات مخزنة مؤقتًا بالفعل).
  2. يتم تفريغ برنامج فك ترميز الفيديو وبدء فك الترميز من الإطار I (الإطار الرئيسي) قبل موضع التشغيل الجديد، بسبب ترميز الإطار الداخلي الذي تستخدمه معظم تنسيقات ضغط الفيديو. لضمان دقة البحث (أي بدء التشغيل من موضع البحث بالضبط)، يجب فك ترميز جميع الإطارات بين الإطار I السابق وموضع البحث، ثم تجاهلها على الفور (بدون عرضها على الشاشة).

يمكن تخفيف وقت الاستجابة الناتج عن (1) إما عن طريق زيادة كمية البيانات المخزنة مؤقتًا في الذاكرة بواسطة المشغل، أو التخزين المؤقت للبيانات على القرص.

يمكن تقليل وقت الاستجابة الناتج عن (2) إما من خلال تقليل دقة البحث باستخدام ExoPlayer.setSeekParameters أو إعادة ترميز الفيديو للحصول على إطارات I أكثر تكرارًا (ما يؤدي إلى ملف ناتج أكبر).

إذا كان التقديم أو الترجيع بطيئًا أثناء سحب المستخدم لشريط التقديم/الترجيع، يمكنك تفعيل وضع التقديم/الترجيع السريع (ExoPlayer.setScrubbingModeEnabled)، الذي يجمع عمليات التقديم أو الترجيع السريعة، ويزيد من معدل نقل البيانات لوحدة فك الترميز، ويتيح ضبط هامش خطأ جزئي للتقديم أو الترجيع استنادًا إلى عرض شريط التقديم/الترجيع في واجهة المستخدم.

لماذا يتعذّر تشغيل بعض ملفات MPEG-TS؟

لا تحتوي بعض ملفات MPEG-TS على محدّدات وحدات الوصول (AUD). يعتمد ExoPlayer تلقائيًا على محدّدات وحدات الوصول (AUD) لرصد حدود اللقطات بتكلفة منخفضة. وبالمثل، لا تحتوي بعض ملفات MPEG-TS على إطارات مفتاحية IDR. بشكل تلقائي، هذه هي النوع الوحيد من الإطارات الرئيسية التي يأخذها ExoPlayer في الاعتبار.

سيظهر ExoPlayer عالقًا في حالة التخزين المؤقت عند طلب تشغيل ملف MPEG-TS لا يحتوي على AUDs أو إطارات مفتاحية IDR. إذا كنت بحاجة إلى تشغيل هذه الملفات، يمكنك إجراء ذلك باستخدام FLAG_DETECT_ACCESS_UNITS وFLAG_ALLOW_NON_IDR_KEYFRAMES على التوالي. يمكن ضبط هذه العلامات على DefaultExtractorsFactory باستخدام setTsExtractorFlags أو على DefaultHlsExtractorFactory باستخدام المُنشئ. لا يؤدي استخدام FLAG_DETECT_ACCESS_UNITS إلى أي آثار جانبية سوى أنّه مكلف من الناحية الحسابية مقارنةً برصد حدود الإطارات المستند إلى AUD. قد يؤدي استخدام FLAG_ALLOW_NON_IDR_KEYFRAMES إلى تلف مرئي مؤقت في بداية التشغيل وبعد عمليات البحث مباشرةً عند تشغيل بعض ملفات MPEG-TS.

لماذا لا يتم العثور على الترجمة في بعض ملفات MPEG-TS؟

تتضمّن بعض ملفات MPEG-TS مقاطع CEA-608 ولكن لا يتم الإعلان عنها في البيانات الوصفية للحاوية، لذا يتعذّر على ExoPlayer رصدها. يمكنك تحديد أي مسارات ترجمة يدويًا من خلال تقديم قائمة بتنسيقات الترجمة المتوقعة إلى DefaultExtractorsFactory، بما في ذلك قنوات تسهيل الاستخدام التي يمكن استخدامها لتحديدها في بث MPEG-TS:

Kotlin

val extractorsFactory =
  DefaultExtractorsFactory()
    .setTsSubtitleFormats(
      listOf(
        Format.Builder()
          .setSampleMimeType(MimeTypes.APPLICATION_CEA608)
          .setAccessibilityChannel(accessibilityChannel)
          // Set other subtitle format info, such as language.
          .build()
      )
    )
val player: Player =
  ExoPlayer.Builder(context, DefaultMediaSourceFactory(context, extractorsFactory)).build()

Java

DefaultExtractorsFactory extractorsFactory =
    new DefaultExtractorsFactory()
        .setTsSubtitleFormats(
            ImmutableList.of(
                new Format.Builder()
                    .setSampleMimeType(MimeTypes.APPLICATION_CEA608)
                    .setAccessibilityChannel(accessibilityChannel)
                    // Set other subtitle format info, such as language.
                    .build()));
Player player =
    new ExoPlayer.Builder(context, new DefaultMediaSourceFactory(context, extractorsFactory))
        .build();

لماذا لا يتم تشغيل بعض ملفات MP4/FMP4 بشكل صحيح؟

تحتوي بعض ملفات MP4/FMP4 على قوائم تعديل تعيد كتابة المخطط الزمني للوسائط من خلال تخطّي قوائم العيّنات أو نقلها أو تكرارها. يتيح ExoPlayer جزئيًا تطبيق قوائم التعديل على سبيل المثال، يمكنه تأخير أو تكرار مجموعات من العينات بدءًا من عينة المزامنة، ولكنه لا يقتطع عينات الصوت أو وسائط ما قبل التشغيل للتعديلات التي لا تبدأ في عينة المزامنة.

إذا لاحظت أنّ جزءًا من الوسائط مفقود أو متكرر بشكل غير متوقّع، جرِّب ضبط Mp4Extractor.FLAG_WORKAROUND_IGNORE_EDIT_LISTS أو FragmentedMp4Extractor.FLAG_WORKAROUND_IGNORE_EDIT_LISTS، ما سيؤدي إلى تجاهل أداة الاستخراج لقوائم التعديل بالكامل. ويمكن ضبطها على DefaultExtractorsFactory باستخدام setMp4ExtractorFlags أو setFragmentedMp4ExtractorFlags.

لماذا يتعذّر تشغيل بعض أحداث البث المباشر مع رمز الاستجابة HTTP‏ 301 أو 302؟

يشير رمزا الاستجابة HTTP‏ 301 و302 إلى إعادة التوجيه. يمكن العثور على أوصاف موجزة على Wikipedia. عندما يرسل ExoPlayer طلبًا ويتلقّى ردًا برمز الحالة 301 أو 302، سيتّبع عادةً عملية إعادة التوجيه ويبدأ التشغيل كالمعتاد. الحالة الوحيدة التي لا يحدث فيها ذلك تلقائيًا هي عمليات إعادة التوجيه عبر البروتوكولات. إعادة التوجيه عبر البروتوكولات هي إعادة توجيه من HTTPS إلى HTTP أو العكس (أو بشكل أقل شيوعًا، بين زوج آخر من البروتوكولات). يمكنك اختبار ما إذا كان عنوان URL يؤدي إلى إعادة توجيه عبر بروتوكولات مختلفة باستخدام أداة سطر الأوامر wget على النحو التالي:

wget "https://yourserver.example.com/test.mp3" 2>&1  | grep Location

من المفترض أن تظهر النتيجة على النحو التالي:

Location: https://secondserver.example.net/test.mp3 [following]
Location: http://thirdserver.example.org/test.mp3 [following]

في هذا المثال، هناك عمليتا إعادة توجيه. تتم إعادة التوجيه الأولى من https://yourserver.example.com/test.mp3 إلى https://secondserver.example.net/test.mp3. كلاهما يستخدم HTTPS، وبالتالي لا تُعدّ هذه عملية إعادة توجيه عبر بروتوكولات مختلفة. تتم إعادة التوجيه الثانية من https://secondserver.example.net/test.mp3 إلى http://thirdserver.example.org/test.mp3. يؤدي ذلك إلى إعادة التوجيه من HTTPS إلى HTTP، وبالتالي تكون عملية إعادة توجيه بين بروتوكولات متعددة. لن يتّبع ExoPlayer عملية إعادة التوجيه هذه في إعداداته التلقائية، ما يعني أنّ عملية التشغيل ستتعذّر.

إذا لزم الأمر، يمكنك ضبط ExoPlayer ليتّبع عمليات إعادة التوجيه عبر البروتوكولات عند إنشاء مثيلات DefaultHttpDataSource.Factory المستخدَمة في تطبيقك. يمكنك الاطّلاع على مزيد من المعلومات حول اختيار حزمة الشبكة وضبطها هنا.

لماذا يتعذّر تشغيل بعض أحداث البث المباشر بسبب الخطأ UnrecognizedInputFormatException؟

يتعلّق هذا السؤال بأخطاء التشغيل في النموذج التالي:

UnrecognizedInputFormatException: None of the available extractors
(MatroskaExtractor, FragmentedMp4Extractor, ...) could read the stream.

هناك سببان محتملان لهذا الخطأ. السبب الأكثر شيوعًا هو أنّك تحاول تشغيل محتوى DASH (mpd) أو HLS (m3u8) أو SmoothStreaming (ism, isml)، ولكن يحاول المشغّل تشغيله كبث تدريجي. لتشغيل هذه البثوث، يجب الاعتماد على وحدة ExoPlayer المعنيّة. في الحالات التي لا ينتهي فيها معرّف الموارد المنتظم (URI) للبث بامتداد الملف العادي، يمكنك أيضًا تمرير MimeTypes.APPLICATION_MPD أو MimeTypes.APPLICATION_M3U8 أو MimeTypes.APPLICATION_SS إلى setMimeType من MediaItem.Builder لتحديد نوع البث بشكل صريح.

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

لماذا لا تعمل setPlaybackParameters بشكل صحيح على بعض الأجهزة؟

عند تشغيل إصدار مخصص لتصحيح الأخطاء من تطبيقك على Android M والإصدارات الأقدم، قد تواجه أداءً متقطعًا ومشاكل في الصوت واستخدامًا عاليًا لوحدة المعالجة المركزية عند استخدام واجهة برمجة التطبيقات setPlaybackParameters. ويرجع ذلك إلى أنّ عملية التحسين المهمة لواجهة برمجة التطبيقات هذه تكون غير مفعَّلة في الإصدارات المخصّصة لتصحيح الأخطاء التي تعمل على إصدارات Android هذه.

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

ما معنى أخطاء "تم الوصول إلى المشغّل في سلسلة التعليمات غير الصحيحة"؟

يُرجى الاطّلاع على ملاحظة حول سلاسل المحادثات في صفحة البدء.

كيف يمكنني حلّ مشكلة "سطر الحالة غير متوقّع: ICY 200 OK"؟

يمكن أن تحدث هذه المشكلة إذا كانت استجابة الخادم تتضمّن سطر حالة ICY، بدلاً من سطر متوافق مع بروتوكول HTTP. تم إيقاف أسطر حالة ICY نهائيًا ويجب عدم استخدامها، لذا إذا كنت تتحكّم في الخادم، عليك تعديله لتقديم استجابة متوافقة مع HTTP. إذا لم تتمكّن من إجراء ذلك، سيؤدي استخدام مكتبة ExoPlayer OkHttp إلى حلّ المشكلة، لأنّها قادرة على معالجة أسطر حالة ICY بشكل صحيح.

كيف يمكنني الاستعلام عمّا إذا كان البث الذي يتم تشغيله هو بث مباشر؟

يمكنك الاستعلام عن طريقة isCurrentWindowLive الخاصة بالمشغّل. بالإضافة إلى ذلك، يمكنك التحقّق من isCurrentWindowDynamic لمعرفة ما إذا كانت النافذة ديناميكية (أي أنّها لا تزال تتغيّر بمرور الوقت).

كيف يمكنني مواصلة تشغيل الصوت عندما يكون تطبيقي في الخلفية؟

اتّبِع الخطوات التالية لضمان استمرار تشغيل الصوت عندما يكون تطبيقك في الخلفية:

  1. يجب أن تكون لديك خدمة تعمل في المقدّمة. يمنع هذا النظام من إنهاء العملية لتحرير الموارد.
  2. يجب أن يكون لديك WifiLock وWakeLock. تضمن هذه الأذونات أنّ النظام يحافظ على تفعيل وحدة المعالجة المركزية (CPU) وشبكة Wi-Fi. يمكن إجراء ذلك بسهولة في حال استخدام ExoPlayer من خلال استدعاء setWakeMode، ما سيؤدي تلقائيًا إلى الحصول على الأقفال المطلوبة وإلغائها في الأوقات المناسبة.

من المهم إلغاء قفل الشاشة (في حال عدم استخدام setWakeMode) وإيقاف الخدمة فور توقّف تشغيل الصوت.

لماذا يتوافق ExoPlayer مع المحتوى الخاص بي بينما لا تتوافق مكتبة ExoPlayer Cast معه؟

من المحتمل أنّ المحتوى الذي تحاول تشغيله غير متوافق مع CORS. يتطلب إطار عمل Cast تفعيل مشاركة الموارد المتعددة المنشأ (CORS) في المحتوى لتشغيله.

لماذا يتعذّر تشغيل المحتوى بدون ظهور أي رسالة خطأ؟

من المحتمل أنّ الجهاز الذي تشغّل المحتوى عليه لا يتوافق مع تنسيق معيّن لعيّنة الوسائط. يمكنك التأكّد من ذلك بسهولة من خلال إضافة EventLogger كمستمع إلى المشغّل، والبحث عن سطر مشابه لهذا السطر في Logcat:

[ ] Track:x, id=x, mimeType=mime/type, ... , supported=NO_UNSUPPORTED_TYPE

تشير القيمة NO_UNSUPPORTED_TYPE إلى أنّ الجهاز لا يمكنه فك ترميز تنسيق عيّنة الوسائط المحدّد بواسطة mimeType. يمكنك الاطّلاع على مستندات تنسيقات الوسائط في Android للحصول على معلومات حول تنسيقات العيّنات المتوافقة. كيف يمكنني تحميل مكتبة فك الترميز واستخدامها للتشغيل؟ قد يكون مفيدًا أيضًا.

كيف يمكنني تحميل مكتبة فك ترميز واستخدامها للتشغيل؟

  • تتضمّن معظم مكتبات برامج فك الترميز خطوات يدوية للتحقّق من التبعيات وإنشائها، لذا تأكَّد من اتّباع الخطوات الواردة في ملف README للمكتبة ذات الصلة. على سبيل المثال، بالنسبة إلى مكتبة ExoPlayer FFmpeg، من الضروري اتّباع التعليمات الواردة في libraries/decoder_ffmpeg/README.md، بما في ذلك تمرير علامات الضبط لتفعيل برامج فك الترميز لأي تنسيقات تريد تشغيلها.
  • بالنسبة إلى المكتبات التي تحتوي على رموز برمجية أصلية، تأكَّد من استخدام الإصدار الصحيح من Android NDK كما هو محدّد في ملف README، وابحث عن أي أخطاء تظهر أثناء الإعداد والإنشاء. من المفترض أن تظهر ملفات .so في الدليل الفرعي libs لمسار المكتبة لكل بنية متوافقة بعد اتّباع الخطوات الواردة في ملف README.
  • لتجربة التشغيل باستخدام المكتبة في التطبيق التجريبي، يُرجى الاطّلاع على تفعيل برامج فك الترميز المجمّعة. يُرجى الاطّلاع على ملف README الخاص بالمكتبة للحصول على تعليمات حول كيفية استخدام المكتبة من تطبيقك.
  • إذا كنت تستخدم DefaultRenderersFactory، من المفترض أن يظهر لك سطر سجلّ على مستوى المعلومات مثل "تم تحميل FfmpegAudioRenderer" في Logcat عند تحميل برنامج فك الترميز. إذا لم يكن هذا الخيار متاحًا، تأكَّد من أنّ التطبيق يعتمد على مكتبة فك الترميز.
  • إذا ظهرت لك سجلّات على مستوى التحذير من LibraryLoader في Logcat، يشير ذلك إلى تعذُّر تحميل المكوّن الأصلي للمكتبة. في حال حدوث ذلك، تأكَّد من اتّباع الخطوات الواردة في ملف README الخاص بالمكتبة بشكل صحيح ومن عدم ظهور أي أخطاء أثناء اتّباع التعليمات.

إذا كنت لا تزال تواجه مشاكل في استخدام مكتبات فك الترميز، يُرجى مراجعة أداة تتبُّع المشاكل في Media3 بحثًا عن أي مشاكل حديثة ذات صلة. إذا أردت الإبلاغ عن مشكلة جديدة تتعلّق بإنشاء الجزء الأصلي من المكتبة، يُرجى تضمين الناتج الكامل لسطر الأوامر من تشغيل تعليمات README لمساعدتنا في تشخيص المشكلة.

هل يمكنني تشغيل فيديو على YouTube مباشرةً باستخدام ExoPlayer؟

لا، لا يمكن لمشغّل ExoPlayer تشغيل فيديوهات من YouTube، مثل عناوين URL التي تتخذ الشكل https://www.youtube.com/watch?v=.... بدلاً من ذلك، يجب استخدام YouTube IFrame Player API، وهي الطريقة الرسمية لتشغيل فيديوهات على YouTube على Android.

تشغيل الفيديو متقطّع

قد لا يتمكّن الجهاز من فك ترميز المحتوى بسرعة كافية إذا كان، على سبيل المثال، معدل نقل البيانات أو دقة المحتوى يتجاوزان إمكانات الجهاز. قد تحتاج إلى استخدام محتوى منخفض الجودة للحصول على أداء جيد على هذه الأجهزة.

إذا كنت تواجه مشكلة تقطُّع الفيديو على جهاز يعمل بإصدار من Android بدءًا من Android 6.0 (مستوى واجهة برمجة التطبيقات 23) وحتى Android 11 (مستوى واجهة برمجة التطبيقات 30)، خاصةً عند تشغيل محتوى محمي بموجب إدارة الحقوق الرقمية أو محتوى بمعدل اللقطات في الثانية مرتفع، يمكنك محاولة تفعيل ميزة "إضافة قائمة انتظار المخزن المؤقت بشكل غير متزامن".

أخطاء lint في واجهة برمجة التطبيقات غير المستقرة

تضمن Media3 التوافق الثنائي لمجموعة فرعية من واجهة برمجة التطبيقات. أما الأجزاء التي لا تضمن التوافق الثنائي، فيتم تمييزها بالرمز @UnstableApi. لتوضيح هذا الفرق، يؤدي استخدام رموز واجهة برمجة التطبيقات غير المستقرة إلى ظهور خطأ في أداة التحقّق من الأخطاء ما لم يتم وضع تعليقات توضيحية عليها باستخدام @OptIn.

لا يشير التعليق التوضيحي @UnstableApi إلى أي شيء يتعلّق بجودة واجهة برمجة التطبيقات أو أدائها، بل يشير فقط إلى حقيقة أنّها ليست "مجمّدة".

لديك خياران للتعامل مع أخطاء lint في واجهة برمجة التطبيقات غير المستقرة:

  • يُرجى التبديل إلى استخدام واجهة برمجة تطبيقات ثابتة تحقّق النتيجة نفسها.
  • مواصلة استخدام واجهة برمجة التطبيقات غير المستقرة وإضافة تعليقات توضيحية على الاستخدام باستخدام @OptIn، كما هو موضّح لاحقًا
إضافة التعليق التوضيحي @OptIn

يمكن أن يساعدك "استوديو Android" في إضافة التعليق التوضيحي:

لقطة شاشة: كيفية إضافة التعليق التوضيحي Optin
الشكل 2: إضافة تعليق توضيحي ‎ @androidx.annotations.OptIn باستخدام "استوديو Android"

يمكنك أيضًا إضافة تعليقات توضيحية يدويًا إلى مواقع استخدام معيّنة:

Kotlin

import androidx.annotation.OptIn
import androidx.media3.common.util.UnstableApi

@OptIn(UnstableApi::class)
fun functionUsingUnstableApi() { ... }

Java

import androidx.annotation.OptIn;
import androidx.media3.common.util.UnstableApi;

@OptIn(markerClass = UnstableApi.class)
private void methodUsingUnstableApis() { ... }

يمكن تفعيل الحزم بأكملها من خلال إضافة ملف package-info:

Kotlin

// In your package-info.kt
@OptIn(UnstableApi::class)
package name.of.your.package

import androidx.annotation.OptIn
import androidx.media3.common.util.UnstableApi

Java

// In your package-info.java
@OptIn(markerClass = UnstableApi.class)
package name.of.your.package;

import androidx.annotation.OptIn;
import androidx.media3.common.util.UnstableApi;

يمكن تفعيل الميزة في مشاريع كاملة من خلال إيقاف خطأ lint المحدّد في ملف lint.xml:

 <?xml version="1.0" encoding="utf-8"?>
 <lint>
   <issue id="UnsafeOptInUsageError">
     <option name="opt-in" value="androidx.media3.common.util.UnstableApi" />
   </issue>
 </lint>

هناك أيضًا تعليق توضيحي kotlin.OptIn يجب عدم استخدامه. من المهم استخدام التعليق التوضيحي androidx.annotation.OptIn.

كيف يمكنني اختبار المشاكل الناتجة عن التحسينات أو الميزات الجديدة أو عزلها؟

تتضمّن Media3 بنية أساسية لعلامات الميزات، حيث يتم تفعيل الميزات والتحسينات الجديدة تلقائيًا في وضع Canary.

إذا كنت تشك في أنّ مشكلة أو تراجعًا في تطبيقك مرتبط بميزة أو تحسين تم تقديمهما حديثًا، يمكنك إيقاف وضع Canary مؤقتًا:

Flags.setCanaryModeEnabled(false);

أو يمكنك إيقاف علامات ميزات معيّنة بشكل فردي باستخدام Flags.disableFlag(flagId). لمزيد من التفاصيل حول ضبط وضع Canary، وتجاوز العلامات، وإعداد مفاتيح الإيقاف عن بُعد، يُرجى الاطّلاع على دليل علامات الميزات ووضع Canary.