عیب یابی


رفع خطاهای "ترافیک HTTP Cleartext مجاز نیست".

این خطا در صورتی رخ می دهد که برنامه شما ترافیک 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 دارای مهرهای زمانی نمونه مطلق در جریان نیست، بنابراین این رویکرد امکان پذیر نیست.

به این دلایل، تنها راه برای جستجوی دقیق یک فایل VBR 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 در نظر گرفته شده است.

هنگامی که از شما خواسته می شود یک فایل MPEG-TS را که فاقد AUD یا IDR فریم های کلیدی است پخش کند، به نظر می رسد که ExoPlayer در حالت بافر گیر کرده است. اگر نیاز به پخش چنین فایل‌هایی دارید، می‌توانید این کار را به ترتیب با استفاده از 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 301 یا 302 شکست می خورند؟

کدهای پاسخ HTTP 301 و 302 هر دو نشان دهنده تغییر مسیر هستند. توضیحات مختصری را می توان در ویکی پدیا یافت. هنگامی که ExoPlayer درخواستی می دهد و پاسخی با کد وضعیت 301 یا 302 دریافت می کند، معمولاً تغییر مسیر را دنبال می کند و پخش را به طور معمول شروع می کند. یکی از مواردی که این امر به طور پیش فرض اتفاق نمی افتد، برای تغییر مسیرهای متقابل پروتکل است. ریدایرکت متقابل پروتکلی است که از HTTPS به HTTP یا برعکس (یا کمتر متداول، بین یک جفت پروتکل دیگر) هدایت می شود. با استفاده از ابزار خط فرمان wget می‌توانید آزمایش کنید که آیا URL باعث تغییر مسیر پروتکل متقابل می‌شود یا خیر:

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

خروجی باید چیزی شبیه به این باشد:

Location: https://second.com/test.mp3 [following]
Location: http://third.com/test.mp3 [following]

در این مثال، دو تغییر مسیر وجود دارد. اولین تغییر مسیر از https://yourserver.com/test.mp3 به https://second.com/test.mp3 است. هر دو HTTPS هستند و بنابراین این یک تغییر مسیر بین پروتکلی نیست. تغییر مسیر دوم از https://second.com/test.mp3 به http://third.com/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 API عملکردی ناپایدار، آرتیفکت‌های شنیداری و استفاده بالای CPU را تجربه کنید. این به این دلیل است که بهینه‌سازی‌ای که برای این API مهم است برای ساخت‌های اشکال‌زدایی که در این نسخه‌های اندروید اجرا می‌شوند غیرفعال است.

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

خطاهای "بازیکن در رشته اشتباه قابل دسترسی است" به چه معناست؟

به یادداشتی در مورد نخ زنی در صفحه شروع کار مراجعه کنید.

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

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

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

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

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

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

  1. شما باید یک سرویس پیش زمینه در حال اجرا داشته باشید. این مانع از کشتن سیستم برای آزاد کردن منابع می شود.
  2. باید WifiLock و WakeLock نگه دارید. اینها تضمین می کنند که سیستم رادیو وای فای و 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 پخش کند، مانند URLهایی از فرم https://www.youtube.com/watch?v=... در عوض، باید از YouTube IFrame Player API استفاده کنید که راه رسمی پخش ویدیوهای YouTube در اندروید است.

پخش ویدیو دچار لکنت است

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

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

خطاهای پرز ناپایدار API

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

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

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

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

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

اسکرین شات: نحوه اضافه کردن حاشیه نویسی Optin
شکل 2 : اضافه کردن حاشیه نویسی @androidx.annotations.OptIn با Android Studio.

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

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.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 بسیار مهم است.