开发者控制台

杜比集成指南(Fire TV)

杜比集成指南(Fire TV)

本文档为需要支持杜比音频内容的应用开发者提供了集成指南。

转至设置>显示和声音>音频>杜比数字输出,查看Amazon Fire TV中的杜比设置。

术语

请注意以下在本文档中使用的缩写:

  • EAC3: Dolby Digital Plus (DDP)
  • AC3: Dolby Digital (DD)

播放杜比音频的四种方法

您可以采用四种方法在应用中播放杜比(DD/DDP/Atmos)音频内容:

  1. ExoPlayer
  2. 使用自定义媒体播放器
  3. 其他支持的媒体播放器
  4. Android媒体播放器

选项1: 使用ExoPlayer

ExoPlayer是Google支持的开源播放器,支持播放杜比音频流。

亚马逊为Exoplayer开发了补丁,以启用或增强杜比音频内容在各种亚马逊设备上的播放。这些补丁在此处开源提供:exoplayer-amazon-port。(请注意,每个“amazon/rx.y.z”分支均映射到ExoPlayer版本x.y.z。)

方法2: 使用自定义媒体播放器

实现一个使用AudioManagerAudioTrackMediaCodec 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值中的一个。例如:

应用可以注册广播接收器以接收ACTION_HDMI_AUDIO_PLUG意图,并从该意图中获得EXTRA_ENCODINGSEXTRA_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);
            }
        }
    }
};

方法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_AC3ENCODING_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日