عیب‌یابی


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

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

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

اگر رسانه‌ای را که پخش می‌کنید کنترل می‌کنید، قویاً توصیه می‌کنیم که از قالب مناسب‌تری مثل MP4 استفاده کنید. هیچ مورد استفاده‌ای که از آن آگاه باشیم وجود ندارد که در آن MP3 بهترین انتخاب برای قالب رسانه باشد.

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

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

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

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

تأخیر ایجادشده توسط (۲) را می‌توان با کاهش دقت جستجو بااستفاده از 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 انجام دهید. این پرچم‌ها را می‌توان بااستفاده از setTsExtractorFlags روی DefaultExtractorsFactory تنظیم کرد یا بااستفاده از سازنده روی 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 301 یا 302 ناموفق هستند؟

کدهای پاسخ HTTP 301 و 302 هر دو نشان‌دهنده هدایت هستند. شرح‌های کوتاه را می‌توانید در ویکی‌پدیا پیدا کنید. وقتی 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 مربوطه متکی باشید. در مواردی که نشانی وب جاری‌سازی به پسوند فایل استاندارد ختم نمی‌شود، می‌توانید MimeTypes.APPLICATION_MPD، MimeTypes.APPLICATION_M3U8، یا MimeTypes.APPLICATION_SS را به setMimeType از MediaItem.Builder ارسال کنید تا نوع جاری‌سازی را به‌طور صریح مشخص کنید.

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

چرا setPlaybackParameters در برخی دستگاه‌ها به‌درستی کار نمی‌کند؟

هنگام اجرای ساخت اشکال‌زدایی برنامه در Android M و نسخه‌های قدیمی‌تر، ممکن است هنگام استفاده از میانای برنامه کاربردی setPlaybackParameters با عملکرد ناهموار، مصنوعات شنیداری، و استفاده بالای CPU مواجه شوید. دلیل این امر این است که بهینه‌سازی مهم برای این API در ساخت‌های اشکال‌زدایی که در این نسخه‌های Android اجرا می‌شوند غیرفعال است.

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

خطاهای «Player is accessed on the wrong thread» به چه معنا است؟

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

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

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

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

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

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

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

  1. باید سرویس پیش‌زمینه‌ای درحال اجرا داشته باشید. این کار مانع می‌شود سیستم فرایند شما را برای آزاد کردن منابع متوقف کند.
  2. باید WifiLock و WakeLock داشته باشید. این تنظیمات تضمین می‌کند که سیستم رادیو Wi-Fi و CPU را بیدار نگه دارد. اگر از ExoPlayer با فراخوانی setWakeMode استفاده کنید، این کار به‌راحتی انجام می‌شود، زیرا این فراخوانی به‌طور خودکار قفل‌های موردنیاز را در زمان‌های صحیح به‌دست می‌آورد و آزاد می‌کند.

مهم است که قفل‌ها را آزاد کنید (اگر از setWakeMode استفاده نمی‌کنید) و به‌محض اینکه صدا دیگر پخش نمی‌شود، سرویس را متوقف کنید.

چرا ExoPlayer از محتوای من پشتیبانی می‌کند اما کتابخانه ExoPlayer Cast پشتیبانی نمی‌کند؟

ممکن است محتوایی که می‌خواهید پخش کنید CORS فعال نباشد. چارچوب «پخش محتوا» برای پخش محتوا نیاز دارد که محتوا در 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 علامت‌گذاری شده‌اند. برای اینکه این تمایز واضح باشد، استفاده از نمادهای ناپایدار میانای برنامه‌سازی کاربردی خطای lint تولید می‌کند، مگر اینکه با @OptIn حاشیه‌نویسی شده باشند.

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

برای مدیریت خطاهای ناپایدار API lint دو انتخاب دارید:

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

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

نماگرفت: نحوه افزودن گزارمان «موافقت»
شکل ۲: افزودن گزارمان @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.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 مهم است.