אודיו מרחבי

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

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

אם התוכן שלכם כולל פורמט אודיו נתמך, תוכלו להוסיף אודיו מרחבי אפליקציה שמתחילה ב-Android 13 (רמת API 33).

שאילתת יכולות

להשתמש בכיתה Spatializer כדי לשלוח שאילתה על יכולות המרחב ועל ההתנהגות של המכשיר. קודם כול צריך לאחזר את הנתונים מופע של Spatializer AudioManager:

Kotlin

val spatializer = audioManager.spatializer

Java

Spatializer spatializer = AudioManager.getSpatializer();

אחרי שמקבלים את Spatializer, כדאי לבדוק את ארבעת התנאים שחייבים להתקיים True כדי שהמכשיר יפיק אודיו מרחבי:

קריטריונים בדיקה
האם המכשיר תומך במרחב? getImmersiveAudioLevel() אינו SPATIALIZER_IMMERSIVE_LEVEL_NONE
האם אפשר להשתמש במרחב משותף?
הזמינות תלויה בתאימות לניתוב הנוכחי של פלט האודיו.
isAvailable() היא true
האם המרחב מופעל? isEnabled() היא true
האם אפשר להתאים מרחבי טראק של אודיו עם הפרמטרים הנתונים? canBeSpatialized() היא true

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

מעקב אחר תנועות הראש

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

תוכן תואם

Spatializer.canBeSpatialized() מציין אם ניתן מרחבי אודיו עם המאפיינים הנתונים הניתוב הנוכחי של מכשיר הפלט. השיטה הזו אורכת AudioAttributes וגם AudioFormat, ששניהם כמתואר בפירוט בהמשך.

AudioAttributes

אובייקט AudioAttributes שמתאר את השימוש שידור אודיו (לדוגמה, אודיו של משחק או מדיה רגילה), יחד עם התנהגויות ההפעלה וסוג התוכן שלו.

בשיחה אל canBeSpatialized(), צריך להשתמש באותה AudioAttributes כפי שמוגדר ל-Player. לדוגמה, אם אתם משתמשים בספריית Jetpack Media3 ולא ביצעתם התאמה אישית של AudioAttributes, שימוש ב-AudioAttributes.DEFAULT.

השבתת האודיו המרחבי

כדי לציין שהתוכן שלכם כבר תופס במרחב, צריך להתקשר setIsContentSpatialized(true) כדי שהאודיו לא יעבור עיבוד כפול. לחלופין, משנים את התנהגות של התאמה מרחבית כדי להשבית לגמרי את המרחב באמצעות קריאה setSpatializationBehavior(AudioAttributes.SPATIALIZATION_BEHAVIOR_NEVER)

AudioFormat

אובייקט AudioFormat מתאר פרטים על הפורמט ועל תצורת הערוץ של טראק של אודיו.

כשמייצרים מופע של AudioFormat שצריך לעבור אל canBeSpatialized(), הגדרת הקידוד להיות זהה לפורמט הפלט שמצופה מהמפענח. צריך גם להגדיר מסכת ערוץ שתואם לתצורת הערוץ של התוכן. עיינו ב הקטע התנהגות ברירת מחדל של מרחבים משותפים לקבלת הנחיות לגבי ערכים ספציפיים לשימוש.

האזנה לשינויים בSpatializer

אפשר להוסיף מאזינים כדי להאזין לשינויים במצב של Spatializer עם Spatializer.addOnSpatializerStateChangedListener(). באופן דומה, כדי להאזין לשינויים בזמינות של מכשיר למעקב אחר תנועות הראש, קוראים לפונקציה Spatializer.addOnHeadTrackerAvailableListener().

האפשרות הזו שימושית אם רוצים לשנות את בחירת הטראק במהלך ההפעלה באמצעות הקריאות החוזרות (callback) של המאזין. לדוגמה, כשמשתמש מחבר או מנתק את אוזניות מהמכשיר, onSpatializerAvailableChanged קריאה חוזרת (callback) מציינת אם אפקט המרחב המשותף זמין ניתוב פלט אודיו. בשלב זה, תוכל לשקול לעדכן את לעקוב אחרי לוגיקת הבחירה כדי להתאים ליכולות החדשות של המכשיר. לפרטים על אופן בחירת הטראק של ExoPlayer: מומלץ לעיין במאמר ExoPlayer ואודיו מרחבי. .

נגן ExoPlayer ואודיו מרחבי

הגרסאות האחרונות של ExoPlayer מקלות על השימוש באודיו מרחבי. אם משתמשים ספריית ExoPlayer העצמאית (שם החבילה com.google.android.exoplayer2), בגרסה 2.17 מגדירה את הפלטפורמה לפלט של אודיו מרחבי וגרסה 2.18 כולל מגבלות על מספר ערוצי האודיו. אם משתמשים במודול ExoPlayer מספריית Media3, (שם החבילה) androidx.media3), גרסאות 1.0.0-beta01 ועדכונים חדשים יותר כוללים את אותם עדכונים.

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

מגבלות על מספר ערוצי האודיו

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

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

Kotlin

exoPlayer.trackSelectionParameters = DefaultTrackSelector.Parameters.Builder(context)
  .setConstrainAudioChannelCountToDeviceCapabilities(false)
  .build()

Java

exoPlayer.setTrackSelectionParameters(
  new DefaultTrackSelector.Parameters.Builder(context)
    .setConstrainAudioChannelCountToDeviceCapabilities(false)
    .build()
);

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

Kotlin

val trackSelector = DefaultTrackSelector(context)
...
trackSelector.parameters = trackSelector.buildUponParameters()
  .setConstrainAudioChannelCountToDeviceCapabilities(false)
  .build()

Java

DefaultTrackSelector trackSelector = new DefaultTrackSelector(context);
...
trackSelector.setParameters(
  trackSelector
    .buildUponParameters()
    .setConstrainAudioChannelCountToDeviceCapabilities(false)
    .build()
);

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

בחירת טראק של אודיו

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

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

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

Kotlin

exoPlayer.trackSelectionParameters = exoPlayer.trackSelectionParameters
  .buildUpon()
  .setMaxAudioChannelCount(2)
  .build()

Java

exoPlayer.setTrackSelectionParameters(
  exoPlayer.getTrackSelectionParameters()
    .buildUpon()
    .setMaxAudioChannelCount(2)
    .build()
);

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

התנהגות ברירת המחדל של הפריסה המרחבית

התנהגות ברירת המחדל של הצגת המרחב המשותף ב-Android כוללת את ההתנהגויות הבאות שעשוי להיות מותאם אישית על ידי יצרני ציוד מקורי:

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

    Kotlin

    val mediaFormat = MediaFormat()
    mediaFormat.setInteger(MediaFormat.KEY_MAX_OUTPUT_CHANNEL_COUNT, 99)
    

    Java

    MediaFormat mediaFormat = new MediaFormat();
    mediaFormat.setInteger(MediaFormat.KEY_MAX_OUTPUT_CHANNEL_COUNT, 99);
    

    כדי לראות דוגמה בפעולה, אפשר לעיין ב-MediaCodecAudioRenderer.java של ExoPlayer. כדי להשבית את המרחב המשותף, בלי קשר ל-OEM למידע נוסף, כדאי לעיין במאמר השבתת אודיו מרחבי.

  • AudioAttributes: אפשר להשתמש באודיו מרחבי אם usage מוגדר כ-USAGE_MEDIA או USAGE_GAME.

  • AudioFormat: משתמשים במסכת ערוץ שמכילה לפחות את המאפיין של AudioFormat.CHANNEL_OUT_QUAD ערוצים (שמאליים קדמיים, ימניים, אחוריים וימניים) בשביל האודיו כשירות לשימוש במרחב משותף. בדוגמה הבאה אנחנו משתמשים בפונקציה AudioFormat.CHANNEL_OUT_5POINT1 לטראק של אודיו 5.1. לטראק של אודיו בסטריאו, משתמשים ב-AudioFormat.CHANNEL_OUT_STEREO.

    אם משתמשים ב-Media3, אפשר להשתמש ב-Util.getAudioTrackChannelConfig(int channelCount) כדי להמיר ספירת ערוצים למסכה של ערוץ.

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

    Kotlin

    val audioFormat = AudioFormat.Builder()
      .setEncoding(AudioFormat.ENCODING_PCM_16BIT)
      .setChannelMask(AudioFormat.CHANNEL_OUT_5POINT1)
      .build()
    

    Java

    AudioFormat audioFormat = new AudioFormat.Builder()
      .setEncoding(AudioFormat.ENCODING_PCM_16BIT)
      .setChannelMask(AudioFormat.CHANNEL_OUT_5POINT1)
      .build();
    

בדיקת אודיו מרחבי

צריך לוודא שאודיו מרחבי מופעל במכשיר הבדיקה:

  • לאוזניות חוטיות, עוברים אל הגדרות מערכת > צליל ו רטט > מרחבי אודיו.
  • לאוזניות אלחוטיות, עוברים אל הגדרות מערכת > מכשירים מחוברים > סמל גלגל השיניים עבור המכשיר האלחוטי שלך > אודיו מרחבי.

כדי לבדוק את הזמינות של אודיו מרחבי בניתוב הנוכחי, מריצים את הפקודה הפקודה adb shell dumpsys audio במכשיר. אתם אמורים לראות את הדברים הבאים פרמטרים בפלט בזמן שההפעלה פעילה:

Spatial audio:
mHasSpatializerEffect:true (effect present)
isSpatializerEnabled:true (routing dependent)