空間音訊

空間音訊可帶來身歷其境的聽覺饗宴, 是動作核心,讓內容聽起來更加逼真。聲音是 「空間化」創作多種喇叭效果,類似環場音效 設定,改為使用耳機。

以電影為例,汽車的聲音可能會在使用者後面 然後沿著這個距離前進在視訊通訊中,語音可以: 分隔點並放置在使用者周圍,可以更輕鬆地辨識講者。

如果內容使用系統支援的音訊格式,你可以在 App。

功能查詢

使用 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()敬上 指出能否使用指定屬性的音訊進行空間化 目前的輸出裝置轉送方式這個方法需要使用 AudioAttributesAudioFormat,兩者皆 。

AudioAttributes

AudioAttributes 物件 說明瞭 Pod 的用途 音訊串流 (例如遊戲音訊) 或標準媒體), 以及播放行為和內容類型

呼叫 canBeSpatialized() 時,使用相同的 設為 PlayerAudioAttributes 執行個體。舉例來說 您使用的是 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 引進聲道數限制。 如果使用 Media3 程式庫中的 ExoPlayer 模組 (套件名稱), 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()。 同樣地,您可以透過 Player.getTrackSelectionParameters()。 舉例來說,如要在播放期間選取立體聲音軌,請按照下列步驟操作:

Kotlin

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

Java

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

請注意,如果在播放期間變更音軌選擇參數,可能會導致 中斷播放。進一步瞭解如何調整玩家音軌 選取參數 音軌選取 一節所述的所有內容。

預設空間化行為

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_MEDIAUSAGE_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)