AVS Device SDK兼容服务接入示例

设备接入AVS Device SDK

点击链接下载avs-device-sdk到你的设备。AVS Device SDK目前支持Ubuntu Linux,Raspberry Pi(Raspbian Stretch),macOS,Windows 64-bit,Generic Linux平台。请确保拉取github的代码reset到commit 6a4f9f01361ea095e4fd64fb85de38452113fe1b版本,该版本是V1.6版本,以下示例和说明也都是基于这个版本。

git clone https://github.com/alexa/avs-device-sdk.git
git reset 6a4f9f01361ea095e4fd64fb85de38452113fe1b

按照文档中方法,将你的设备接入AVS Device SDK。启动AVS Device SDK示例程序,尝试用你的设备和Alexa进行交流,并确认设备得到Alexa的语音回复。在与Alexa交流过程中,需要保证设备所在的网络环境能够访问https://avs-alexa-na.amazon.com

接入AVS Device SDK的设备接入DuerOS

修改AVS SDK代码

修改AVS SDK代码,使其适配DuerOS。下面提供了批量修改和手动修改两种方式,开发者根据需要选择合适的方式。

批量修改

  • 下载avs_to_dcs.patch文件,在samples目录下运行git apply avs_to_dcs.patch完成批量修改代码。
    cd samples
    git apply avs_to_dcs.patch

手动修改

  • 在ACL/src/Transport/HTTP2Stream.cpp中的Header中添加Dueros-Device-Id和Transfer-Encoding信息,以适配DuerOS服务。(在195行后新增如下代码,共12行)
std::ostringstream dsnHeader;
dsnHeader << "Dueros-Device-Id: avstest123XXXXX"; //此处建议从外部读取设备唯一标识(如MAC)
if (!m_transfer.addHTTPHeader(dsnHeader.str())) {
    ACSDK_ERROR(LX("setCommonOptionsFailed")
                        .d("reason", "addHTTPHeaderFailed")
                        .sensitive("dsnHeader", dsnHeader.str()));
    return false;
}

std::ostringstream teHeader;
teHeader << "Transfer-Encoding: chunked";
if (!m_transfer.addHTTPHeader(teHeader.str())) {
    ACSDK_ERROR(LX("s   etCommonOptionsFailed")
                        .d("reason", "addHTTPHeaderFailed")
                        .sensitive("teHeader", teHeader.str()));
    return false;
}
  • 修改ACL/src/Transport/HTTP2Transport.cpp中的服务域名。(修改52行到59行中的如下代码,共4行)。
- const static std::string DEFAULT_AVS_ENDPOINT = "https://avs-alexa-na.amazon.com";
- const static std::string AVS_DOWNCHANNEL_URL_PATH_EXTENSION = "/v20160207/directives";
- const static std::string AVS_EVENT_URL_PATH_EXTENSION = "/v20160207/events";
- const static std::string AVS_PING_URL_PATH_EXTENSION = "/ping";
+ const static std::string DEFAULT_AVS_ENDPOINT = "https://dueros-h2.baidu.com";
+ const static std::string AVS_DOWNCHANNEL_URL_PATH_EXTENSION = "/dcs/avs-compatible-v20160207/directives";
+ const static std::string AVS_EVENT_URL_PATH_EXTENSION = "/dcs/avs-compatible-v20160207/events";
+ const static std::string AVS_PING_URL_PATH_EXTENSION = "/dcs/avs-compatible-v20160207/ping";
  • 在ACL/src/Transport/HTTP2Transport.cpp/handlePingResponse函数中,amazon的服务器返回码204,而DuerOS的服务器在相同情况下的返回码是200,为兼容这个情况,此处加上对返回码200的处理。(在667行进行如下修改,共1行)
- if (HTTPResponseCode::SUCCESS_NO_CONTENT != m_pingStream->getResponseCode())
+ if (HTTPResponseCode::SUCCESS_NO_CONTENT != m_pingStream->getResponseCode()
        && HTTPResponseCode::SUCCESS_OK != m_pingStream->getResponseCode())
  • 修改AVSCommon/Utils/src/LibcurlUtils/CurlEasyHandleWrapper.cpp的JSON MIME格式。(在41行进行如下修改,共1行)
- static std::string JSON_MIME_TYPE = "text/json";
+ static std::string JSON_MIME_TYPE = "application/json";
  • 修改AuthDelegate/src/AuthDelegate.cpp中的授权服务地址和请求格式。(在69、78行进行修改,共2行)

    - static const std::string DEFAULT_LWA_URL = "https://api.amazon.com/auth/o2/token";
    + static const std::string DEFAULT_LWA_URL = "https://openapi.baidu.com/oauth/2.0/token";
    - static const std::string POST_DATA_UP_TO_CLIENT_ID = "grant_type=refresh_token&client_id=";
    + static const std::string POST_DATA_UP_TO_CLIENT_ID = "grant_type=client_credentials&client_id=";

获取DuerOS授权

  1. 首先在设备控制平台申请开发者账号,并创建产品,记录产品的clientID和clientSecret信息。具体操作请参照控制台接入流程文档。

  2. 修改AlexaClientSDKConfig.json文件的clientSecret和clientId信息。
"authDelegate":{
    "clientSecret":"XXXXXX",
     "refreshToken":"",
     "clientId":"XXXXX"
},
  1. 执行命令AuthServer.py获取refreshToken。
    python AuthServer.py CONFIG_FILE_PATH/AlexaClientSDKConfig.json

注意:DuerOS授权有生命周期,如果出现如下错误,说明DuerOS授权已经到期,请重新获取refreshToken。

HttpPost:doPostSucceeded:code=400
AuthDelegate:handleLwaResponseFailed:error=expired_token,isUnrecoverable=false

示例中使用的Client Credentials授权方式。百度授权提供了多种授权方式,开发者可以根据需要选择合适的授权方式。

编译与运行

按照文档中的指导进行编译,并运行程序。当程序运行成功时,设备已经接入DuerOS,此时可以与设备进行交互,如询问“现在几点了”、“今天天气怎么样”、“讲个笑话吧”等,DuerOS会进行语音回复。

配置唤醒引擎(可选)

AVS Device SDK在V1.6版本中去除了唤醒相关的说明,如果需要加入唤醒模块,请参考下面的配置。

首先下载SnowBoy唤醒引擎,在cmake中增加如下编译选项。

-DKITTAI_KEY_WORD_DETECTOR=ON \
-DKITTAI_KEY_WORD_DETECTOR_LIB_PATH=${SOURCE_PATH}/snowboy/lib/ubuntu64/libsnowboy-detect.a \
-DKITTAI_KEY_WORD_DETECTOR_INCLUDE_DIR=${SOURCE_PATH}/snowboy/include

然后指定alexa.umdl、common.res两个资源文件路径。

最后编译、运行程序。

./SampleApp AlexaClientSDKConfig.json RESOURCE_FILE_PATH

当程序运行成功时,你可以使用唤醒词唤醒设备,并与设备交互。你可以询问“Alexa,现在几点了”。当然,唤醒词Alexa可以根据SnowBoy的说明进行更换。

注意:使用snowboy的唤醒引擎时,要求gcc的版本是4.8.5。