נגן הוא הרכיב באפליקציה שמאפשר הפעלה של פריטי מדיה.
ממשק Media3 Player
מגדיר מתווה לפונקציונליות שהשחקן בדרך כלל מטפל בה. הזה
כוללת:
- השפעה על פקדי הפעלה, כגון הפעלה, השהיה ודילוג
- שליחת שאילתות למאפיינים של המדיה שמופעלת כרגע, כמו ההפעלה מיקום
- ניהול פלייליסט/תור של פריטי מדיה
- להגדיר את מאפייני ההפעלה, כמו הפעלה אקראית, חזרה, מהירות ו נפח
- מתבצע רינדור של הסרטון למסך
Media3 מספקת גם הטמעה של הממשק של Player
, שנקרא
ExoPlayer
.
ממשק משותף בין רכיבים
חלק מהרכיבים ב-Media3 מטמיעים את ממשק הנגן, לדוגמה:
רכיב | תיאור הערות לגבי התנהגות |
---|---|
ExoPlayer |
API של נגן מדיה והטמעת ברירת המחדל של הממשק Player . |
MediaController |
משתמש באינטראקציה עם MediaSession כדי לשלוח פקודות הפעלה. אם המיקום
Player ו-MediaSession שלך
Service בנפרד מ-Activity או
Fragment במיקום שבו נמצא ממשק המשתמש של הנגן, ניתן להקצות לו
MediaController כנגן
ממשק המשתמש PlayerView . הקריאות לשיטת הפעלה ופלייליסט יישלחו
אל Player דרך MediaSession .
|
MediaBrowser |
בנוסף לפונקציונליות שמציעה
MediaController , מקיים אינטראקציה עם
MediaLibrarySession כדי לעיין בתוכן המדיה הזמין.
|
ForwardingPlayer |
הטמעת Player שמעבירה קריאות ל-method אל
Player נוסף. שימוש במחלקה הזו כדי להסתיר או לשנות
פעולות ספציפיות על ידי שינוי השיטות המתאימות.
|
SimpleBasePlayer |
הטמעת Player שמפחיתה את מספר השיטות
שצריך ליישם עד כה. שימושי כאשר משתמשים בנגן מותאם אישית
ברצונך להתחבר אל MediaSession .
|
CastPlayer |
הטמעת Player שמתקשרת עם Cast
האפליקציה המקבל. ההתנהגות תלויה בסשן הפעלת Cast הבסיסי.
|
אמנם MediaSession
לא מיישם את הממשק Player
, אבל הוא מחייב
Player
כשיוצרים אותו. מטרת הפרויקט היא לתת גישה אל Player
מתהליכים או משרשורים אחרים.
ארכיטקטורת הפעלת מדיה 3
אם יש לך גישה אל Player
, עליך לבצע קריאה לשיטות שלו ישירות כדי להנפיק
פקודות להפעלה. ניתן לפרסם את התוכן שהעלית ולהעניק מקורות חיצוניים
של לחצן ההפעלה על ידי הטמעה של MediaSession
. המקורות החיצוניים האלה
להטמיע MediaController
, שמאפשר להתחבר לסשן מדיה
ושליחת בקשות לפקודות הפעלה.
בעת הפעלת מדיה ברקע, עליך לאחסן את סשן המדיה שלך
בתוך MediaSessionService
או MediaLibraryService
שפועל
שירות שפועל בחזית. אם תעשו זאת, תוכלו להפריד את הנגן מהפעילות
באפליקציה שמכילה את ממשק המשתמש לבקרת ההפעלה. דבר כזה עשוי לחייב
אתם משתמשים בבקר מדיה.
מצב הנגן
המצב של נגן מדיה שמטמיע את הממשק של Player
מורכב
בעיקר מ-4 קטגוריות מידע:
- מצב ההפעלה
- אחזור באמצעות
getPlaybackState()
. - ערך המצב שמוגדר בממשק הוא
STATE_IDLE
STATE_BUFFERING
,STATE_READY
, ו-STATE_ENDED
.
- אחזור באמצעות
- פלייליסט של פריטי מדיה
- רצף של
MediaItem
מופעים להפעלה. - אחזור באמצעות
getCurrentTimeline()
- מופעים של
Player
יכולים לספק שיטות פעולה של פלייליסט, כמו הוספה או הסרהMediaItem
ושיטות נוחות כמוgetCurrentMediaItem()
.
- רצף של
- הפעלה/השהיה של מאפיינים, כמו:
playWhenReady
: אינדיקציה אם המשתמש רוצה להפעיל מדיה כשהדבר אפשרי או להישאר בהשהיה- הסיבה לביטול ההפעלה:
אינדיקציה למה ההפעלה הופסקה, אם רלוונטי, גם אם
playWhenReady
הואtrue
isPlaying
: אינדיקטור שמציין אם הנגן פועל באותו רגע. יוצג רקtrue
אם מצב ההפעלה הואSTATE_READY
,playWhenReady
הואtrue
, וגם ההפעלה לא מבוטלת
- מיקום ההפעלה, כולל:
- האינדקס הנוכחי של פריטי המדיה:
האינדקס של
MediaItem
הנוכחי בפלייליסט. isPlayingAd
: אינדיקציה אם מודעה שהוכנסה מופעלת.- מיקום ההפעלה הנוכחי:
מיקום ההפעלה הנוכחי ב-
MediaItem
הנוכחי או במודעה שהוכנסה.
- האינדקס הנוכחי של פריטי המדיה:
האינדקס של
בנוסף, הממשק של Player
מאפשר גישה
טראקים זמינים,
מטא-נתונים של מדיה,
מהירות ההפעלה,
נפח ועוד
מאפייני העזר של ההפעלה.
האזנה לשינויים
שימוש ב-Player.Listener
כדי להאזין לשינויים ב-Player
. אפשר לעיין בתיעוד של ExoPlayer בכתובת
אירועי שחקן עבור
פרטים על יצירת מאזינים ושימוש בהם.
שימו לב שממשק ה-listener לא כולל קריאות חוזרות (callback) לצורך מעקב רגיל את התקדמות ההפעלה. כדי לעקוב ברציפות אחר התקדמות ההפעלה, למשל כדי להגדיר במעלה ממשק משתמש של סרגל התקדמות, עליכם להריץ שאילתה על המיקום הנוכחי במרווחי זמן מתאימים.
Kotlin
val handler = Handler(Looper.getMainLooper()) fun checkPlaybackPosition(delayMs: Long): Boolean = handler.postDelayed( { val currentPosition = player.currentPosition // Update UI based on currentPosition checkPlaybackPosition(delayMs) }, delayMs)
Java
Handler handler = new Handler(Looper.getMainLooper()); boolean checkPlaybackPosition(long delayMs) { return handler.postDelayed(() -> { long currentPosition = player.getCurrentPosition(); // Update UI based on currentPosition checkPlaybackPosition(delayMs); }, delayMs); }
שליטה בהפעלה
בממשק של Player
יש הרבה דרכים לשנות את המצב ולשלוט
הפעלה:
- רכיבי UI בסיסיים להפעלה
כמו
play()
,pause()
,prepare()
ו-stop()
. - פעולות בפלייליסט, כמו
addMediaItem()
אוremoveMediaItem()
. - רוצים לשנות את הפריט או המיקום הנוכחי.
- להגדיר מצבי חזרה וגם את מצב ההפעלה האקראית.
- עדכון הגרסה העדפות לבחירת טראק.
- מגדירים את מהירות ההפעלה.
הטמעות של Player
בהתאמה אישית
כדי ליצור נגן מותאם אישית, אפשר להרחיב
SimpleBasePlayer
כלולה ב-Media3. הסיווג הזה מספק הטמעה בסיסית של Player
כדי לצמצם למינימום את מספר השיטות שצריך ליישם.
כדי להתחיל, צריך לשנות את ה-method getState()
. השיטה הזו אמורה לאכלס את
על המצב הנוכחי של הנגן בעת קריאה, כולל:
- קבוצת הפקודות הזמינות
- מאפייני הפעלה, למשל אם הנגן צריך להתחיל לפעול כאשר
מצב ההפעלה הוא
STATE_READY
, האינדקס של פריט המדיה שמופעל כרגע, ואת מיקום ההפעלה בתוך הפריט הנוכחי
Kotlin
class CustomPlayer : SimpleBasePlayer(looper) { override fun getState(): State { return State.Builder() .setAvailableCommands(...) // Set which playback commands the player can handle // Configure additional playback properties .setPlayWhenReady(true, PLAY_WHEN_READY_CHANGE_REASON_USER_REQUEST) .setCurrentMediaItemIndex(0) .setContentPositionMs(0) .build() } }
Java
public class CustomPlayer extends SimpleBasePlayer { public CustomPlayer(Looper looper) { super(looper); } @Override protected State getState() { return new State.Builder() .setAvailableCommands(...) // Set which playback commands the player can handle // Configure additional playback properties .setPlayWhenReady(true, PLAY_WHEN_READY_CHANGE_REASON_USER_REQUEST) .setCurrentMediaItemIndex(0) .setContentPositionMs(0) .build(); } }
המדיניות SimpleBasePlayer
אוכפת שה-State
נוצר עם
שילוב של ערכי מצב. הוא גם יטפל במאזינים ויספק מידע
המאזינים של שינויי מצב. אם אתם צריכים להפעיל עדכון מצב באופן ידני,
קוראים לפונקציה invalidateState()
.
מעבר ל-method getState()
, צריך רק להטמיע שיטות שמשתמשים בהן
לפקודות שהנגן מצהיר עליהן שהן זמינות. מוצאים את ה-handler שניתן לשנות
שתואמת לפונקציונליות שרוצים להטמיע. לדוגמה,
לשנות את הערך של handleSeek()
.
שתומכת בפעולות כמו COMMAND_SEEK_IN_CURRENT_MEDIA_ITEM
ו-COMMAND_SEEK_TO_NEXT_MEDIA_ITEM
.