אודיו מרחבי הוא חוויית אודיו immersive שמציבה את המשתמשים במרכז הפעולה, וכך הופכת את התוכן למציאותי יותר. הקול 'מקבל מיקום מרחבי' כדי ליצור אפקט של רמקולים מרובים, בדומה להגדרת צליל סראונד, אבל באוזניות.
לדוגמה, בסרט, הצליל של מכונית עשוי להתחיל מאחורי המשתמש, לנוע קדימה ולהיעלם במרחק. בצ'אט וידאו, אפשר להפריד בין הקולות ולהציב אותם סביב המשתמש, כדי שיהיה קל יותר לזהות את הדוברים.
אם התוכן שלכם נעשה בו שימוש בפורמט אודיו נתמך, תוכלו להוסיף אודיו מרחבי לאפליקציה החל מגרסה 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()
.
האפשרות הזו שימושית אם רוצים לשנות את בחירת הטראק במהלך ההפעלה באמצעות קריאות החזרה (callbacks) של המאזין. לדוגמה, כשמשתמש מחבר או מנתק את האוזניות מהמכשיר, קריאת החזרה (callback) של onSpatializerAvailableChanged
מציינת אם אפקט ה-Spatializer זמין לניתוב החדש של פלט האודיו. בשלב הזה, כדאי לעדכן את הלוגיקה של בחירת הטראקים בנגן כך שתתאים ליכולות החדשות של המכשיר. פרטים על אופן הבחירה של הטראקים ב-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 על ידי הגדרת פרמטרים לבחירת טראקים לפני ההפעלה או במהלכה. כברירת מחדל, 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);
דוגמה לשימוש ב-ExoPlayer מופיעה ב-
MediaCodecAudioRenderer.java
. כדי להשבית את הסטריאופוניה בעצמכם, ללא קשר להתאמה אישית של יצרן הציוד המקורי, תוכלו לעיין במאמר השבתה של אודיו מרחבי.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)