杜比集成指南(Fire TV)
本文档为需要支持杜比音频内容的应用开发者提供了集成指南。
转至设置>显示和声音>音频>杜比数字输出,查看Amazon Fire TV中的杜比设置。
- 术语
- 播放杜比音频的四种方法
- 选项1: 使用ExoPlayer
- 方法2: 使用自定义媒体播放器
- 选项3: 使用其他支持的媒体播放器
- 方法4: 使用Android媒体播放器
- 处理非杜比终端节点和专属聆听模式
术语
请注意以下在本文档中使用的缩写:
- EAC3: Dolby Digital Plus (DDP)
- AC3: Dolby Digital (DD)
播放杜比音频的四种方法
您可以采用四种方法在应用中播放杜比(DD/DDP/Atmos)音频内容:
选项1: 使用ExoPlayer
ExoPlayer是Google支持的开源播放器,支持播放杜比音频流。
亚马逊为Exoplayer开发了补丁,以启用或增强杜比音频内容在各种亚马逊设备上的播放。这些补丁在此处开源提供:exoplayer-amazon-port。(请注意,每个“amazon/rx.y.z”分支均映射到ExoPlayer版本x.y.z。)
方法2: 使用自定义媒体播放器
实现一个使用AudioManager、AudioTrack和MediaCodec API的自定义播放器。本节说明了如何使用AudioManager、AudioTrack和MediaCodec API来播放Android推荐的杜比音频内容。
检测杜比支持
要采用以下方法更轻松地测试音频功能,请使用测试应用。
方法1: EXTRA_ENCODINGS
Android L(API级别21)增强了AudioManager中的ACTION_HDMI_AUDIO_PLUG意图,以报告HDMI接收器设备的功能。将HDMI插入或拔出设备时,都会广播此意图。
此意图还规定,应用须通过意图中提供的EXTRA_ENCODINGS来检测所连接终端节点(AVR或TV)的功能。可能值为ENCODING_XXXX值中的一个。例如:
- ENCODING_PCM_16BIT
- ENCODING_AC3
- ENCODING_E_AC3
- ENCODING_E_AC3_JOC(在API级别28中添加 - Fire OS 7及更高版本)
应用可以注册广播接收器以接收ACTION_HDMI_AUDIO_PLUG意图,并从该意图中获得EXTRA_ENCODINGS和EXTRA_AUDIO_PLUG_STATE等信息。
BroadcastReceiver mAudioHDMIPlugReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (intent == null) {
if (intent.getIntExtra(AudioManager.EXTRA_AUDIO_PLUG_STATE, 0) == 0) {
// 处理HDMI拔出状态
} else {
// 处理EXTRA_ENCODINGS
int[] extraEncodings = intent.getIntArrayExtra(AudioManager.EXTRA_ENCODINGS);
}
}
}
};
- 如果HDMI已拔出,则返回所有设备支持的最少音频功能。通常应该为AudioFormat.ENCODING_PCM_16BIT。请参阅来自Exoplayer的官方示例。
- 如果HDMI接收器设备支持Dolby Atmos,则在EXTRA_ENCODINGS列表中会存在AudioFormat.ENCODING_E_AC3_JOC enum(18)。
方法2:audio_platform_capabilities全局设置
audio_platform_capabilities全局设置是亚马逊设计的一种方法,用于查询Fire OS中的接收器功能。AudioService启动后,audio_platform_capabilities会被初始化,以JSON格式存储在全局设置中,并在接收器功能更改后更新。
开发者可在全局设置中查询audio_platform_capabilities,以便通过执行以下操作获得当前的音频终端节点功能:
String audioCapJson = Settings.Global.getString(mContext.getContentResolver(), "audio_platform_capabilities");
要主动观察功能变化,开发者可以使用ContentObserver,如下所示:
ContentResolver mContentResolver = mContext.getContentResolver();
Uri audioPlatformUri = Settings.Global.getUriFor("audio_platform_capabilities");
ContentObserver mAudioPlatformJsonObserver = new ContentObserver(new Handler()) {
@Override
public void onChange(boolean selfChange) {
String audioCapJson = Settings.Global.getString(mContentResolver, "audio_platform_capabilities");
Log.d(TAG, "audio_platform_capabilities=" + audioCapJson);
}
};
mContentResolver.registerContentObserver(audioPlatformUri, false, mAudioPlatformJsonObserver);
下面是一个audio_platform_capabilities的JSON字符串示例,适用于支持Dolby Atmos的接收器。
{
"audiocaps": {
"pcm" : {
"mixing" : true
},
"ddplus" : {
"mixing" : true
},
"atmos" : {
"enabled" : true
}
}
}
开发者可以通过以下操作查询Dolby Atmos功能的audiocaps.atmos.enabled:
String audioCapJsonStr = Settings.Global.getString(mContext.getContentResolver(), "audio_platform_capabilities");
JSONObject mAudioCapJson = new JSONObject(audioCapJson).getJSONObject("audiocaps");
JSONObject mAtmosCapJson = mAudioCapJson.getJSONObject("atmos");
boolean atmosEnabled = mAtmosCapJson.getBoolean("enabled");
通过查看audio_platform_capabilities全局设置,开发者无需区分产品、Fire OS版本和不同的音频终端节点。未来,我们将在audio_platform_capabilities设置中提供更多信息,例如支持的采样率。
方法3: AudioDeviceInfo
Android API级别23添加了一个也可以查询接收器功能的getEncodings API。它的形式如下所示:
AudioManager audio = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
AudioDeviceInfo[] devices = audio.getDevices(audio.GET_DEVICES_OUTPUTS);
for (AudioDeviceInfo device : devices) {
Log.i(TAG, "Supported Encodings" + Arrays.toString(device.getEncodings()));
}
例如,如果看一下TYPE_HDMI设备,则输出编码列表可能为:
[2, 4, 5, 6, 7, 8, 13]
映射来自Android开源项目(AOSP)的编码名称:[PCM 16 Bit, Dolby Digital, Dolby Digital Plus, Dolby Atmos in Dolby Digital Plus, DTS, DTS HD, IEC61937]
建议
Fire OS 7设备
使用方法1: EXTRA_ENCODINGS来检测所有功能变化,包括Dolby Atmos。
Fire OS 6设备
使用方法1: EXTRA_ENCODINGS来检测功能变化。在流式传输Dolby Atmos内容时,使用方法2:audio_platform_capabilities全局设置来检查Atmos功能。
测试应用
此音频测试应用可以帮助您根据上面列出的检测方法查找所有信息。
AudioTrack概述
在AudioFormat中,Android L增加了对ENCODING_AC3和ENCODING_E_AC3编码格式的支持。Android P增加了对用于Atmos的ENCODING_E_AC3_JOC的支持。如果AudioTrack配置有杜比编码格式,并且所连接的终端节点支持该编码格式,则AudioTrack接受杜比原始位流作为输入,并在使用IEC61937标准封包后将位流传递到终端节点。AudioTrack仅支持明文(未加密)输入位流。
此外,如果所连接的终端节点不支持该编码格式,则AudioTrack创建失败。
如果连接的终端节点仅支持DD,则某些平台将DDP位流转码为DD。
MediaCodec概述
AudioTrack不支持DRM密钥加密的杜比音频内容。因此,对于加密的杜比音频位流,必须使用MediaCodec API来解密位流,然后将解密的位流传递给AudioTrack。
Android通过名为“OMX.google.raw.dec”的MediaCodec接口提供了一个通用的原始音频解码器,它本质上是一个无操作(no-op)复制解码器。如果位流被加密,则使用MediaCrypto API来解密并输出位流。应用必须使用此解码器来解密加密的杜比位流,并将明文杜比位流传递给AudioTrack。
或者,平台可以通过MediaCodec接口来支持杜比解码器。该解码器将杜比音频位流解码为PCM。应用可以使用findDecoderForFormat来检测是否存在支持杜比MIME类型的解码器。
选项3: 使用其他支持的媒体播放器
您可以使用Amazon Fire TV支持的其他媒体播放器(如VisualOn或NexPlayer)播放杜比音频内容和DRM内容。请参阅媒体播放器了解更多详情。
方法4: 使用Android媒体播放器
您的应用可以使用Android MediaPlayer播放杜比内容。
注意: Android MediaPlayer只能输出立体声PCM内容,不支持直通播放。
处理非杜比终端节点和专属聆听模式
本节介绍了在连接到非杜比终端节点和专属聆听(蓝牙)时,在Amazon Fire TV系列设备上播放杜比音频内容的建议和最佳实践。遵循这些准则有助于为您带来杜比音频内容播放的最佳用户体验。
如前所述,Android L在AudioManager中引入了一个名为ACTION_HDMI_AUDIO_PLUG意图的新API。此意图允许应用检测所连接的终端节点(AVR或TV)的功能。此检测可用于支持杜比音频内容在各种HDMI相关场景中播放。
当连接到蓝牙耳机等非HDMI接收器设备时,建议重新创建AudioTrack并切换到非杜比音频内容,例如AAC。与杜比音频内容相比,此选项的优点是可以减少带宽使用。
但是,如果应用无法选择替代的非杜比音频内容并选择继续播放杜比音频,则应用应使用MediaCodec将编解码器从直通(OMX.google.raw.dec)切换到适当的杜比编解码器(OMX.dolby.ac3.decoder或OMX.dolby.eac3.decoder)。
MediaCodec解码器可解码杜比位流,下混合成立体声PCM。
再次创建ENCODING_PCM_16BIT
音频格式的AudioTrack之后,才能渲染PCM数据。
由于所有平台中的杜比解码器都将多声道内容向下混音为立体声,因此在终端节点不支持DD或DDP时,选择杜比音频内容并无真正的优势。
- 问:对于Fire TV Edition,应用如何检测所连接终端节点的功能(如上面提到的ACTION_HDMI_AUDIO_PLUG)?
- 默认情况下,Fire TV Edition的扬声器仅支持立体声输出,因此应用默认可以播放立体声内容。但是,当在电视扬声器上播放时,支持并建议使用杜比直通。
当电视通过光学音频输出或HDMI连接到条形音箱或AVR(基于用户在Fire TV Edition上设置的杜比系统设置)时,应用可以选择以杜比音频格式播放环绕声。 -
为此,应用需要读取全局设置
external_surround_sound_enabled
,以确定是否支持环绕声(AC3和EAC3)。如果值为1
,则支持杜比音频。如果值为0
,则应用可以进一步使用其他方法(例如使用ACTION_HDMI_AUDIO_PLUG来确定是否支持环绕声)。请参考此Exoplayer补丁(添加了对光学输出的环绕声检测的支持)。 - 问:当所连接的终端节点支持DD但不支持DDP时,应选择哪个音频流进行播放?
- 大多数亚马逊设备都能够自动将DDP内容转码为DD,并将内容传递到纯DD接收器设备。
该情况假定亚马逊设备也可报告对DD的支持。如果不支持DD(如上文所述),则需要选择替代的非杜比音频轨道,或者DDP内容需要解码为PCM。
Last updated: 2022年2月22日