عیب‌یابی


برطرف کردن خطاهای «ترافیک HTTP با متن آشکار مجاز نیست»

اگر برنامه شما ترافیک HTTP با متن آشکار (یعنی http:// به‌جای https://) درخواست کند و «پیکربندی امنیتی شبکه» آن اجازه ندهد، این خطا رخ می‌دهد. اگر برنامه شما Android 9 (سطح ای‌پی‌آی ۲۸) یا بالاتر را هدف قرار می‌دهد، ترافیک 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. برای جستجوی دقیق، قالب محفظه در حالت ایده‌آل نگاشت دقیق زمان به بایت را در سرصفحه ارائه می‌دهد. این نگاشت به پخش‌کننده امکان می‌دهد زمان جستجوی درخواست‌شده را به انحراف بایت مربوطه نگاشت کند و درخواست، تجزیه، و پخش رسانه را از آن انحراف شروع کند. سرایندهای موجود برای مشخص کردن این نگاشت در MP3 (مانند سرایندهای XING) متأسفانه اغلب غیردقیق هستند.
  2. برای قالب‌های محفظه‌ای که نگاشت دقیق زمان به بایت (یا هرگونه نگاشت زمان به بایت) ارائه نمی‌دهند، همچنان امکان انجام جستجوی دقیق وجود دارد، به‌شرطی که محفظه شامل مُهرهای زمانی مطلق نمونه در جاری‌سازی باشد. در این حالت، پخش‌کننده می‌تواند زمان جستجو را به بهترین حدس از انحراف بایت مربوطه نگاشت کند، درخواست رسانه را از آن انحراف شروع کند، اولین مُهر زمان نمونه مطلق را تجزیه کند، و به‌طور مؤثر جستجوی دودویی هدایت‌شده‌ای را در رسانه انجام دهد تا نمونه درست را پیدا کند. متأسفانه MP3 شامل مُهرهای زمان نمونه مطلق در جاری‌سازی نیست، بنابراین این رویکرد امکان‌پذیر نیست.

به این دلایل، تنها راه برای انجام جستجوی دقیق در فایل MP3 با نرخ بیت متغیر این است که کل فایل اسکن شود و نگاشت زمان به بایت به‌صورت دستی در پخش‌کننده ایجاد شود. این راهبرد را می‌توان بااستفاده از FLAG_ENABLE_INDEX_SEEKING فعال کرد، که می‌توان آن را بااستفاده از setMp3ExtractorFlags روی DefaultExtractorsFactory تنظیم کرد. توجه داشته باشید که این روش برای فایل‌های MP3 بزرگ مقیاس‌پذیری خوبی ندارد، به‌ویژه اگر کاربر بخواهد مدت کوتاهی پس‌از شروع بازپخش به نزدیک انتهای جاری‌سازی برود، که در این صورت پخش‌کننده باید منتظر بماند تا کل جاری‌سازی بارگیری و نمایه‌سازی شود و سپس جستجو را انجام دهد. در ExoPlayer، تصمیم گرفتیم در این مورد سرعت را بر دقت ترجیح دهیم و بنابراین FLAG_ENABLE_INDEX_SEEKING به‌طور پیش‌فرض غیرفعال است.

اگر رسانه‌ای را که پخش می‌کنید کنترل می‌کنید، اکیداً توصیه می‌کنیم از قالب محفظه مناسب‌تری مانند MP4 استفاده کنید. مورد استفاده‌ای که MP3 بهترین انتخاب برای قالب رسانه باشد سراغ نداریم.

چرا جستجو در ویدیو من کند است؟

وقتی پخش‌کننده به موقعیت بازپخش جدیدی در ویدیو می‌رود، باید دو کار انجام دهد:

  1. داده‌های مربوط به موقعیت بازپخش جدید را در میان‌گیر بار کنید (اگر این داده‌ها ازقبل میان‌گیری شده باشد، ممکن است این کار لازم نباشد).
  2. به‌دلیل کدبندی درون‌فریمی که در اکثر قالب‌های فشرده‌سازی ویدیو استفاده می‌شود، رمزگشای ویدیو را پاک کنید و رمزگشایی را از قاب I (قاب کلیدی) قبل‌از موقعیت بازپخش جدید شروع کنید. برای اطمینان از اینکه جستجو دقیق است (یعنی بازپخش دقیقاً از موقعیت جستجو شروع می‌شود)، همه فریم‌های بین I-frame قبلی و موقعیت جستجو باید رمزگشایی شوند و بلافاصله دور انداخته شوند (بدون اینکه در صفحه نشان داده شوند).

تأخیر ایجادشده توسط (۱) را می‌توان با افزایش مقدار داده‌های میان‌گیری‌شده در حافظه توسط پخش‌کننده یا پیش‌ذخیره‌سازی داده‌ها در دیسک کاهش داد.

تأخیر ایجادشده توسط (۲) را می‌توان با کاهش دقت جستجو بااستفاده از ExoPlayer.setSeekParameters یا بازکدگذاری ویدیو برای داشتن فریم‌های I بیشتر (که منجر به فایل خروجی بزرگ‌تر می‌شود) کاهش داد.

چرا برخی‌از فایل‌های MPEG-TS پخش نمی‌شوند؟

برخی‌از فایل‌های MPEG-TS حاوی جداکننده‌های واحد دسترسی (AUD) نیستند. به‌طور پیش‌فرض، ExoPlayer برای تشخیص ارزان مرزهای فریم به AUD متکی است. به‌طور مشابه، برخی‌از فایل‌های MPEG-TS فاقد فریم‌های کلیدی IDR هستند. به‌طور پیش‌فرض، این‌ها تنها نوع کلیدفریم‌هایی هستند که ExoPlayer درنظر می‌گیرد.

وقتی از ExoPlayer خواسته می‌شود فایل MPEG-TS فاقد AUD یا فریم‌های کلیدی 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 استفاده شوند، هر قطعه زیرنویسی را به‌صورت دستی مشخص کنید:

کاتلین

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()

جاوا

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‏ ۳۰۱ یا ۳۰۲ ناموفق می‌شوند؟

کدهای پاسخ HTTP‏ ۳۰۱ و ۳۰۲ هر دو نشان‌دهنده تغییر مسیر هستند. شرح‌های کوتاه را می‌توانید در Wikipedia پیدا کنید. وقتی ExoPlayer درخواستی ارسال می‌کند و پاسخی با کد وضعیت ۳۰۱ یا ۳۰۲ دریافت می‌کند، معمولاً تغییرمسیر را دنبال می‌کند و پخش را به‌صورت عادی شروع می‌کند. تنها موردی که این اتفاق به‌طور پیش‌فرض رخ نمی‌دهد برای تغییرمسیرهای بین پروتکلی است. بازهدایت بین‌پروتکلی بازهدایتی است که از HTTPS به HTTP یا برعکس (یا به‌ندرت بین جفت پروتکل دیگری) انجام می‌شود. می‌توانید بااستفاده از ابزار خط فرمان 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، عملکرد ناپایدار، مصنوعات شنیداری، و استفاده زیاد از CPU را تجربه کنید. دلیل این امر این است که بهینه‌سازی‌ای که برای این API مهم است برای ساخت‌های اشکال‌زدایی که در این نسخه‌های Android اجرا می‌شوند غیرفعال است.

توجه به این نکته مهم است که این مشکل فقط بر ساخت‌های اشکال‌زدایی تأثیر می‌گذارد. این تنظیم بر ساخت‌های نسخه پخش که بهینه‌سازی همیشه برای آن‌ها فعال است تأثیری ندارد. بنابراین، نسخه‌های پخشی که به کاربران نهایی ارائه می‌دهید نباید تحت تأثیر این مشکل قرار بگیرند.

خطای «دسترسی به پخش‌کننده در رشته اشتباه» به چه معنا است؟

یادداشتی درباره رشته‌سازی را در صفحه شروع به کار ببینید.

چگونه می‌توانم «خط وضعیت غیرمنتظره: ICY 200 OK» را برطرف کنم؟

این مشکل زمانی رخ می‌دهد که پاسخ سرور شامل خط وضعیت ICY باشد، نه خطی که با HTTP سازگار باشد. خطوط وضعیت ICY منسوخ شده‌اند و نباید استفاده شوند، بنابراین اگر سرور را کنترل می‌کنید، باید آن را به‌روز کنید تا پاسخی مطابق با HTTP ارائه دهد. اگر نمی‌توانید این کار را انجام دهید، استفاده از کتابخانه ExoPlayer OkHttp مشکل را حل خواهد کرد، زیرا می‌تواند خطوط وضعیت ICY را به‌درستی مدیریت کند.

چگونه می‌توانم پرس‌وجو کنم که آیا جاری‌سازی درحال پخش یک جاری‌سازی زنده است؟

می‌توانید روش isCurrentWindowLive پخش‌کننده را پرسمان کنید. علاوه‌براین، می‌توانید isCurrentWindowDynamic را بررسی کنید تا متوجه شوید که آیا پنجره پویا است (یعنی همچنان با گذشت زمان به‌روز می‌شود) یا نه.

چگونه می‌توانم پخش صدا را هنگام قرار گرفتن برنامه‌ام در پس‌زمینه ادامه دهم؟

برای اطمینان از ادامه پخش صدا وقتی برنامه‌تان در پس‌زمینه است، این مراحل را دنبال کنید:

  1. باید سرویس پیش‌زمینه‌ای درحال اجرا داشته باشید. این کار از متوقف کردن فرایند شما توسط سیستم برای آزاد کردن منابع جلوگیری می‌کند.
  2. باید WifiLock و WakeLock داشته باشید. این موارد تضمین می‌کند که سیستم رادیو WiFi و CPU را بیدار نگه می‌دارد. این کار را می‌توان به‌راحتی بااستفاده از 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 مشخص شده است استفاده می‌کنید و مراقب هرگونه خطایی که درطول پیکربندی و ساخت ظاهر می‌شود باشید. پس‌از دنبال کردن مراحل README، باید ببینید که فایل‌های .so در زیرفهرست راهنمای libs مسیر کتابخانه برای هر معماری پشتیبانی‌شده ظاهر می‌شوند.
  • برای امتحان کردن بازپخش بااستفاده از کتابخانه در برنامه نمایشی، فعال کردن رمزگشاهای بسته‌ای را ببینید. برای دستورالعمل‌های استفاده از کتابخانه از برنامه خودتان، به README کتابخانه مراجعه کنید.
  • اگر از DefaultRenderersFactory استفاده می‌کنید، باید هنگام بار شدن رمزگشا، خط گزارش سطح اطلاعاتی مانند «Loaded FfmpegAudioRenderer» را در Logcat ببینید. اگر این مورد وجود ندارد، مطمئن شوید که برنامه به کتابخانه رمزگشایی وابسته است.
  • اگر گزارش‌های سطح هشدار را از LibraryLoader در Logcat می‌بینید، این نشان می‌دهد که بار کردن مؤلفه بومی کتابخانه ناموفق بوده است. اگر این اتفاق افتاد، بررسی کنید که مراحل موجود در README کتابخانه را به‌درستی دنبال کرده باشید و هیچ خطایی در حین دنبال کردن دستورالعمل‌ها خروجی داده نشده باشد.

اگر همچنان در استفاده از کتابخانه‌های رمزگشایی مشکل دارید، لطفاً ردیاب مشکل Media3 را برای مشکلات اخیر مرتبط بررسی کنید. اگر لازم است مشکل جدیدی را ثبت کنید و این مشکل به ساختن بخش بومی کتابخانه مربوط می‌شود، لطفاً خروجی کامل خط فرمان را از اجرای دستورالعمل‌های README اضافه کنید تا به ما در تشخیص مشکل کمک کند.

آیا می‌توانم ویدیوهای YouTube را مستقیماً با ExoPlayer پخش کنم؟

نه، ExoPlayer نمی‌تواند ویدیوهای YouTube را پخش کند، مثل نشانی‌های وب فرم https://www.youtube.com/watch?v=.... درعوض، باید از YouTube IFrame Player API استفاده کنید که روش رسمی برای پخش ویدیوهای YouTube در Android است.

بازپخش ویدیو با وقفه انجام می‌شود

اگر، برای مثال، نرخ بیت یا وضوح محتوا از قابلیت‌های دستگاه فراتر برود، ممکن است دستگاه نتواند محتوا را با سرعت کافی رمزگشایی کند. ممکن است لازم باشد برای دستیابی به عملکرد خوب در چنین دستگاه‌هایی، از محتوای با کیفیت پایین‌تر استفاده کنید.

اگر در دستگاهی که نسخه Android آن از Android 6.0 (سطح میانای برنامه‌سازی کاربردی ۲۳) تا Android 11 (سطح میانای برنامه‌سازی کاربردی ۳۰) است، با مشکل لکنت ویدیو مواجه هستید، به‌ویژه هنگام پخش محتوای محافظت‌شده با DRM یا با نرخ فریم بالا، می‌توانید صف‌بندی میان‌گیر ناهمگام را فعال کنید.

خطاهای lint میانای برنامه‌سازی کاربردی ناپایدار

Media3 سازگاری دودویی را برای زیرمجموعه‌ای از سطح API تضمین می‌کند. بخش‌هایی که سازگاری دودویی را تضمین نمی‌کنند با @UnstableApi علامت‌گذاری شده‌اند. برای روشن کردن این تمایز، استفاده از نمادهای API ناپایدار خطای lint ایجاد می‌کند، مگراینکه با @OptIn حاشیه‌نویسی شده باشند.

حاشیه‌نویسی @UnstableApi هیچ چیزی درباره کیفیت یا عملکرد API نشان نمی‌دهد، فقط این واقعیت را نشان می‌دهد که «API-frozen» نیست.

دو گزینه برای رسیدگی به خطاهای lint ناپایدار API دارید:

  • به استفاده از میانای برنامه‌سازی کاربردی پایداری که همان نتیجه را به‌دست می‌دهد تغییر دهید.
  • به استفاده از میانای برنامه‌سازی کاربردی ناپایدار ادامه دهید و استفاده را با @OptIn حاشیه‌نویسی کنید، همان‌طور که در ادامه نشان داده شده است.
گزارمان @OptIn را اضافه کن

«استودیو Android» می‌تواند به شما کمک کند حاشیه‌نویسی را اضافه کنید:

نماگرفت: نحوه افزودن حاشیه‌نویسی Optin
شکل ۲: افزودن حاشیه‌نویسی ‎ @androidx.annotations.OptIn با «استودیو Android».

همچنین می‌توانید سایت‌های استفاده خاص را به‌صورت دستی حاشیه‌نویسی کنید:

کاتلین

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

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

جاوا

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

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

با افزودن فایل package-info می‌توانید برای کل بسته‌ها موافقت کنید:

کاتلین

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

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

جاوا

// 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 فعال هستند.

اگر مشکوک هستید که مشکل یا پس‌رفتی در برنامه‌تان به ویژگی یا بهینه‌سازی جدیدی مربوط است، می‌توانید موقتاً حالت «قناری» را غیرفعال کنید:

Flags.setCanaryModeEnabled(false);

یا پرچم‌های ویژگی خاص را به‌طور جداگانه بااستفاده از Flags.disableFlag(flagId) غیرفعال کنید. برای جزئیات بیشتر درباره پیکربندی حالت Canary، لغو پرچم‌ها، و راه‌اندازی کلیدهای قطع اضطراری از راه دور، به راهنمای پرچم‌های ویژگی و حالت Canary مراجعه کنید.