ميزة "الصوت المكاني" هي تجربة صوتية غامرة تضع المستخدمين في مكان واحد ركيزة أساسية، ما يجعل المحتوى يبدو أكثر واقعية. الصوت هو "محددة المكان" لإنشاء تأثير مكبّر صوت متعدد، يشبه الصوت المحيطي الإعداد، ولكن من خلال سماعات الرأس بدلاً من ذلك.
على سبيل المثال، في فيلم، قد يبدأ صوت السيارة خلف المستخدم، ويتحرك إلى الأمام، وتتبع المسافة. في دردشة الفيديو، يمكن أن تكون الأصوات منفصلة ووضعها حول المستخدم، مما يسهل التعرف على المتحدثين.
إذا كان المحتوى الخاص بك يستخدم تنسيقًا صوتيًا متوافقًا، يمكنك إضافة صوت مكاني إلى تطبيق يبدأ بالإصدار 13 من نظام التشغيل Android (المستوى 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()
وقد يفيد ذلك إذا كنت تريد ضبط اختيار المقطع الصوتي أثناء التشغيل.
باستخدام استدعاءات المستمع. على سبيل المثال، عندما يتصل مستخدم أو يقطع اتصاله
سماعة الرأس من الجهاز، فإن 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 المقطع الصوتي تلقائيًا التي تتطابق مع خصائص محدِّد الصوت المكاني في الجهاز بدلاً من ذلك، يمكنك تخصيص منطق اختيار مسار 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 السلوكيات التالية: التي يمكن أن يخصّصها المصنّعون الأصليون للأجهزة:
يتم تحديد المكان المناسب لعرض المحتوى المتعدّد القنوات فقط وليس المحتوى المجسَّم. في حال عدم استخدام 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)