שליטה במדיה באמצעות MediaSession

1. מבוא

עדכון אחרון: 9 בספטמבר 2020

מהם היתרונות של הוספת MediaSession להפעלות של סרטונים?

סשנים במדיה הם קישור בלתי נפרד בין פלטפורמת Android לאפליקציות המדיה. מערכת Android גם מודיעה ל-Android שהמדיה מופעלת, כדי שאפשר יהיה להעביר פעולות של מדיה לסשן הנכון, וגם מודיעה לפלטפורמה מה מופעל ואיך אפשר לשלוט בו.

לחשיפת סשן MediaSession דרך האפליקציה יש יתרונות שונים שהמשתמשים ייהנו מהם. ריכזנו כאן כמה דוגמאות מעולות.

Google Assistant

המשתמשים יכולים לבצע בקלות פעולות מדיה באפליקציה באמצעות פקודות קוליות כמו "Pause", "Resume", ו-"Next". אפשר להשתמש במטא-נתונים מהמדיה שלכם גם כדי לקבל תשובות לגבי התוכן שמושמע כרגע.

Android TV

בחוויות הצפייה במסך גדול, האפליקציה ל-Android TV יכולה להשתמש בשלטים רחוקים רגילים למשתמשים עם טלוויזיות שתומכות ב-HDMI-CEC. הפקודות של הלחצנים 'הפעלה' / 'השהיה', 'עצירה', 'הבא' ו'הקודם' מועברות לאפליקציה שלכם.

פקדי מדיה במסך

החל מ-Android 4.0 (רמת API 14), המערכת יכולה לגשת למצב ההפעלה ולמטא-נתונים של סשן מדיה. הפונקציונליות הזו מאפשרת למסך הנעילה להציג בקרי מדיה וגרפיקה. ההתנהגות הזו משתנה בהתאם לגרסת Android.

מדיה ברקע

אפשר לשלוט במדיה בכל אחד מהתרחישים האלה, גם אם האפליקציה שמפעילה את המדיה פועלת ברקע.

מחשוב סביבה

חשיפת המדיה באמצעות נתונים על מה שמושמע ואיך אפשר לשלוט בו יכולה לגשר בין מכשירים, כך שהמשתמשים יוכלו לקיים אינטראקציה עם מגוון דרכים מהנות.

מה תפַתחו

ב-Codelab הזה, אתם מתכוונים להרחיב את הדוגמה הקיימת של Exo Player כדי להוסיף תמיכה בסשן מדיה. האפליקציה שלך:

  • משקפים בצורה נכונה את המצב הפעיל של סשן המדיה
  • העברה של בקרי מדיה ל-ExpoPlayer
  • העברת מטא-נתונים של פריטים בתור להפעלת המדיה

מה תלמדו

  • למה סשנים במדיה מציעים למשתמשים חוויה עשירה יותר
  • איך ליצור סשן מדיה ולנהל את המצב שלו
  • איך לחבר סשן מדיה ל-ExpoPlayer
  • איך כוללים מטא-נתונים של פריטים בתור ההפעלה במהלך סשן המדיה
  • איך מוסיפים עוד פעולות (מותאמות אישית)

ה-Codelab הזה מתמקד ב-MediaSession SDK. אין דיון במושגים ובלוקים של קוד שלא רלוונטיים, כולל פרטים על הטמעת ExoPlayer, אך ניתנים לך פשוט כדי להעתיק ולהדביק אותם.

מה צריך להכין

  • גרסה עדכנית של Android Studio (3.5 ואילך)
  • ידע בסיסי בפיתוח אפליקציות ל-Android

2. בתהליך ההגדרה

מהי נקודת ההתחלה שלנו?

נקודת ההתחלה היא ההדגמה העיקרית של ExoPlayer. ההדגמה הזו מכילה סרטונים עם פקדי הפעלה במסך, אבל לא משתמשת בסשנים של מדיה מחוץ לקופסה. זה מקום נהדר שבו אנחנו יכולים לצלול לעומק ולהוסיף אותם!

קבלת דוגמת ExoPlayer

כדי להתחיל, נתחיל עם הדוגמה של ExoPlayer. משכפלים את המאגר ב-GitHub על ידי הרצת הקוד הבא.

git clone https://github.com/google/ExoPlayer.git

לפתיחת ההדגמה

ב-Android Studio, פותחים את פרויקט ההדגמה הראשי שנמצא בקטע demos/main.

תוצג ב-Android Studio בקשה להגדיר את נתיב ה-SDK. אם תיתקלו בבעיות, מומלץ לפעול לפי ההמלצות לעדכון כלי הפיתוח המשולב וה-SDK.

10e3b5c652186d57.png

אם התבקשת להשתמש בגרסה העדכנית ביותר של Gradle, עליך לעדכן אותה.

כדאי להקדיש רגע כדי להבין באופן בסיסי איך האפליקציה מתוכננת. שימו לב שיש שתי פעילויות: SampleChooserActivity ו- PlayerActivity. את שאר השיעור של ה-Codelab ב-PlayActivity, שבו המדיה תופעל בפועל, צריך לפתוח את הכיתה הזו ולהמשיך לקטע הבא.

3. יצירת סשן מדיה וניהול המצב שלו

יצירת סשן המדיה

פתיחת PlayerActivity.java. הכיתה הזו יוצרת את ExoPlayer ומנהלת את הפונקציות שלו, למשל עיבוד של סרטון למסך. בפעילות הזו, נחבר את ExoPlayer לסשן מדיה.

מצהירים על שני השדות הבאים בחלק העליון של הכיתה. נשתמש בשדות האלה לאורך החלק הזה.

private MediaSessionCompat mediaSession;
private MediaSessionConnector mediaSessionConnector;

צריך להוסיף את האפשרותextension-mediasession של תלות בפרויקט ב-build.gradle ברמת המודול עבור 'Module: demo':

implementation project(path: ':extension-mediasession')

לתשומת ליבכם: Android Studio יכול לעזור לכם להוסיף את התלות הזאת באופן אוטומטי אם מעבירים את העכבר מעל השגיאה בפתרון MediaSessionConnector:

60055e4ad54fbb97.png

בסוף, פותרים את הבעיה של ייבוא הכיתה באמצעות הוספת הפרטים הבאים:

import android.support.v4.media.session.MediaSessionCompat;
import com.google.android.exoplayer2.ext.mediasession.MediaSessionConnector;

כשהפעילות נוצרת, נרצה ליצור סשן מדיה ומחבר סשן מדיה שישמש כמתווכת בין סשן המדיה לבין ExoPlayer.

המקום האידיאלי להכניס אותו הוא גם המקום שבו נוצר ExoPlayer. באפליקציית ההדגמה שלנו אפשר לצרף את הקוד בסוף initializePlayer(). חשוב להוסיף את הלוגיקה הזו אחרי היצירה של הנגן!

private void initializePlayer() {
  if (player == null) {
    ...
    player = ...
    ...
    mediaSession = new MediaSessionCompat(this, "sample");
    mediaSessionConnector = new MediaSessionConnector(mediaSession);
    mediaSessionConnector.setPlayer(player);
  }
  ...
}

ביטול סשן המדיה

משחררים את סשן המדיה כשאין בו יותר צורך. כשאנחנו משיקים את ExoPlayer ב-releasePlayer(), אנחנו יכולים לכלול גם את הקוד הבא כדי לעשות זאת:

private void releasePlayer() {
  if (mediaSession != null) {
    mediaSession.release();
  }
  ...
}

ניהול המצב של סשן המדיה

עכשיו, אחרי שיצרנו את הסשן של המדיה, צריך לוודא שהמצב שלו משתקף בצורה נכונה כשהמשתמש מקיים אינטראקציה עם הפעילות.

כשהמשתמש מתחיל את הפעילות, סשן המדיה צריך להפוך לפעיל:

@Override
public void onStart() {
  ...
  if (mediaSession != null) {
    mediaSession.setActive(true);
  }
}

מכיוון שהאפליקציה לא מפעילה מדיה ברקע, חשוב לוודא שסשן המדיה הופך ללא פעיל כשהמשתמש עוזב את הפעילות:

@Override
public void onStop() {
  super.onStop();
  if (mediaSession != null) {
    mediaSession.setActive(false);
  }
  ...
}

עכשיו נריץ את ההדגמה

  1. מחברים מכשיר Android או מפעילים אמולטור.
  2. צריך לוודא שהשדה 'הדגמה' מופעלת בסרגל הכלים של Android Studio. cb1ec4e50886874f.png
  3. לוחצים על 9d8fb3a9ddf12827.png בסרגל הכלים של Android Studio.
  4. אחרי שהאפליקציה מופעלת במכשיר, בוחרים שידור וידאו שרוצים להפעיל.
  5. לאחר התחלת ההפעלה, תוכלו להשתמש בפקודות adb הבאות כדי לשלוט בסשן המדיה:
adb shell media dispatch pause
adb shell media dispatch play
adb shell media dispatch play-pause
adb shell media dispatch fast-forward
adb shell media dispatch rewind
  1. כדאי גם לבדוק איך מערכת Android מזהה את סשן המדיה שלך. באופן ספציפי, אתם יכולים לבדוק אילו פעולות נתמכות בשדה הפעולה. המספר שמופיע כאן הוא שילוב של מזהי פעולות, כפי שהוצהר באובייקט PlaybackState. כדי לראות את ההרצה של המדיה: adb shell dumpsys media_session
  2. אם אתם משתמשים במכשיר פיזי עם מיקרופון, נסו להפעיל את Google Assistant ולבצע פקודות קוליות כמו: "Pause". ‏"Resume" "Fast- forward 1 minutes" (הרצה 1 דקה קדימה).

b8dda02a6fb0f6a4.pngדוגמה של ExoPlayer פועלת ב-Android TV.

4. הכללת מטא-נתונים של פריטים בתור ההפעלה

עכשיו אנחנו יכולים להרחיב את התכונות הנתמכות בסשן המדיה שלנו שבו יצרנו בעבר את MediaSessionConnector שלנו ב-initializePlayer().

הוספת ציר זמןQueueNavigator

ExoPlayer מייצג את המבנה של המדיה כציר זמן. לפרטים על האופן שבו זה עובד, כדאי להקדיש כמה רגעים כדי לקרוא על אובייקט ציר הזמן של ExoPlayer. באמצעות גישה למבנה הזה, נוכל לקבל מידע על שינויים בתוכן ולחשוף מטא-נתונים של מה שמושמע כרגע כשתתבקשו.

כדי לעשות זאת, נגדיר TimeQueueNavigator. מאתרים את המופע של MediaSessionConnector ב-initializePlayer() ומוסיפים הטמעה של deliveryQueueNavigator אחרי האתחול של mediaSession.

mediaSessionConnector.setQueueNavigator(new TimelineQueueNavigator(mediaSession) {
  @Override
  public MediaDescriptionCompat getMediaDescription(Player player, int windowIndex) {
    return new MediaDescriptionCompat.Builder()
            .setTitle(player.getCurrentMediaItem().mediaMetadata.title)
            .setDescription("MediaDescription description for " + windowIndex)
            .setSubtitle("MediaDescription subtitle")
            .build();
  }
});

כדי לפתור את ייבוא הכיתה, מוסיפים:

import android.support.v4.media.MediaDescriptionCompat;
import com.google.android.exoplayer2.ext.mediasession.TimelineQueueNavigator;

חשוב לוודא שהפרמטר windowIndex תואם לפריט של אותו אינדקס בתור ההפעלה.

עכשיו, אחרי שהוספת מטא-נתונים, אפשר לבדוק ש-Assistant מבינה מה מושמע. בזמן הצפייה בסרטון ב-Android TV, צריך להפעיל את Assistant ולשאול "What's playing? "

6c7fc0cb853cbc38.png

5. התאמה אישית של פעולות

יכול להיות שהנגן לא תומך בפעולות מסוימות, או שברצונך לכלול תמיכה בפעולות נוספות? עכשיו נתעמק קצת בסשן המדיה שבו יצרנו בעבר את MediaSessionConnector שלנו ב-initializePlayer().

הצהרה על פעולות נתמכות

אפשר להשתמש ב-mediaSessionConnector.setEnabledPlaybackActions() כדי להתאים אישית את הפעולות שבהן רוצים שסשן המדיה יתמוך.

חשוב לשים לב: הקבוצה המלאה:

mediaSessionConnector.setEnabledPlaybackActions(
        PlaybackStateCompat.ACTION_PLAY_PAUSE
                | PlaybackStateCompat.ACTION_PLAY
                | PlaybackStateCompat.ACTION_PAUSE
                | PlaybackStateCompat.ACTION_SEEK_TO
                | PlaybackStateCompat.ACTION_FAST_FORWARD
                | PlaybackStateCompat.ACTION_REWIND
                | PlaybackStateCompat.ACTION_STOP
                | PlaybackStateCompat.ACTION_SET_REPEAT_MODE
                | PlaybackStateCompat.ACTION_SET_SHUFFLE_MODE
);

בואו נראה שוב איך הנתונים האלה נחשפים לפלטפורמה:

  1. כמו קודם, אתם יכולים להתחיל סרטון.
  2. כדי לגלות איך מערכת Android מזהה את המטא-נתונים מסשן המדיה שלך, מריצים את adb shell dumpsys media_session
  3. מאתרים את השורה שמכילה מטא-נתונים ומוודאים שהכותרת והתיאור כלולים ומשויך ל-com.google.android.exoplayer2.demo/sample.

הוספה של פעולות נוספות

אנחנו יכולים להרחיב את סשן המדיה שלנו עם כמה פעולות נוספות. בקטע הזה נוסיף רק תמיכה בכתוביות.

כתוביות נתמכות

הוספת תמיכה בכתוביות לפעילויות של מדיה מאפשרת למשתמשים להחליף מצב שלהן באמצעות הקול. במקום שבו אתחלת את המחבר להפעלת מדיה, מוסיפים את הפרטים הבאים:

mediaSessionConnector.setCaptionCallback(new MediaSessionConnector.CaptionCallback() {
      @Override
      public void onSetCaptioningEnabled(Player player, boolean enabled) {
        Log.d("MediaSession", "onSetCaptioningEnabled: enabled=" + enabled);
      }

      @Override
      public boolean hasCaptions(Player player) {
        return true;
      }

      @Override
      public boolean onCommand(Player player, ControlDispatcher controlDispatcher, String command, Bundle extras, ResultReceiver cb) {
        return false;
      }
    }
);

לסיום, פותרים בעיות ייבוא חסרות.

כדי לבדוק את זה, אפשר להפעיל את Google Assistant ב-Android TV ולהגיד "הפעלת כתוביות". כדי לבדוק איך השיחות מגיעות לקוד, צריך להיכנס ל-Logcat.

6. מזל טוב

מזל טוב, הוספת בהצלחה פעילויות מדיה לדוגמה!

קיבלת כמות עצומה של פונקציונליות בזכות:

  • כשמוסיפים סשן מדיה,
  • שיחברו סשנים של מדיה למכונה של ExoPlayer,
  • הוספת מטא-נתונים ופעולות נוספות.

עכשיו אתם יודעים מהם השלבים העיקריים שצריך לבצע כדי להעשיר את אפליקציית המדיה ולהציע למשתמשים חוויה מגוונת יותר!

הערה סופית

ה-Codelab הזה נבנה על גבי דגימה מקוד המקור של ExoPlayer. אין צורך להשתמש ב-ExoPlayer ממקור, ובמקום זאת מומלץ לשלוף את יחסי התלות של ExoPlayer ושל MediaSessionConnector כדי שיהיה קל יותר להתעדכן בגרסאות האחרונות.

כדי לעשות את זה, פשוט מחליפים את יחסי התלות של הפרויקט, כמו:

implementation project(modulePrefix + 'library-core')
implementation project(path: ':extension-mediasession')

לשלוף ממאגרים של Maven, כמו:

implementation 'com.google.android.exoplayer:exoplayer-core:2.+'
implementation 'com.google.android.exoplayer:extension-mediasession:2.+'

מסמכי עזר