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


إصلاح أخطاء "لا يُسمح بزيارات 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 إلى حدوث مشكلة في شهادة طبقة المقابس الآمنة للخادم. هذه الأخطاء ليست خاصة بـ ExoPlayer. لمزيد من التفاصيل، يُرجى الاطّلاع على مستندات طبقة المقابس الآمنة في Android.

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

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

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

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

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

  1. لإجراء عملية بحث دقيقة، من المفترض أن يوفّر تنسيق الحاوية عملية ربط دقيقة بين الوقت والبايت في العنوان. تتيح عملية الربط هذه للاعب ربط وقت البحث المطلوب بإزاحة البايت المقابلة، والبدء في طلب الوسائط وتحليلها وتشغيلها من تلك الإزاحة. إنّ العناوين المتاحة لتحديد هذا الربط بتنسيق 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 (ما سيؤدي إلى زيادة حجم ملف الإخراج).

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

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

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

يشير كلّ من رمزي الاستجابة 301 و302 في HTTP إلى إعادة التوجيه. يمكنك الاطّلاع على أوصاف موجزة على ويكيبيديا. عندما يرسل 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.

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

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

اطّلِع على ملاحظة حول إنشاء سلاسل المحادثات في صفحة "البدء".

كيف يمكنني حلّ الخطأ "Unexpected status line: ICY 200 OK"؟

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

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

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

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

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

  1. يجب أن تكون لديك خدمة تعمل في المقدّمة قيد التشغيل. يمنع ذلك النظام من إيقاف العملية لتحرير الموارد.
  2. يجب أن يكون لديك WifiLock وWakeLock. وتضمن هذه العمليات بقاء وحدة 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، بما في ذلك تمرير علامات الإعدادات إلى enable decoders لأي تنسيقات تريد تشغيلها.
  • بالنسبة إلى المكتبات التي تتضمّن رمزًا برمجيًا أصليًا، تأكَّد من استخدام الإصدار الصحيح من 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 على الأجزاء التي لا تضمن التوافق الثنائي. ولتوضيح هذا الفرق، تؤدي استخدامات رموز واجهة برمجة التطبيقات غير الثابتة إلى حدوث خطأ في أداة Lint ما لم يتم إضافة التعليق التوضيحي @OptIn إليها.

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

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

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

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

لقطة شاشة: كيفية إضافة التعليق التوضيحي 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.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" encodin>g=<&quo>t;ut<f-8"?
 lint
   issue id=&qu>ot;Uns<afeOptInUsageError"
     option name="opt-in" value=&qu>ot;a<ndroid>x.<media>3.common.util.UnstableApi" /
   /issue
 /lint

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