پخش زنده

ExoPlayer اکثر پخش‌های زنده تطبیقی ​​را بدون هیچ پیکربندی خاصی و به صورت پیش‌فرض پخش می‌کند. برای جزئیات بیشتر به صفحه فرمت‌های پشتیبانی‌شده مراجعه کنید.

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

تشخیص و نظارت بر پخش زنده

هر بار که یک پنجره زنده به‌روزرسانی می‌شود، نمونه‌های ثبت‌شده Player.Listener یک رویداد onTimelineChanged دریافت می‌کنند. می‌توانید جزئیات مربوط به پخش زنده فعلی را با پرس‌وجو از متدهای مختلف Player و Timeline.Window ، همانطور که در زیر فهرست شده و در شکل بعدی نشان داده شده است، بازیابی کنید.

پنجره زنده

  • Player.isCurrentWindowLive نشان می‌دهد که آیا آیتم رسانه‌ای در حال پخش، یک پخش زنده است یا خیر. این مقدار حتی اگر پخش زنده پایان یافته باشد، همچنان درست است.
  • Player.isCurrentWindowDynamic نشان می‌دهد که آیا آیتم رسانه‌ای در حال پخش هنوز در حال به‌روزرسانی است یا خیر. این معمولاً برای پخش‌های زنده‌ای که هنوز پایان نیافته‌اند صادق است. توجه داشته باشید که این پرچم در برخی موارد برای پخش‌های غیر زنده نیز صادق است.
  • Player.getCurrentLiveOffset انحراف بین زمان واقعی فعلی و موقعیت پخش (در صورت وجود) را برمی‌گرداند.
  • Player.getDuration طول پنجره‌ی پخش زنده‌ی فعلی را برمی‌گرداند.
  • Player.getCurrentPosition موقعیت پخش را نسبت به شروع پنجره پخش زنده برمی‌گرداند.
  • Player.getCurrentMediaItem آیتم رسانه فعلی را برمی‌گرداند، که در آن MediaItem.liveConfiguration شامل overrideهای ارائه شده توسط برنامه برای آفست زنده هدف و پارامترهای تنظیم آفست زنده است.
  • Player.getCurrentTimeline ساختار رسانه فعلی را در یک Timeline برمی‌گرداند. Timeline.Window فعلی را می‌توان با استفاده از Player.getCurrentMediaItemIndex و Timeline.getWindow از Timeline بازیابی کرد. درون Window :
    • Window.liveConfiguration شامل آفست زنده هدف و پارامترهای تنظیم آفست زنده است. این مقادیر بر اساس اطلاعات موجود در رسانه و هرگونه override ارائه شده توسط برنامه در MediaItem.liveConfiguration تنظیم شده‌اند.
    • Window.windowStartTimeMs زمانی است که از عصر یونیکس، پنجره‌ی زنده شروع به کار می‌کند.
    • Window.getCurrentUnixTimeMs زمان از زمان آغاز یونیکس (Unix Epoch) زمان واقعی فعلی است. این مقدار ممکن است با اختلاف ساعت مشخص بین سرور و کلاینت اصلاح شود.
    • Window.getDefaultPositionMs موقعیتی در پنجره پخش زنده است که پخش‌کننده به‌طور پیش‌فرض پخش را از آن شروع می‌کند.

جستجو در پخش زنده

شما می‌توانید با استفاده از Player.seekTo در هر جایی از پنجره‌ی زنده جستجو کنید. موقعیت جستجوی ارسالی نسبت به شروع پنجره‌ی زنده است. برای مثال، seekTo(0) در شروع پنجره‌ی زنده جستجو خواهد کرد. پخش‌کننده سعی می‌کند پس از جستجو، همان فاصله‌ی زنده را با موقعیت مورد نظر حفظ کند.

پنجره پخش زنده همچنین یک موقعیت پیش‌فرض دارد که قرار است پخش از آنجا شروع شود. این موقعیت معمولاً جایی نزدیک به لبه پخش زنده است. می‌توانید با فراخوانی Player.seekToDefaultPosition به موقعیت پیش‌فرض بروید.

رابط کاربری پخش زنده

اجزای رابط کاربری پیش‌فرض ExoPlayer مدت زمان پنجره زنده و موقعیت پخش فعلی درون آن را نشان می‌دهند. این بدان معناست که هر بار که پنجره زنده به‌روزرسانی می‌شود، موقعیت به عقب پرش می‌کند. اگر به رفتار متفاوتی نیاز دارید، مثلاً نمایش زمان یونیکس یا آفست زنده فعلی، می‌توانید PlayerControlView تغییر داده و آن را متناسب با نیازهای خود تغییر دهید.

پیکربندی پارامترهای پخش زنده

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

ExoPlayer مقادیر این پارامترها را از سه مکان، به ترتیب نزولی اولویت، دریافت می‌کند (اولین مقدار یافت شده استفاده می‌شود):

  • مقادیر Per MediaItem که به MediaItem.Builder.setLiveConfiguration ارسال می‌شوند.
  • مقادیر پیش‌فرض سراسری روی DefaultMediaSourceFactory تنظیم شده‌اند.
  • ارزش‌هایی که مستقیماً از رسانه‌ها خوانده می‌شوند.

کاتلین

// Global settings.
val player =
  ExoPlayer.Builder(context)
    .setMediaSourceFactory(DefaultMediaSourceFactory(context).setLiveTargetOffsetMs(5000))
    .build()

// Per MediaItem settings.
val mediaItem =
  MediaItem.Builder()
    .setUri(mediaUri)
    .setLiveConfiguration(
      MediaItem.LiveConfiguration.Builder().setMaxPlaybackSpeed(1.02f).build()
    )
    .build()
player.setMediaItem(mediaItem)

جاوا

// Global settings.
ExoPlayer player =
    new ExoPlayer.Builder(context)
        .setMediaSourceFactory(
            new DefaultMediaSourceFactory(context).setLiveTargetOffsetMs(5000))
        .build();

// Per MediaItem settings.
MediaItem mediaItem =
    new MediaItem.Builder()
        .setUri(mediaUri)
        .setLiveConfiguration(
            new MediaItem.LiveConfiguration.Builder().setMaxPlaybackSpeed(1.02f).build())
        .build();
player.setMediaItem(mediaItem);

مقادیر پیکربندی موجود عبارتند از:

  • targetOffsetMs : آفست زنده هدف. بازیکن در صورت امکان سعی می‌کند در طول پخش به این آفست زنده نزدیک شود.
  • minOffsetMs : حداقل آفست مجاز پخش زنده. حتی هنگام تنظیم آفست با توجه به شرایط فعلی شبکه، پخش‌کننده در حین پخش سعی نمی‌کند از این آفست پایین‌تر بیاید.
  • maxOffsetMs : حداکثر آفست مجاز پخش زنده. حتی هنگام تنظیم آفست با شرایط فعلی شبکه، پخش‌کننده در طول پخش سعی نمی‌کند از این آفست بالاتر برود.
  • minPlaybackSpeed : حداقل سرعت پخشی که بازیکن می‌تواند هنگام تلاش برای رسیدن به آفست زنده هدف، از آن برای عقب‌نشینی استفاده کند.
  • maxPlaybackSpeed : حداکثر سرعت پخشی که بازیکن می‌تواند برای جبران عقب‌ماندگی پخش زنده مورد نظر از آن استفاده کند.

تنظیم سرعت پخش

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

اگر تنظیم خودکار سرعت پخش مورد نظر نباشد، می‌توان آن را با تنظیم ویژگی‌های minPlaybackSpeed ​​و maxPlaybackSpeed ​​روی 1.0f غیرفعال کرد. به طور مشابه، می‌توان آن را برای پخش زنده‌های غیر کم‌تاخیر با تنظیم صریح این ویژگی‌ها روی مقادیری غیر از 1.0f فعال کرد. برای جزئیات بیشتر در مورد نحوه تنظیم این ویژگی‌ها، به بخش پیکربندی بالا مراجعه کنید.

سفارشی‌سازی الگوریتم تنظیم سرعت پخش

اگر تنظیم سرعت فعال باشد، یک LivePlaybackSpeedControl تنظیماتی را که انجام می‌شوند تعریف می‌کند. می‌توان یک LivePlaybackSpeedControl سفارشی پیاده‌سازی کرد یا پیاده‌سازی پیش‌فرض را که DefaultLivePlaybackSpeedControl است، سفارشی‌سازی کرد. در هر دو مورد، می‌توان هنگام ساخت پخش‌کننده، یک نمونه تنظیم کرد:

کاتلین

val player =
  ExoPlayer.Builder(context)
    .setLivePlaybackSpeedControl(
      DefaultLivePlaybackSpeedControl.Builder().setFallbackMaxPlaybackSpeed(1.04f).build()
    )
    .build()

جاوا

ExoPlayer player =
    new ExoPlayer.Builder(context)
        .setLivePlaybackSpeedControl(
            new DefaultLivePlaybackSpeedControl.Builder()
                .setFallbackMaxPlaybackSpeed(1.04f)
                .build())
        .build();

پارامترهای سفارشی‌سازی مربوط به DefaultLivePlaybackSpeedControl عبارتند از:

  • fallbackMinPlaybackSpeed ​​و fallbackMaxPlaybackSpeed : حداقل و حداکثر سرعت پخشی که می‌توان برای تنظیم استفاده کرد، اگر نه رسانه و نه MediaItem ارائه شده توسط برنامه، محدودیتی تعیین نکرده باشند.
  • proportionalControlFactor : میزان نرمی تنظیم سرعت را کنترل می‌کند. مقدار بالا باعث می‌شود تنظیمات ناگهانی‌تر و واکنشی‌تر باشند، اما احتمال شنیدن آنها نیز بیشتر است. مقدار کمتر منجر به انتقال نرم‌تر بین سرعت‌ها می‌شود، اما به قیمت کندتر شدن.
  • targetLiveOffsetIncrementOnRebufferMs : این مقدار هر زمان که یک rebuffer رخ می‌دهد، به target live offset اضافه می‌شود تا با احتیاط بیشتری عمل شود. این ویژگی را می‌توان با تنظیم مقدار روی ۰ غیرفعال کرد.
  • minPossibleLiveOffsetSmoothingFactor : یک ضریب هموارسازی نمایی است که برای ردیابی حداقل آفست زنده ممکن بر اساس رسانه بافر شده فعلی استفاده می‌شود. مقداری بسیار نزدیک به ۱ به این معنی است که تخمین محتاطانه‌تر است و ممکن است زمان بیشتری برای تنظیم با شرایط بهبود یافته شبکه طول بکشد، در حالی که مقدار کمتر به این معنی است که تخمین سریع‌تر تنظیم می‌شود و خطر بیشتری برای مواجه شدن با بافرها وجود دارد.

خطای BehindLiveWindowException و ERROR_CODE_BEHIND_LIVE_WINDOW

موقعیت پخش ممکن است پشت پنجره زنده قرار بگیرد، برای مثال اگر پخش‌کننده برای مدت زمان طولانی متوقف شده یا در حالت بافر باشد. اگر این اتفاق بیفتد، پخش با شکست مواجه می‌شود و یک استثنا با کد خطای ERROR_CODE_BEHIND_LIVE_WINDOW از طریق Player.Listener.onPlayerError گزارش می‌شود. کد برنامه ممکن است بخواهد با از سرگیری پخش در موقعیت پیش‌فرض، چنین خطاهایی را مدیریت کند. PlayerActivity برنامه آزمایشی این رویکرد را نشان می‌دهد.

کاتلین

override fun onPlayerError(error: PlaybackException) {
  if (error.errorCode == PlaybackException.ERROR_CODE_BEHIND_LIVE_WINDOW) {
    // Re-initialize player at the live edge.
    player.seekToDefaultPosition()
    player.prepare()
  } else {
    // Handle other errors
  }
}

جاوا

@Override
public void onPlayerError(PlaybackException error) {
  if (error.errorCode == PlaybackException.ERROR_CODE_BEHIND_LIVE_WINDOW) {
    // Re-initialize player at the live edge.
    player.seekToDefaultPosition();
    player.prepare();
  } else {
    // Handle other errors
  }
}