改善音訊播放品質
透過集合功能整理內容
你可以依據偏好儲存及分類內容。
當您嘗試使用 USB API 直接存取 USB 音訊週邊裝置時,
有助於解決 AI 問題這些問題可能包括:安全性問題、限制媒體
可透過其他應用程式播放,以及關閉鬧鐘、通知和鈴聲
USB 裝置。
如要改善音訊播放品質,請改為設定 Mixer 屬性。
使用
AudioMixerAttributes
API
您可以在 USB 上為應用程式設定偏好的混合器屬性。
您的應用程式播放內容符合編碼格式、頻道遮罩和範例
偏好混合器屬性的速率,播放會附加在音訊上
輸出串流,但該輸出串流設定了偏好的混合器屬性。
應用程式可以透過任何設定串流至硬體抽象化
以及傳輸至裝置上,前提是 USB 裝置必須支援
此外還會從 0 自動調整資源配置
您完全不必調整資源調度設定
AudioMixerAttributes
中允許的兩種混音器行為為 DEFAULT
和
BIT_PERFECT
。如果混合器行為為 DEFAULT
,代表音訊
來自不同來源的資料
當混合器行為為 BIT_PERFECT
時,系統不會調整音訊混音、音量調整,
或音訊處理效果資料傳送形式為
位於 HAL 部分
最後前往 USB 裝置
使用 BIT_PERFECT
可讓你直接串流播放內容
數位 (DSD) 管理 Android 裝置。
以下程式碼範例說明如何完成這項作業:
Kotlin
val EXPECTED_FORMAT: AudioFormat = AudioFormat.Builder()
.setEncoding(AudioFormat.ENCODING_PCM_24BIT_PACKED)
.setChannelMask(AudioFormat.CHANNEL_OUT_STEREO)
.setSampleRate(44100)
.build()
fun startPlayback() {
// Query all supported mixer attributes
val mixerAttributesList: List<AudioMixerAttributes?> =
mAudioManager.getSupportedMixerAttributes(usbDevice)
// Find the wanted mixer attributes
val mixerAttributes = mixerAttributesList.stream()
.filter { mixerAttr: AudioMixerAttributes? ->
EXPECTED_FORMAT.equals(
mixerAttr!!.format
)
}
.findAny()
.orElse(null)
// Register a listener to mixer attributes changed
val listener = MyPreferredMixerAttributesChangedListener()
mAudioManager.addOnPreferredMixerAttributesChangedListener(
Executors.newSingleThreadExecutor(), listener
)
// Currently, only media usage over USB devices will be allowed
val attr: AudioAttributes = AudioAttributes.Builder()
.setUsage(AudioAttributes.USAGE_MEDIA).build()
// Set preferred mixer attributes
mAudioManager.setPreferredMixerAttributes(
attr, usbDevice, mixerAttributes
)
// Start playback, note the playback and the audio format must
// match what is set when calling `setPreferredMixerAttriutes`
// API.
val audioTrack = AudioTrack.Builder()
.setAudioAttributes(attr)
.setAudioFormat(mixerAttributes!!.format)
.build()
// Clear all preferred mixer attributes related stuff when
// playback task is completed
mAudioManager.clearPreferredMixerAttributes(attr, usbDevice)
mAudioManager.removeOnPreferredMixerAttributesChangedListener(listener)
}
private class MyPreferredMixerAttributesChangedListener :
AudioManager.OnPreferredMixerAttributesChangedListener {
override fun onPreferredMixerAttributesChanged(
attributes: AudioAttributes,
device: AudioDeviceInfo,
mixerAttributes: AudioMixerAttributes?,
) {
// Do something when preferred mixer attributes changed
}
}
Java
final AudioFormat EXPECTED_FORMAT = new AudioFormat.Builder()
.setEncoding(AudioFormat.ENCODING_PCM_24BIT_PACKED)
.setChannelMask(AudioFormat.CHANNEL_OUT_STEREO)
.setSampleRate(44100)
.build();
void startPlayback() {
// Query all supported mixer attributes
List<AudioMixerAttributes> mixerAttributesList =
mAudioManager.getSupportedMixerAttributes(usbDevice);
// Find the wanted mixer attributes
AudioMixerAttributes mixerAttributes =
mixerAttributesList.stream()
.filter(mixerAttr -> EXPECTED_FORMAT.equals(mixerAttr.getFormat()))
.findAny()
.orElse(null);
// Register a listener to mixer attributes changed
MyPreferredMixerAttributesChangedListener listener =
new MyPreferredMixerAttributesChangedListener();
mAudioManager.addOnPreferredMixerAttributesChangedListener(
Executors.newSingleThreadExecutor(), listener);
// Currently, only media usage over USB devices will be allowed
AudioAttributes attr = new AudioAttributes.Builder()
.setUsage(AudioAttributes.USAGE_MEDIA).build();
// Set preferred mixer attributes
mAudioManager.setPreferredMixerAttributes(
attr, usbDevice, mixerAttributes);
// Start playback, note the playback and the audio format must
// match what is set when calling `setPreferredMixerAttriutes`
// API.
AudioTrack audioTrack = new AudioTrack.Builder()
.setAudioAttributes(attr)
.setAudioFormat(mixerAttributes.getFormat())
.build();
// Clear all preferred mixer attributes related stuff when
// playback task is completed
mAudioManager.clearPreferredMixerAttributes(attr, usbDevice);
mAudioManager.removeOnPreferredMixerAttributesChangedListener(
listener);
}
private class MyPreferredMixerAttributesChangedListener
implements AudioManager.OnPreferredMixerAttributesChangedListener {
@Override
public void onPreferredMixerAttributesChanged(
AudioAttributes attributes,
AudioDeviceInfo device,
AudioMixerAttributes mixerAttributes) {
// Do something when preferred mixer attributes changed
}
}
這個頁面中的內容和程式碼範例均受《內容授權》中的授權所規範。Java 與 OpenJDK 是 Oracle 和/或其關係企業的商標或註冊商標。
上次更新時間:2025-07-27 (世界標準時間)。
[[["容易理解","easyToUnderstand","thumb-up"],["確實解決了我的問題","solvedMyProblem","thumb-up"],["其他","otherUp","thumb-up"]],[["缺少我需要的資訊","missingTheInformationINeed","thumb-down"],["過於複雜/步驟過多","tooComplicatedTooManySteps","thumb-down"],["過時","outOfDate","thumb-down"],["翻譯問題","translationIssue","thumb-down"],["示例/程式碼問題","samplesCodeIssue","thumb-down"],["其他","otherDown","thumb-down"]],["上次更新時間:2025-07-27 (世界標準時間)。"],[],[],null,["# Improve audio playback\n\nWhen you try to directly access the USB audio peripheral using the USB APIs,\nproblems arise. These problems can include: security issues, limiting media\nplayback from other apps, and loss of alarms, notifications, and ringtones over\nUSB devices.\n\nTo improve audio playback, instead configure the mixer attributes.\n\n### Configure mixer attributes\n\nBy using the\n[`AudioMixerAttributes`](/reference/android/media/AudioMixerAttributes) APIs,\nyou can configure your app with preferred mixer attributes over USB.\n\nWhen your app playback matches the encoding format, channel mask, and sample\nrate of the preferred mixer attributes, the playback is attached to the audio\noutput stream whose mixer is configured with the preferred mixer attributes.\n\nYour app can stream at any configuration to the hardware abstraction\nlayer (HAL), and to the device, as long as the USB device supports the\nconfiguration.\n\nThe two allowed mixer behaviors in `AudioMixerAttributes` are `DEFAULT` and\n`BIT_PERFECT`. When the mixer behavior is `DEFAULT`, it indicates that audio\ndata from different sources is mixed.\n\nWhen the mixer behavior is `BIT_PERFECT`, no audio mixing, volume adjustment,\nor audio processed effect is applied to the playback. The data is sent as\nis to the HAL and finally down to the USB device.\n\nUsing `BIT_PERFECT` lets you direct stream\ndigital (DSD) over pulse code modulation (PCM) on Android-powered devices.\nThe following code sample shows how this can be accomplished: \n\n### Kotlin\n\n```kotlin\nval EXPECTED_FORMAT: AudioFormat = AudioFormat.Builder()\n .setEncoding(AudioFormat.ENCODING_PCM_24BIT_PACKED)\n .setChannelMask(AudioFormat.CHANNEL_OUT_STEREO)\n .setSampleRate(44100)\n .build()\n\nfun startPlayback() {\n // Query all supported mixer attributes\n val mixerAttributesList: List\u003cAudioMixerAttributes?\u003e =\n mAudioManager.getSupportedMixerAttributes(usbDevice)\n\n // Find the wanted mixer attributes\n val mixerAttributes = mixerAttributesList.stream()\n .filter { mixerAttr: AudioMixerAttributes? -\u003e\n EXPECTED_FORMAT.equals(\n mixerAttr!!.format\n )\n }\n .findAny()\n .orElse(null)\n\n // Register a listener to mixer attributes changed\n val listener = MyPreferredMixerAttributesChangedListener()\n mAudioManager.addOnPreferredMixerAttributesChangedListener(\n Executors.newSingleThreadExecutor(), listener\n )\n\n // Currently, only media usage over USB devices will be allowed\n val attr: AudioAttributes = AudioAttributes.Builder()\n .setUsage(AudioAttributes.USAGE_MEDIA).build()\n // Set preferred mixer attributes\n mAudioManager.setPreferredMixerAttributes(\n attr, usbDevice, mixerAttributes\n )\n\n // Start playback, note the playback and the audio format must\n // match what is set when calling `setPreferredMixerAttriutes`\n // API.\n val audioTrack = AudioTrack.Builder()\n .setAudioAttributes(attr)\n .setAudioFormat(mixerAttributes!!.format)\n .build()\n\n // Clear all preferred mixer attributes related stuff when\n // playback task is completed\n mAudioManager.clearPreferredMixerAttributes(attr, usbDevice)\n mAudioManager.removeOnPreferredMixerAttributesChangedListener(listener)\n}\n\nprivate class MyPreferredMixerAttributesChangedListener :\n AudioManager.OnPreferredMixerAttributesChangedListener {\n override fun onPreferredMixerAttributesChanged(\n attributes: AudioAttributes,\n device: AudioDeviceInfo,\n mixerAttributes: AudioMixerAttributes?,\n ) {\n // Do something when preferred mixer attributes changed\n }\n}\n```\n\n### Java\n\n```java\nfinal AudioFormat EXPECTED_FORMAT = new AudioFormat.Builder()\n .setEncoding(AudioFormat.ENCODING_PCM_24BIT_PACKED)\n .setChannelMask(AudioFormat.CHANNEL_OUT_STEREO)\n .setSampleRate(44100)\n .build();\n\nvoid startPlayback() {\n // Query all supported mixer attributes\n List\u003cAudioMixerAttributes\u003e mixerAttributesList =\n mAudioManager.getSupportedMixerAttributes(usbDevice);\n\n // Find the wanted mixer attributes\n AudioMixerAttributes mixerAttributes =\n mixerAttributesList.stream()\n .filter(mixerAttr -\u003e EXPECTED_FORMAT.equals(mixerAttr.getFormat()))\n .findAny()\n .orElse(null);\n\n // Register a listener to mixer attributes changed\n MyPreferredMixerAttributesChangedListener listener =\n new MyPreferredMixerAttributesChangedListener();\n mAudioManager.addOnPreferredMixerAttributesChangedListener(\n Executors.newSingleThreadExecutor(), listener);\n\n // Currently, only media usage over USB devices will be allowed\n AudioAttributes attr = new AudioAttributes.Builder()\n .setUsage(AudioAttributes.USAGE_MEDIA).build();\n // Set preferred mixer attributes\n mAudioManager.setPreferredMixerAttributes(\n attr, usbDevice, mixerAttributes);\n\n // Start playback, note the playback and the audio format must\n // match what is set when calling `setPreferredMixerAttriutes`\n // API.\n AudioTrack audioTrack = new AudioTrack.Builder()\n .setAudioAttributes(attr)\n .setAudioFormat(mixerAttributes.getFormat())\n .build();\n\n // Clear all preferred mixer attributes related stuff when\n // playback task is completed\n mAudioManager.clearPreferredMixerAttributes(attr, usbDevice);\n mAudioManager.removeOnPreferredMixerAttributesChangedListener(\n listener);\n}\n\nprivate class MyPreferredMixerAttributesChangedListener\n implements AudioManager.OnPreferredMixerAttributesChangedListener {\n @Override\n public void onPreferredMixerAttributesChanged(\n AudioAttributes attributes,\n AudioDeviceInfo device,\n AudioMixerAttributes mixerAttributes) {\n // Do something when preferred mixer attributes changed\n }\n}\n```"]]