اخبار محصول

ارتقای بازپخش رسانه: معرفی پیش‌بارگیری با 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

برای واسط‌های کاربر پویا مانند فیدهای عمودی یا گردونه‌ها، که در آن‌ها مورد «بعدی» براساس تعامل کاربر تعیین می‌شود، 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 که برمی‌گردانید مشخص کنید.

برای مثال،

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

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

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 در پس‌زمینه می‌کند.

After adding, tell the manager to re-evaluate its new list (hinting that something has changed like adding/ removing an item, or the user switches to play a new item.)

preloadManager.invalidate()

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

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

اگر مورد بازیابی‌شده از PreloadManager تهی باشد، یعنی mediaItem هنوز پیش‌بارگیری نشده است یا به PreloadManager اضافه نشده است، بنابراین انتخاب می‌کنید که 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 می‌اندازیم.

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

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

نویسنده:
ادامه خواندن