ב-Media3 יש PlayerView
שמוגדר כברירת מחדל, עם כמה אפשרויות התאמה אישית. אנחנו מצפים ממפתחי אפליקציות להטמיע רכיבים משלהם בממשק המשתמש כדי לבצע התאמה אישית נוספת.
שיטות מומלצות
כשמטמיעים ממשק משתמש של מדיה שמתחבר ל-Player
של Media3 (לדוגמה, ExoPlayer
, MediaController
או הטמעה מותאמת אישית של Player
), כדאי ליישם באפליקציות את השיטות המומלצות הבאות כדי ליהנות מחוויית המשתמש הטובה ביותר.
לחצן ההפעלה/השהיה
לחצן ההפעלה וההשהיה לא תואם ישירות למצב של נגן יחיד. לדוגמה, משתמש צריך להיות מסוגל להפעיל מחדש את ההפעלה אחרי שהיא הסתיימה או נכשלה, גם אם הנגן לא מושהה.
כדי לפשט את ההטמעה, Media3 מציע שיטות שמאפשרות להחליט איזה לחצן להציג (Util.shouldShowPlayButton
) ולטפל בלחיצות על לחצנים (Util.handlePlayPauseButtonAction
):
Kotlin
val shouldShowPlayButton: Boolean = Util.shouldShowPlayButton(player) playPauseButton.setImageDrawable(if (shouldShowPlayButton) playDrawable else pauseDrawable) playPauseButton.setOnClickListener { Util.handlePlayPauseButtonAction(player) }
Java
boolean shouldShowPlayButton = Util.shouldShowPlayButton(player); playPauseButton.setImageDrawable(shouldShowPlayButton ? playDrawable : pauseDrawable); playPauseButton.setOnClickListener(view -> Util.handlePlayPauseButtonAction(player));
האזנה לעדכוני המצב
רכיב ממשק המשתמש צריך להוסיף Player.Listener
כדי לקבל עדכונים על שינויים במצב שדורשים עדכון תואם של ממשק המשתמש. פרטים נוספים זמינים במאמר האזנה לאירועי הפעלה.
רענון ממשק המשתמש יכול להיות יקר, ולעיתים קרובות מגיעים כמה אירועי שחקנים יחד. כדי להימנע מרענון ממשק המשתמש בתדירות גבוהה מדי במהלך פרק זמן קצר, עדיף להאזין רק ל-onEvents
ולהפעיל משם עדכונים בממשק המשתמש:
Kotlin
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() } } })
Java
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
צריך לבדוק את פקודות הנגן הזמינות כדי להציג או להסתיר לחצנים, וכדי להימנע מהפעלת שיטות שלא נתמכות:
Kotlin
nextButton.isEnabled = player.isCommandAvailable(Player.COMMAND_SEEK_TO_NEXT)
Java
nextButton.setEnabled(player.isCommandAvailable(Player.COMMAND_SEEK_TO_NEXT));
הצגת התמונה והתריס של הפריים הראשון
כשרכיב בממשק המשתמש מציג סרטון או תמונות, בדרך כלל נעשה בו שימוש בתצוגת תריס של placeholder עד שהפריים או התמונה הראשונים האמיתיים יהיו זמינים. בנוסף, כדי להציג סרטונים ותמונות בו-זמנית, צריך להסתיר ולהציג את תצוגת התמונה בזמנים המתאימים.
דפוס נפוץ לטיפול בעדכונים האלה הוא להאזין ל-Player.Listener.onEvents
כדי לזהות שינויים בטראקים שנבחרו (EVENT_TRACKS_CHANGED
) ולזהות מתי מסגרת הווידאו הראשונה עברה רינדור (EVENT_RENDERED_FIRST_FRAME
), וגם ל-ImageOutput.onImageAvailable
כדי לזהות מתי תמונה חדשה זמינה:
Kotlin
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. }
Java
@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. }