阿里云声纹识别Android版SDK用户指南与参考

1.本文档是阿里云声纹Android 版SDK的用户指南与参考文件,介绍了声纹(说话人识别)功能的类与函数的基本使用。
 
 
 
2.  下载
 
华南1地域Android版SDK下载点击Voiceprint_Android_SDK_v3.1.2
 
新加坡地域Android版SDK下载点击Voiceprint_sg_Android_SDK_v3.1.2

3.  应用场景与业务流程
 
(1)  概述
 
阿里云声纹SDK提供的主要功能有声纹注册与声纹验证。在允许用户进行声纹注册之前,应该先用其他方式验证用户的身份(如用户名/密码登录、手机验证码登录等)。用户完成声纹注册后,将来需要验证用户身份时,即可使用声纹验证代替其他的身份验证方法,使验证更加便利。如果用户的声纹发生了改变,可以进行修改注册。
 
注册声纹时,系统学习用户的声纹,并将声纹与用户身份进行关联。声纹注册成功后,用户才能进行声纹验证,通过比对说话人的声纹是否与注册用户相关联的声纹相符,从而验证说话人的身份。
 
文本相关
 
在注册时,云端先后提供三组随机数字串,用户分别读出此三组数字串提交语音进行注册。注册成功后,云端提供一组数字串,用户读出这个数字串进行验证。
 
文本无关
 
用户说出长语音(不短于20秒)进行注册,注册成功后,说出长语音(不短于10秒)进行验证,语音内容不限。
 
(2)  使用说明    
 
1) 针对一组随机数字串进行录音的流程
 
a)  在界面上显示本组随机数字;
 
b)  用户发出开始录音指令(如:按下“开始录音”按钮;按住“录音”按钮等),SDK开始录音;
 
c)  用户读出随机数字;
 
d)  用户发出停止录音指令(如:按下“停止录音”按钮;松开“录音”按钮等),或者SDK根据条件自动停止录音(录音超时等),SDK停止录音;
 
e)  SDK判断录音是否符合要求:
 
•    如符合要求,则录音成功;
 
•    如不符合要求,则回到b),重新录制本段语音。
 
2) 声纹注册流程
 
a)  SDK从云端获取1组随机数字;
 
b)  针对该组随机数字进行录音(见1)针对一组随机数字串进行录音的流程);
 
c)  SDK向云端发起注册请求;
 
d)  SDK返回当前步骤注册的结果;
 
e)  再从a)开始重复2次  ,一共需要3次提交数据,才能注册成功。
 
3)声纹验证流程
 
a)  SDK从云端获取1组随机数字;
 
b)  针对随机数字进行录音(见1)针对一组随机数字串进行录音的流程);
 
c)  SDK向云端发起验证请求;
 
d)  SDK返回验证通过或不通过的结果。

4.  预备工作
 
(1)  导入SDK
 
首先将sdk.aar包复制到lib目录下,然后配置当前module 的 build.gradle文件,在当前module 的 build.gradle文件中加入以下内容:
 
repositories{
    flatDir {
        dirs 'libs'
    }
}
 
dependencies {
 
...
    compile(name: 'sdk', ext: 'aar')//name的值必须和aar的文件名一致(可自定义名称)
 
...
}

当前SDK的minSdkVersion 为android 14 ,最低支持到Android 4.0
 
(2)  配置工程权限
 
请在应用中添加录音 、网络、读写存储(可选)、获取网络信息的权限。
 
Android 6.0以上需要运行时动态申请录音权限,如需保存相关录音文件需要申请读写存储权限
 
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
 
<uses-permission android:name="android.permission.INTERNET"/>
 
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
 
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>////可选 如需保存录音文件,才需要此权限
 
Android6.0以下录音权限Manifest无须申请,但深度定制系统(小米 MIUI 、魅族 Flyme、华为EMUI等)对原生安卓有修改,在录音和噪音检测回调listener的onRecordError() onError() 回调中,根据相关返回Code判断是否有录音权限。
 
(3)  初始化
 
在使用声纹SDK的服务之前,需要进行初始化,创建语音配置对象。将初始化代码放在程序Application入口处(Application的onCreate方法:
 
SpeechRecognizer.getInstance().init(this);//初始化 传入Application context
SpeechRecognizer.getInstance().setAppId("应用的appid");//设置当前应用的APP ID
 
SpeechRecognizer.getInstance().setAppScene("应用的scene");//设置当前应用的SCENE
 
SpeechRecognizer.getInstance().setLogEnable(true);//设置是否打印日志
 
SpeechRecognizer.getInstance().setAppIdKey("应用的appIdKey");//设置应用的APP ID KEY
 
SpeechRecognizer.getInstance().setPaAgAppId("阿里云平台ID");//设置应用的PA-AG-APP SECRET
 
SpeechRecognizer.getInstance().setPaAgAccessKeyId("AccessKeyId");//设置账号密钥的 Access Key Id
 
SpeechRecognizer.getInstance().setPaAgSecretAccessKey("SecretAccessKey");//设置账号密钥的 Secret Access Key
 
SpeechRecognizer.getInstance().setAppType(SdkConst.AppType.TEXT_DEPENDENT);//设置应用的类型 文本相关为:SdkConst.AppType.TEXT_DEPENDENT 文本无关为:SdkConst.AppType.TEXT_INDEPENDENT

AppId参数应设置为分配给该App的唯一标识符。
 
如果调试过程中需要打印日志,则可以设置
 
SpeechRecognizer.getInstance().setLogEnable(true);
 
//true 为打印log , false 不打印log

5.  声纹功能使用说明
 
(1)  参数配置
 
产生一个speechRecognizer的instance,并设置相关参数:
 
SpeechRecognizer  speechRecognizer = SpeechRecognizer.getInstance();
 
speechRecognizer.setRecordFilePath(path);//如果需本地保存设置保存路径
 
speechRecognizer.setStageListener(stageListener);//设置相关监听
speechRecognizer.setMinRecordTime(2000);// 设置最短录音时间
speechRecognizer.setMaxRecordTime(6000);// 设置最长录音时间 默认为5s
 
其中stageListener为录音时的相关回调方法,通过该回调,可以获取录音时的音量大小,保存文件路径等相关状态。特别注意 如果有调用噪音检测的功能,噪音检测会把之前设置的speechRecognizer参数覆盖,建议录音的相关参数在调用speechRecognizer.start()之前设置,也就是在录音的时候再去设置参数
 
(2)  文本相关声纹注册
 
首先获取注册随机数字串(1组)
 
speechRecognizer.getSpeechText(currentUserId, SdkConst.SpeechType.TYPE_REGISTER,  resultListener);

参数:
 
currentUserId 为当前注册用户的用户名;
 
SdkConst.SpeechType.TYPE_REGISTER 表示获取注册用的随机数字串;
 
resultListener为当前网络请求的回调。
 
示例:
 
speechRecognizer.getSpeechText(currentUserName, SdkConst.SpeechType.TYPE_REGISTER, new ResultListener() {
    @Override
    public void onResult(String result) {
        try {
            JSONObject jsonObject = new JSONObject(result);
            JSONObject data = jsonObject.getJSONObject("data");
            JSONObject returnData = data.getJSONObject("returnData");
 
            currentSpeechText = returnData.getString("speechText");
            //speechText为返回的随机数字
            speechKey = returnData.getString("speechKey");
            //发送注册请求时需要的speechKey
            numberText.setText(currentSpeechText);
 
        } catch (JSONException e) {
            e.printStackTrace();
        }
 
    }
 
    @Override
    public void onNetworkUnavailable() {
 
    }
 
    @Override
    public void onFailed(String error) {
 
    }
});
 
 
 
onResult返回的JSON数据格式如下:
 
{
 
    "data": {
 
        "returnCode": "200",
 
        "returnMsg": "交易成功",
 
        "returnData": {
 
            "speechText": "62748390",
 
            "speechKey": "a006a3eec0bd41929f9c2807e3798cd7"
 
        },
 
        "returnFlag": "SUCC",
 
        "serialNum": "FRS15008600621774b8gqtY5"
 
    },
 
    "responseCode": "00",
 
    "responseMsg": "操作成功"
 
}
 
其中:
 
speechText为返回的注册随机数字;
 
speechKey为本次注册操作的标识符,注册时需要传回给服务器。

成功获取随机数字之后即可开始录音,需要录制3段,每段对应一个随机数字,每段录音结束后需要立即提交注册,然后再获取一个随机数字,再提交注册。应用界面应该向用户显示第一组随机数字串,要求用户读出数字串,同时进行录音:
 
speechRecognizer.start();//开始录音
 
手动结束录音:
 
speechRecognizer.stop();//结束录音
 
如果录音过程中静音超过了(1)参数配置中设置的长度,则自动结束录音。录音结束时会触发stageListener的onStopRecording回调方法。如果录音成功,通过stageListener 的 onRecordBase64String(String base64) 的方法可以获得base64编码的音频数据。
 
重复以上步骤,每次显示一个随机数字串并录音,录音成功后,将base64编码过的音频数据String传入register方法,向服务端发起注册请求:
 
speechRecognizer.register(currentUserId, SdkConst.RegisterType.TYPE_REGISTER, currentSpeechText,speechKey,base64, currentStep,resultListener);
 
参数:
 
 currentUserId 为当前注册用户的用户名;
 
 SdkConst.RegisterType.TYPE_REGISTER 代表进行注册操作;
 
currentSpeechText 为之前获取的随机数字串;
 
speechKey 为之前获取的speechKey;
 
base64为该条录音的音频数据
 
currentStep表示当前的步骤 从第1开始 到第3结束
 
resultListener为网络请求数据的回调,结构与获取随机数字时相同。
 
返回的JSON数据格式为:
 
{
 
    "data": {
 
        "returnCode": "200",
 
        "returnMsg": "本次注册成功,请继续完成后续注册!",
 
        "returnData": {
 
            "code": "2000",
 
            "msg": "本次注册成功,请继续完成后续注册!"
 
        },
 
        "returnFlag": "FAIL",
 
        "serialNum": "FRS150174256361886gUEdts"
 
    },
 
    "responseCode": "00",
 
    "responseMsg": "操作成功"
 
}
 
其中data.returnData.code字段代表注册操作的状态:
 
Code码
 
RegisterResult
 
600
 
注册成功
 
601
 
注册失败
 
801
 
SpeechText已超时,请重新获取
 
1000
 
注册语音非同一人
 
1001
 
语音与文字不匹配
 
9999
 
系统异常
 
201
 
用户已注册
 
204
 
注册修改失败
 
302
 
参数异常
 
2000
 
本次注册成功,请继续完成后续注册!
 
803
 
注册or验证文本变更需通知声纹平台及时更新!
 
804
 
注册流程时间过长,需从第一条开始重新注册
 
805
 
注册过程中,上一条语音尚未注册成功

(3)  文本相关声纹验证
 
首先获取随机数字串(1组):
 
speechRecognizer.getSpeechText(currentUserId, SdkConst.SpeechType.TYPE_VERIFY, resultListener);
 
参数:
 
SdkConst.SpeechType.TYPE_VERIFY 代表获取验证用的随机数字串;
 
其他参数同(2)文本相关声纹注册中获取注册随机数字串。
 
成功获取随机数字串后即可开始录音,只需录制一段,录音方式同(2)文本相关声纹注册。
 
录音完成后,向服务器发起验证请求:
 
speechRecognizer.verify(currentUserId, currentSpeechText,speechKey, verifyString, resultListener);

参数:
 
currentUserId为当前验证用户的用户名;
 
currentSpeechText为之前获取的随机数字;
 
speechKey 为之前获取的speechKey;
 
verifyString为base64编码的音频数据;
 
resultListener为验证结果回调。
 
服务器返回的json格式为:
 
{
 
    "data": {
 
        "returnCode": "200",
 
        "returnMsg": "验证成功",
 
        "returnData": {
 
            "code": "603",
 
            "msg": "验证成功"
 
        },
 
        "returnFlag": "SUCC",
 
        "serialNum": "FRS1500435721699wdCSpp0R"
 
    },
 
    "responseCode": "00",
 
    "responseMsg": "操作成功"
 
}
 
其中data.returnData.code字段代表验证操作的状态:
 
Code码
 
VerifyResult
 
603
 
验证成功
 
604
 
验证失败
 
801
 
SpeechText已超时,请重新获取
 
1001
 
语音与文字不匹配
 
9999
 
系统异常
 
203
 
用户尚未注册
 
202
 
用户存在,状态异常
 
302
 
参数异常
 
803
 
注册or验证文本变更需通知声纹平台及时更新!

(4)  判断用户是否已经注册
 
可以使用以下的方法向服务器查询某个用户是否已经注册:
 
speechRecognizer.isUserRegistered(currentUserId, resultListener)
 
参数:
 
currentUserId为需要查询的用户名;
 
resultListener为结果回调。
 
服务器返回的JSON数据格式为:
 
{
 
    "data": {
 
        "returnCode": "200",
 
        "returnMsg": "用户已注册",
 
        "returnData": {
 
            "code": "201",
 
            "msg": "用户已注册"
 
        },
 
        "returnFlag": "SUCC",
 
        "serialNum": "FRS1500862507829T34CDLSt"
 
    },
 
    "responseCode": "00",
 
    "responseMsg": "操作成功"
 
}
 
其中data.returnData.code字段代表查询结果:
 
Code码
 
RegisterResult
 
201
 
用户已注册
 
203
 
用户未注册
 
601
 
用户注册过,但是并未成功
 
 
 
(5)  噪音检测
 
噪音检测用于在录音之前确定环境是否足够安静。若噪音检测不通过,则环境不适合进行声纹注册或验证操作。
 
开始噪音检测后无需调用方法停止,4s之后会自动停止,特别注意 如果有调用噪音检测的功能,噪音检测会把之前设置的speechRecognizer参数覆盖,建议录音的相关参数在调用speechRecognizer.start()之前设置,也就是在录音的时候再去设置参数
 
speechRecognizer. startNoiseDetection(noiseListener);
 
参数:noiseListener 为噪音检测的回调,其中包含以下方法:
 
void currentDb(double db):当前的噪音分贝大小;
 
void isNoisy(boolean isNoisy):环境是否嘈杂;
 
void onStart():噪音检测开始;
 
void onStop():噪音检测结束。
 
(6)  文本无关声纹注册
 
说一段长语音(不短于20秒)进行声纹注册
 
speechRecognizer.registerLong(currentUserId, registerType, currentBase64, resultListener
 
参数:
 
currentUserId为需要注册的用户名;

registerType 为注册类型  SdkConst.RegisterType.TYPE_REGISTER表示注册,SdkConst.RegisterType.TYPE_LONG_MODIFY表示重新注册

resultListener为结果回调 返回的json格式同(2)文本相关声纹注册

currentBase64  为验证时一整段录音base64编码的音频数据

(7)  文本无关声纹验证

说一段长语音(不短于10秒)进行声纹验证
 
speechRecognizer.verifyLong(currentUserId, verifyString,resultListener);

参数:
 
currentUserId为需要验证的用户名

verifyString  为验证时一整段录音base64编码的音频数据

resultListener 为验证结果的回调返回的json格式同(3)文本相关声纹验证