אודיו מרחבי הוא חוויית אודיו סוחפת שמאפשרת למשתמשים להיות במרכז העניינים, כך שהתוכן נשמע מציאותי יותר. הצליל עובר 'מרחביות' כדי ליצור אפקט של האזנה למספר רמקולים, בדומה להגדרת צליל סראונד, אבל דרך אוזניות במקום רמקולים.
לדוגמה, בסרט, הצליל של מכונית עשוי להתחיל מאחורי המשתמש, לנוע קדימה ולדעוך למרחק. בשיחות וידאו, אפשר להפריד בין הקולות ולמקם אותם מסביב למשתמש, וכך קל יותר לזהות את הדוברים.
אם התוכן שלכם משתמש בפורמט אודיו נתמך, אתם יכולים להוסיף אודיו מרחבי לאפליקציה שלכם החל מ-Android 13 (רמת API 33).
שאילתה לגבי יכולות
אפשר להשתמש במחלקה Spatializer
כדי לשלוח שאילתה לגבי היכולות וההתנהגות של המכשיר בנוגע להפרדה מרחבית. מתחילים באחזור מופע של Spatializer
מ-AudioManager
:
Kotlin
val spatializer = audioManager.spatializer
Java
Spatializer spatializer = AudioManager.getSpatializer();
אחרי שמקבלים את Spatializer
, בודקים אם מתקיימים ארבעת התנאים הבאים שנדרשים כדי שהמכשיר יוציא פלט של אודיו מרחבי:
קריטריונים | סימן וי |
---|---|
האם המכשיר תומך בהוספת אפקט מרחבי? |
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) של המאזין. לדוגמה, כשמשתמש מחבר או מנתק את האוזניות מהמכשיר, הקריאה החוזרת (callback) של onSpatializerAvailableChanged
מציינת אם אפקט המרחב זמין לניתוב החדש של פלט האודיו. בשלב הזה, כדאי לשקול לעדכן את הלוגיקה של בחירת הרצועה בנגן כך שתתאים ליכולות החדשות של המכשיר. פרטים על אופן בחירת הטראקים ב-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 לא בוחר באופן אוטומטי פסקול אודיו שתואם למאפיינים של מכשיר ה-Spatializer. במקום זאת, אפשר להתאים אישית את הלוגיקה של בחירת הטראקים ב-ExoPlayer על ידי הגדרת פרמטרים של בחירת טראקים לפני ההפעלה או במהלכה. כברירת מחדל, 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 כוללת את ההתנהגויות הבאות, שיצרני ציוד מקורי (OEM) יכולים להתאים אישית:
האודיו המרחבי זמין רק בתוכן מרובה ערוצים, ולא בתוכן סטריאו. אם אתם לא משתמשים ב-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. כדי להשבית את האודיו המרחבי בעצמכם, בלי קשר להתאמה אישית של יצרן ציוד מקורי, אפשר לעיין במאמר בנושא השבתת אודיו מרחבי.
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)