נגן הוא הרכיב באפליקציה שמסייע בהפעלה של פריטי מדיה.
ממשק Media3 Player מגדיר תוכנית לפונקציונליות שמטופלת בדרך כלל על ידי נגן. זה כולל:
- השפעה על אמצעי הבקרה של ההפעלה, כמו הפעלה, השהיה וחיפוש
- שאילתה לגבי מאפיינים של המדיה שמופעלת כרגע, כמו מיקום ההפעלה
- ניהול פלייליסט או תור של פריטי מדיה
- הגדרת מאפייני ההפעלה, כמו ערבוב, חזרה, מהירות ועוצמת הקול
- רינדור הסרטון במסך
Media3 מספק גם הטמעה של הממשק Player, שנקרא ExoPlayer.
ממשק משותף בין הרכיבים
כמה רכיבים ב-Media3 מטמיעים את ממשק Player, למשל:
| רכיב | תיאור והערות לגבי ההתנהגות |
|---|---|
ExoPlayer |
ממשק API של נגן מדיה וההטמעה שמוגדרת כברירת מחדל של הממשק Player. |
MediaController |
אינטראקציה עם MediaSession כדי לשלוח פקודות הפעלה. אם Player ו-MediaSession נמצאים ב-Service נפרד מ-Activity או מ-Fragment שבו נמצא ממשק המשתמש של השחקן, אפשר להקצות את MediaController כשחקן לממשק המשתמש של PlayerView. הקריאות לשיטות של הפלייליסט וההפעלה נשלחות אל Player דרך MediaSession.
|
MediaBrowser |
בנוסף לפונקציונליות שמציע MediaController, הוא מקיים אינטראקציה עם MediaLibrarySession כדי לעיין בתוכן מדיה זמין.
|
SimpleBasePlayer |
הטמעה של Player שמצמצמת את מספר השיטות
שצריך להטמיע למינימום. התכונה הזו שימושית כשמשתמשים בנגן מותאם אישית שרוצים לקשר ל-MediaSession.
|
ForwardingSimpleBasePlayer |
מחלקת משנה SimpleBasePlayer שנועדה להעביר פעולות הפעלה ל-Player אחר, תוך מתן אפשרות להתאמות אישיות עקביות של התנהגות כמו SimpleBasePlayer. אפשר להשתמש במחלקה הזו כדי להשבית או לשנות פעולות הפעלה ספציפיות.
|
RemoteCastPlayer |
הטמעה של Player לשליטה בהפעלה באפליקציית מקלט Cast מרחוק.
|
CastPlayer |
הטמעה של Player לשליטה בהפעלה של Cast מקומית ומרחוק.
|
למרות ש-MediaSession לא מטמיע את הממשק Player, הוא דורש Player כשיוצרים אותו. המטרה שלו היא לספק גישה ל-Player מתהליכים או משרשורים אחרים.
ארכיטקטורה של הפעלת מדיה ב-Media3
אם יש לכם גישה ל-Player, אתם צריכים להפעיל את השיטות שלו ישירות כדי להנפיק פקודות הפעלה. אתם יכולים לפרסם את ההפעלה ולהעניק למקורות חיצוניים שליטה בהפעלה על ידי הטמעה של MediaSession. המקורות החיצוניים האלה מטמיעים MediaController, שמקל על החיבור להפעלת מדיה ועל שליחת בקשות להפעלת פקודות.
כשמפעילים מדיה ברקע, צריך לאחסן את סשן המדיה ואת נגן המדיה ב-MediaSessionService או ב-MediaLibraryService שפועלים כשירות בחזית. אם תעשו את זה, תוכלו להפריד את השחקן מהפעילות באפליקציה שמכילה את ממשק המשתמש לשליטה בהפעלה. יכול להיות שתצטרכו להשתמש בממשק השליטה במדיה.
Player יש תפקיד מרכזי בארכיטקטורה של Media3.מצב השחקן
המצב של נגן מדיה שמטמיע את הממשק 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וההפעלה לא מושבתת
-
- מיקום ההפעלה, כולל:
- Current media item index:
האינדקס של
MediaItemהנוכחי בפלייליסט. -
isPlayingAd: ציון אם מודעה שהוכנסה מוצגת. - Current playback position:
מיקום ההפעלה הנוכחי בתוך
MediaItemהנוכחי או המודעה שמוצגת.
- Current media item index:
האינדקס של
בנוסף, הממשק של Player מאפשר גישה לרצועות הזמינות, למטא נתונים של המדיה, למהירות ההפעלה, לעוצמת הקול ולמאפיינים נוספים של ההפעלה.
האזנה לשינויים
משתמשים ב-Player.Listener
כדי לחפש שינויים ב-Player. במאמר אירועים של נגן בתיעוד של ExoPlayer מוסבר איך ליצור listener ולהשתמש בו.
שימו לב שממשק המאזין לא כולל קריאות חוזרות (callback) למעקב אחרי התקדמות רגילה בהפעלה. כדי לעקוב באופן רציף אחרי התקדמות ההפעלה, למשל כדי להגדיר ממשק משתמש של סרגל התקדמות, צריך לשלוח שאילתה לגבי המיקום הנוכחי במרווחי זמן מתאימים.
Kotlin
fun checkPlaybackPosition(delayMs: Long): Boolean = handler.postDelayed( { val currentPosition = player.currentPosition // Update UI based on currentPosition checkPlaybackPosition(delayMs) }, delayMs, )
Java
boolean checkPlaybackPosition(long delayMs) { return handler.postDelayed( () -> { long currentPosition = player.getCurrentPosition(); // Update UI based on currentPosition checkPlaybackPosition(delayMs); }, delayMs); }
שליטה בהפעלה
ממשק Player מציע הרבה דרכים לשנות את המצב ולשלוט בהפעלה:
- אמצעי בקרה בסיסיים להפעלה
כמו
play(), pause(), prepare()ו-stop(). - פעולות בפלייליסטים כמו
addMediaItem()אוremoveMediaItem(). - חיפוש כדי לשנות את הפריט או המיקום הנוכחיים.
- מגדירים מצבי חזרה ומצב הפעלה אקראית.
- עדכון העדפות הבחירה של רצועות.
- מגדירים את מהירות ההפעלה.
הטמעות Player בהתאמה אישית
כדי ליצור נגן בהתאמה אישית, אפשר להרחיב את
SimpleBasePlayer
שנכלל ב-Media3. המחלקה הזו מספקת הטמעה בסיסית של הממשק Player
כדי לצמצם את מספר השיטות שצריך להטמיע למינימום.
מתחילים בהחלפת השיטה getState(). ה-method הזו צריכה לאכלס את מצב השחקן הנוכחי כשהיא מופעלת, כולל:
- קבוצת הפקודות הזמינות
- מאפייני ההפעלה, כמו האם הנגן צריך להתחיל להפעיל כשהמצב הוא
STATE_READY, האינדקס של קובץ המדיה שמופעל כרגע ומיקום ההפעלה בפריט הנוכחי
Kotlin
class CustomPlayer(looper: Looper) : SimpleBasePlayer(looper) { override fun getState(): State { return State.Builder() .setAvailableCommands(Commands.EMPTY) // 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
private static final class CustomPlayer extends SimpleBasePlayer { public CustomPlayer(Looper looper) { super(looper); } @Override protected State getState() { return new State.Builder() .setAvailableCommands(Commands.EMPTY) // 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().
מעבר לשיטה getState(), צריך להטמיע רק שיטות שמשמשות לפקודות שהנגן מצהיר שהן זמינות. מוצאים את שיטת הטיפול שאפשר לבטל שמתאימה לפונקציונליות שרוצים להטמיע. לדוגמה, אפשר לשנות את השיטה handleSeek() כדי לתמוך בפעולות כמו COMMAND_SEEK_IN_CURRENT_MEDIA_ITEM ו-COMMAND_SEEK_TO_NEXT_MEDIA_ITEM.
שינוי הטמעות של Player
במקום ליצור Player בהתאמה אישית מלאה, אפשר להשתמש ב-ForwardingSimpleBasePlayer כדי לשנות את המצב וההתנהגות של Player קיים. פרטים נוספים זמינים במדריך בנושא דף ההתאמה האישית.