سفارشی سازی UI

Media3 یک PlayerView پیش‌فرض ارائه می‌کند که برخی از گزینه‌های سفارشی‌سازی را ارائه می‌کند. برای هر گونه سفارشی سازی بیشتر، از توسعه دهندگان برنامه انتظار می رود اجزای رابط کاربری خود را پیاده سازی کنند.

بهترین شیوه ها

هنگام پیاده‌سازی یک رابط کاربری رسانه‌ای که به Media3 Player متصل می‌شود (به عنوان مثال ExoPlayer ، MediaController یا پیاده‌سازی Player سفارشی)، به برنامه‌ها توصیه می‌شود این بهترین شیوه‌ها را برای بهترین تجربه رابط کاربری دنبال کنند.

دکمه پخش/مکث

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

برای ساده‌سازی پیاده‌سازی، Media3 روش‌هایی را برای تصمیم‌گیری اینکه کدام دکمه نمایش داده شود ( Util.shouldShowPlayButton ) و برای کنترل فشار دادن دکمه ( Util.handlePlayPauseButtonAction ) ارائه می‌کند:

کاتلین

val shouldShowPlayButton: Boolean = Util.shouldShowPlayButton(player)
playPauseButton.setImageDrawable(if (shouldShowPlayButton) playDrawable else pauseDrawable)
playPauseButton.setOnClickListener { Util.handlePlayPauseButtonAction(player) }

جاوا

boolean shouldShowPlayButton = Util.shouldShowPlayButton(player);
playPauseButton.setImageDrawable(shouldShowPlayButton ? playDrawable : pauseDrawable);
playPauseButton.setOnClickListener(view -> Util.handlePlayPauseButtonAction(player));

به به روز رسانی های ایالت گوش دهید

مؤلفه رابط کاربری باید یک Player.Listener اضافه کند تا از تغییرات وضعیتی که نیاز به به‌روزرسانی رابط کاربری مربوطه دارند مطلع شود. برای جزئیات بیشتر به گوش دادن به رویدادهای پخش مراجعه کنید.

تازه کردن رابط کاربری ممکن است پرهزینه باشد و رویدادهای چند بازیکن اغلب با هم می آیند. برای جلوگیری از به‌روزرسانی بیش از حد UI در مدت زمان کوتاه، معمولاً بهتر است فقط به onEvents گوش دهید و به‌روزرسانی‌های UI را از آنجا فعال کنید:

کاتلین

player.addListener(object : Player.Listener{
  override fun onEvents(player: Player, events: Player.Events){
    if (events.containsAny(
        Player.EVENT_PLAY_WHEN_READY_CHANGED,
        Player.EVENT_PLAYBACK_STATE_CHANGED,
        Player.EVENT_PLAYBACK_SUPPRESSION_REASON_CHANGED)) {
      updatePlayPauseButton()
    }
    if (events.containsAny(Player.EVENT_REPEAT_MODE_CHANGED)) {
      updateRepeatModeButton()
    }
  }
})

جاوا

player.addListener(new Player.Listener() {
  @Override
  public void onEvents(Player player, Player.Events events) {
    if (events.containsAny(
        Player.EVENT_PLAY_WHEN_READY_CHANGED,
        Player.EVENT_PLAYBACK_STATE_CHANGED,
        Player.EVENT_PLAYBACK_SUPPRESSION_REASON_CHANGED)) {
      updatePlayPauseButton();
    }
    if (events.containsAny(Player.EVENT_REPEAT_MODE_CHANGED)) {
      updateRepeatModeButton();
    }
  }
});

کنترل دستورات موجود

یک مؤلفه رابط کاربری عمومی که ممکن است نیاز به کار با پیاده سازی های مختلف Player باشد، باید دستورات پخش کننده موجود را برای نمایش یا پنهان کردن دکمه ها و جلوگیری از فراخوانی روش های پشتیبانی نشده بررسی کند:

کاتلین

nextButton.isEnabled = player.isCommandAvailable(Player.COMMAND_SEEK_TO_NEXT)

جاوا

nextButton.setEnabled(player.isCommandAvailable(Player.COMMAND_SEEK_TO_NEXT));

اولین شاتر فریم و نمایش تصویر

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

یک الگوی رایج برای رسیدگی به این به‌روزرسانی‌ها، گوش دادن به Player.Listener.onEvents برای هرگونه تغییر در آهنگ‌های انتخابی ( EVENT_TRACKS_CHANGED ) و زمانی که اولین فریم ویدیو رندر شده است ( EVENT_RENDERED_FIRST_FRAME )، و همچنین ImageOutput.onImageAvailable برای زمانی که یک تصویر جدید است. موجود است:

کاتلین

override fun onEvents(player: Player, events: Player.Events) {
  if (events.contains(Player.EVENT_TRACKS_CHANGED)) {
    // If no video or image track: show shutter, hide image view.
    // Otherwise: do nothing to wait for first frame or image.
  }
  if (events.contains(Player.EVENT_RENDERED_FIRST_FRAME)) {
    // Hide shutter, hide image view.
  }
}

override fun onImageAvailable(presentationTimeUs: Long, bitmap: Bitmap) {
  // Show shutter, set image and show image view.
}

جاوا

@Override
public void onEvents(Player player, Events events) {
  if (events.contains(Player.EVENT_TRACKS_CHANGED)) {
    // If no video or image track: show shutter, hide image view.
    // Otherwise: do nothing to wait for first frame or image.
  }
  if (events.contains(Player.EVENT_RENDERED_FIRST_FRAME)) {
    // Hide shutter, hide image view.
  }
}

@Override
public void onImageAvailable(long presentationTimeUs, Bitmap bitmap) {
  // Show shutter, set image and show image view.
}