اخبار محصول

بهبود بازپخش رسانه: معرفی پیش‌بارگذاری با Media3 - بخش ۱

‫۸ دقیقه خواندن
مشاهده نمایه Mayuri Khinvasara Khabya
Mayuri Khinvasara Khabya مهندس روابط توسعه‌دهندگان

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

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

مزایای کلیدی پیش‌بارگذاری عبارت‌اند از:

  • 🚀 شروع سریع‌تر بازپخش: ویدیوها ازقبل آماده هستند، که منجر به گذارهای سریع‌تر بین موارد و شروع فوری‌تر می‌شود.
  • 📉 کاهش بافربندی: با بارگیری پیش‌فعال داده‌ها، احتمال توقف پخش بسیار کمتر می‌شود، برای مثال به‌دلیل اختلالات شبکه.
  • ✨ تجربه کاربری روان‌تر: ترکیب شروع سریع‌تر و میان‌گیری کمتر، تعاملی روان‌تر و یکپارچه‌تر برای کاربران ایجاد می‌کند تا از آن لذت ببرند.

در این مجموعه سه‌قسمتی، ابزارهای قدرتمند Media3 را برای (پیش)بار کردن عناصر معرفی و بررسی دقیق خواهیم کرد.

  • در بخش ۱، به مبانی می‌پردازیم: درک استراتژی‌های مختلف پیش‌بارگیری موجود در Media3، فعال کردن PreloadConfiguration و تنظیم DefaultPreloadManager، فعال کردن برنامه برای پیش‌بارگیری موارد. در پایان این وبلاگ، باید بتوانید موارد رسانه‌ای را با رتبه‌بندی و مدت زمان پیکربندی‌شده خود پیش‌بارگیری و پخش کنید.
  • در بخش ۲، به موضوعات پیشرفته‌تر DefaultPreloadManager می‌پردازیم: استفاده از شنوندگان برای تجزیه‌وتحلیل، کاوش روال‌های مطلوب آماده تولید مانند الگوی پنجره لغزنده و عناصر هم‌رسانی سفارشی DefaultPreloadManager و ExoPlayer.
  • در بخش ۳، با DefaultPreloadManager به حافظه نهان دیسکی می‌پردازیم.

پیش‌بارگذاری به کمک شما می‌آید! 🦸‍♀️

ایده اصلی پشت پیش‌بارگذاری ساده است: محتوای رسانه‌ای را قبل‌از نیاز به آن بار کنید. تا زمانی که کاربر به ویدیو بعدی بکشد، بخش‌های اول ویدیو ازقبل بارگیری و دردسترس قرار گرفته و آماده پخش فوری است.

آن را مثل یک رستوران درنظر بگیرید. آشپزخانه شلوغ منتظر نمی‌ماند تا دستور برسد و بعد پیازها را خرد کند. 🧅 آن‌ها کار آماده‌سازی خود را ازقبل انجام می‌دهند. پیش‌بارگذاری کار آماده‌سازی برای پخش‌کننده ویدیو شما است.

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

در Media3 دو API اصلی برای پیش‌بارگذاری وجود دارد که هرکدام برای موارد استفاده مختلف مناسب هستند. انتخاب API مناسب اولین گام است.

۱. پیش‌بارگذاری موارد فهرست پخش با PreloadConfiguration

این رویکرد ساده برای رسانه‌های خطی و متوالی مانند فهرست‌های پخش مفید است، جایی که ترتیب بازپخش قابل پیش‌بینی است (مانند یک مجموعه از قسمت‌ها). بااستفاده از میاناهای فهرست پخش ExoPlayer، فهرست کامل عناصر رسانه‌ای را به پخش‌کننده می‌دهید و PreloadConfiguration را برای پخش‌کننده تنظیم می‌کنید، سپس پخش‌کننده به‌طور خودکار عناصر بعدی را در توالی همان‌طور که پیکربندی شده است پیش‌بار می‌کند. این API تلاش می‌کند تا تأخیر در پیوستن را زمانی که کاربر قبل‌از اینکه بافر بازپخش با مورد بعدی هم‌پوشانی داشته باشد به مورد بعدی می‌رود، بهینه کند.

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

اگر هنوز مطمئن نیستید که به پیش‌بار کردن نیاز دارید یا نه، این «میانای برنامه‌سازی کاربردی» گزینه کم‌هزینه عالی‌ای برای امتحان کردن آن است!

player.preloadConfiguration =
    PreloadConfiguration(/* targetPreloadDurationUs= */ 5_000_000L)

با PreloadConfiguration بالا، پخش‌کننده تلاش می‌کند پنج ثانیه از رسانه را برای مورد بعدی در فهرست پخش پیش‌بارگذاری کند.

پس‌از موافقت، پیش‌بار کردن فهرست پخش را می‌توان بااستفاده از PreloadConfiguration.DEFAULT برای غیرفعال کردن پیش‌بار کردن فهرست پخش دوباره خاموش کرد:

player.preloadConfiguration = PreloadConfiguration.DEFAULT

۲. پیش‌بارگذاری فهرست‌های پویا با PreloadManager

برای واسط‌های کاربر پویا مثل فیدهای عمودی یا گردونه‌ها که در آن‌ها مورد «بعدی» با تعامل کاربر تعیین می‌شود، API «مدیر پیش‌بارگذاری» مناسب است. این یک جزء جدید قدرتمند و مستقل در کتابخانه Media3 ExoPlayer است که به‌طور خاص برای پیش‌بارگذاری پیش‌کنشی طراحی شده است. این ویژگی مجموعه‌ای از MediaSourceهای بالقوه را مدیریت می‌کند و آن‌ها را براساس نزدیکی به موقعیت فعلی کاربر اولویت‌بندی می‌کند و کنترل دانه‌دانه بر روی آنچه پیش‌بارگذاری می‌شود ارائه می‌دهد، که برای سناریوهای پیچیده مانند فیدهای پویا از ویدیوهای کوتاه مناسب است.

راه‌اندازی PreloadManager

DefaultPreloadManager پیاده‌سازی متعارف برای PreloadManager است.

سازنده DefaultPreloadManager می‌تواند هم DefaultPreloadManager و هم هر نمونه ExoPlayer را که محتوای پیش‌بارگذاری‌شده آن را پخش می‌کند بسازد. برای ایجاد یک DefaultPreloadManager، باید یک TargetPreloadStatusControl را بگذرانید که مدیر پیش‌بارگذاری می‌تواند از آن برای یافتن میزان بارگذاری یک مورد پُرسمان کند. در بخش زیر، نمونه‌ای از TargetPreloadStatusControl را توضیح خواهیم داد و تعریف خواهیم کرد.

val preloadManagerBuilder =
DefaultPreloadManager.Builder(context, targetPreloadStatusControl)
val preloadManager = val preloadManagerBuilder.build()

// Build ExoPlayer with DefaultPreloadManager.Builder
val player = preloadManagerBuilder.buildExoPlayer()

استفاده از سازنده یکسان برای ExoPlayer و DefaultPreloadManager ضروری است، که تضمین می‌کند اجزای زیرین آن‌ها به‌درستی هم‌رسانی شوند.

و تمام! اکنون مدیری دارید که آماده دریافت دستورالعمل‌ها است.

پیکربندی مدت و رتبه‌بندی با TargetPreloadStatusControl

اگر بخواهید، مثلاً، ۱۰ ثانیه از ویدیو را پیش‌بارگذاری کنید چه؟ می‌توانید موقعیت عناصر رسانه‌ای خود را در گردونه ارائه دهید و DefaultPreloadManager بار کردن عناصر را براساس نزدیکی به عنصری که کاربر درحال پخش آن است اولویت‌بندی می‌کند.

اگر می‌خواهید کنترل کنید که چه مدت از مورد پیش‌بارگیری شود، می‌توانید این را با DefaultPreloadManager.PreloadStatus که برمی‌گردانید بگویید.

برای مثال،

  • مورد «A» بالاترین اولویت را دارد، ۵ ثانیه از ویدیو بار می‌شود.
  • مورد «B» اولویت متوسط دارد اما وقتی به آن رسیدید، ۳ ثانیه از ویدیو را بار کنید.
  • مورد «C» اولویت کمتری دارد، فقط قطعه‌ها بارگیری می‌شود.
  • مورد «D» اولویت کمتری دارد، فقط آماده شوید.
  • موارد دیگر دور هستند، هیچ‌چیز پیش‌بارگیری نشود.

این کنترل دقیق می‌تواند به شما کمک کند تا استفاده از منابع خود را بهینه کنید که برای بازپخش یکپارچه توصیه می‌شود.

import androidx.media3.exoplayer.DefaultPreloadManager.PreloadStatus


class MyTargetPreloadStatusControl(
    currentPlayingIndex: Int = C.INDEX_UNSET
) : TargetPreloadStatusControl<Int,PreloadStatus> {


    // The app is responsible for updating this based on UI state
    override fun getTargetPreloadStatus(index: Int): PreloadStatus? {

        val distance = index - currentPlayingIndex

        // Adjacent items (Next): preload 5 seconds
        if (distance == 1) { 
        // Return a PreloadStatus that is labelled by STAGE_SPECIFIED_RANGE_LOADED and suggest loading // 5000ms from the default start position
                    return PreloadStatus.specifiedRangeLoaded(5000L)
                } 

        // Adjacent items (Previous): preload 3 seconds
        else if (distance == -1) { 
        // Return a PreloadStatus that is labelled by STAGE_SPECIFIED_RANGE_LOADED //and suggest loading 3000ms from the default start position
                    return PreloadStatus.specifiedRangeLoaded(3000L)
                } 

        // Items two positions away: just select tracks
        else if (distance) == 2) {
        // Return a PreloadStatus that is labelled by STAGE_TRACKS_SELECTED
                    return PreloadStatus.TRACKS_SELECTED
                } 

        // Items four positions away: just select prepare
        else if (abs(distance) <= 4) {
        // Return a PreloadStatus that is labelled by STAGE_SOURCE_PREPARED
                    return PreloadStatus.SOURCE_PREPARED
                }

             // All other items are too far away
             return null
            }
}

نکته: PreloadManager می‌تواند هم موارد قبلی و هم موارد بعدی را ازقبل بار کند، درحالی‌که PreloadConfiguration فقط به موارد بعدی نگاه می‌کند.

مدیریت موارد پیش‌بارگیری

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

۱. افزودن فایل‌های رسانه‌ای

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

val initialMediaItems = pullMediaItemsFromService(/* count= */ 20)
for (index in 0 until initialMediaItems.size) {
    preloadManager.add(
        initialMediaItems.get(index),index)
    )
}

اکنون مدیر شروع به واکشی داده‌ها برای این MediaItem در پس‌زمینه خواهد کرد.

پس‌از افزودن، به مدیر بگویید فهرست جدیدش را دوباره ارزیابی کند (با اشاره به اینکه چیزی تغییر کرده است، مثلاً موردی اضافه/ حذف شده است، یا کاربر به پخش مورد جدیدی تغییر کرده است).

preloadManager.invalidate()

۲. بازیابی و پخش کردن یک مورد

در اینجا منطق اصلی بازپخش قرار دارد. وقتی کاربر تصمیم می‌گیرد آن ویدیو را پخش کند، نیازی نیست MediaSource جدیدی ایجاد کنید. درعوض، از PreloadManager می‌خواهید که همان را که قبلاً آماده کرده است به شما بدهد. می‌توانید MediaSource را بااستفاده از MediaItem از Preload Manager بازیابی کنید.

اگر مورد بازیابی‌شده از PreloadManager تهی باشد، یعنی mediaItem هنوز پیش‌بارگذاری نشده است یا به PreloadMamager اضافه نشده است، بنابراین انتخاب می‌کنید که mediaItem را مستقیماً تنظیم کنید.

// When a media item is about to displ​​ay on the screen
val mediaSource = preloadManager.getMediaSource(mediaItem)
if (mediaSource!= null) {
  player.setMediaSource(mediaSource)
} else {
  // If mediaSource is null, that mediaItem hasn't been added yet.
  // So, send it directly to the player.
  player.setMediaItem(mediaItem)
}
player.prepare()
// When the media item is displaying at the center of the screen
player.play()

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

۳. شاخص کنونی را با واسط کاربر همگام نگه دارید

ازآنجایی‌که فید / فهرست ما می‌تواند پویا باشد، مهم است که PreloadManager را از شاخص پخش فعلی خود مطلع کنید تا همیشه بتواند مواردی را که به شاخص فعلی شما نزدیک‌تر هستند برای پیش‌بارگذاری اولویت‌بندی کند.

preloadManager.setCurrentPlayingIndex(currentIndex)
// Need to call invalidate() to update the priorities
preloadManager.invalidate()

۴. برداشتن مورد

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

// When an item is too far from the current playing index
preloadManager.remove(mediaItem)

اگر نیاز دارید همه موارد را به‌طور هم‌زمان پاک کنید، می‌توانید با preloadManager.reset() تماس بگیرید.

‫۵. «مدیر» را رها کنید

وقتی دیگر به PreloadManager نیاز ندارید (برای نمونه، وقتی واسط کاربرتان ازبین می‌رود)، باید آن را آزاد کنید تا منابعش آزاد شود. مکان مناسب برای انجام این کار جایی است که ازقبل منابع «بازیکن» خود را منتشر می‌کنید. توصیه می‌شود که مدیر را قبل‌از پخش‌کننده منتشر کنید، زیرا اگر دیگر به پیش‌بارگذاری نیاز ندارید، پخش‌کننده می‌تواند به پخش ادامه دهد.

// In your Activity's onDestroy() or Composable's onDispose
preloadManager.release()

زمان نسخه نمایشی

آن را به‌صورت زنده در عمل ببینید 👍

در نسخه نمایشی زیر، تأثیر PreloadManager را در سمت چپ می‌بینیم که زمان بار شدن سریع‌تری دارد، درحالی‌که سمت راست تجربه موجود را نشان می‌دهد. همچنین می‌توانید نمونه کد را برای نسخه نمایشی مشاهده کنید. (امتیاز: همچنین تأخیر راه‌اندازی را برای هر ویدیو نمایش می‌دهد)

Demo-PreloadManager_2.webp

گام بعدی چیست؟

و این پایان قسمت ۱ است! اکنون ابزارهای لازم برای ساختن سیستم پیش‌بارگذاری پویا را دارید. می‌توانید از PreloadConfiguration برای پیش‌بار کردن مورد بعدی فهرست پخش در ExoPlayer استفاده کنید یا DefaultPreloadManager راه‌اندازی کنید، موارد را درحین پخش اضافه و حذف کنید، وضعیت پیش‌بار کردن هدف را پیکربندی کنید، و محتوای پیش‌بارشده را برای بازپخش به‌درستی بازیابی کنید.

در بخش ۲، به DefaultPreloadManager بیشتر می‌پردازیم. بررسی خواهیم کرد که چگونه به رویدادهای پیش‌بارگذاری گوش دهیم، درباره روال‌های مطلوب مانند استفاده از پنجره لغزنده برای جلوگیری از مشکلات حافظه بحث خواهیم کرد، و نگاهی به اجزای مشترک سفارشی ExoPlayer و DefaultPreloadManager خواهیم داشت.

آیا بازخوردی برای هم‌رسانی دارید؟ مشتاقانه منتظر شنیدن نظرات شما هستیم.

منتظر باشید و برنامه‌تان را سریع‌تر کنید! 🚀

نوشته:
ادامه خواندن