# 语音听写 Java SDK 文档

# 1、简介

语音听写,是基于自然语言处理,将自然语言音频转换为文本输出的技术。语音听写技术与语法识别技术的不同在于,语音听写不需要基于某个具体的语法文件,其识别范围是整个语种内的词条。在听写时,应用还可以上传个性化的词表,如联系人列表等,提高列表中词语的匹配率(见后面章节)。

自2019/8/16起,高阶功能-动态修正免费开放!可到这里 动态修正效果 在线体验
使用方法详见 动态修正

语音听写详细的接口介绍及说明请参考: MSC Java API 文档, 在集成过程中如有疑问,可登录语音云开发者论坛,查找答案或与其他开发者交流。

*** 小语种 ***:暂不支持小语种!

# 2、SDK集成指南

# 2.1 Demo运行步骤

1.在控制台下载对应sdk(如何下载见下方常见问题)。

2.配置JDK环境 编者采用的版本是jdk1.8,读者可以从Sun官网 http://java.sun.com/javase/downloads/index.jsp 下载所需的版本;

3.安装Eclipse Java IDE 编者采用的版本是Ecilpse Java IDE,读者可以从官网 http://www.eclipse.org/downloads/packages/release/ganymede/sr2 下载所需的版本

4.直接打开File-->import Projects--->选择已下载java sdk内的sample/MscDemo。

5.运行Mainview即可,其中IatSpeechView为语音听写能力代码示例。

# 2.2 项目集成步骤

# 2.2.1 SDK包说明

《JAVA SDK目录结构一览》

  • bin:

    • 相关类文件
  • lib:

    • msc相关jar包
  • msc:

    • 日志存放文件夹
  • res:

    • UI图片存放文件夹
  • src:

    • IatSpeechView.java(语音听写示例代码)
  • libmsc32库文件

  • libmsc64库文件

  • msc32.dll

  • msc64.dll

# 2.2.2 SDK导入

  1. 在Eclipse中建立你的Java工程。
  2. 将开发工具包中lib目录下的Msc.jar复制到新建工程的lib目录中(如下图所示)。

  1. 在Eclipse中选中工程,通过工具栏Project->Properties->Java Build Path->Libraries->Add JARS或ADD External JARS引入Msc.jar(如下图所示)。

  1. 将SDK.\lib目录下库文件拷贝到工程根目录(如下图所示)。

  1. 在你需要使用MSC服务的文件中导入相应的类,如。

    import com.iflytek.cloud.speech.SpeechRecognizer;
    
    

# 2.2.3 初始化方式

创建用户语音配置对象后才可以使用语音服务,建议在程序入口处调用。

关于初始化时指定库名,或报加载库失败的解决办法,请参考《MSC Reference Manual》中,关于SpeechUtility类,以及SpeechConstant类的说明。

// 将“XXXXXXXX”替换成您申请的APPID
SpeechUtility.createUtility( SpeechConstant.APPID +"=XXXXXXXX ");

# 2.3 参数与说明

# 2.3.1 使用麦克风当音听写示例

private RecognizerListener recognizerListener = new RecognizerListener() {
		@Override
		public void onBeginOfSpeech() {
			DebugLog.Log( "onBeginOfSpeech enter" );
			((JLabel) jbtnRecognizer.getComponent(0)).setText("听写中...");
			jbtnRecognizer.setEnabled(false);
		}
		@Override
		public void onEndOfSpeech() {
			DebugLog.Log( "onEndOfSpeech enter" );
		}
		/**
		 * 获取听写结果. 获取RecognizerResult类型的识别结果,并对结果进行累加,显示到Area里
		 */
		@Override
		public void onResult(RecognizerResult results, boolean islast) {
			DebugLog.Log( "onResult enter" );			
			//如果要解析json结果,请考本项目示例的 com.iflytek.util.JsonParser类
//			String text = JsonParser.parseIatResult(results.getResultString());
			String text = results.getResultString();
			resultArea.append(text);
			text = resultArea.getText();
			if( null!=text ){
				int n = text.length() / TEXT_COUNT + 1;
				int fontSize = Math.max( 10, DEF_FONT_SIZE - 2*n );
				DebugLog.Log( "onResult new font size="+fontSize );
				int style = n>1 ? Font.PLAIN : DEF_FONT_SIZE;
				Font newFont = new Font( DEF_FONT_NAME, style, fontSize );
				resultArea.setFont( newFont );
			}
			if( islast ){
				iatSpeechInitUI();
			}
		}
		@Override
		public void onVolumeChanged(int volume) {
			DebugLog.Log( "onVolumeChanged enter" );
			if (volume == 0)
				volume = 1;
			else if (volume >= 6)
				volume = 6;
			labelWav.setIcon(new ImageIcon("res/mic_0" + volume + ".png"));
		}

		@Override
		public void onError(SpeechError error) {
			DebugLog.Log( "onError enter" );
			if (null != error){
				DebugLog.Log("onError Code:" + error.getErrorCode());
				resultArea.setText( error.getErrorDescription(true) );
				iatSpeechInitUI();
			}
		}
		@Override
		public void onEvent(int eventType, int arg1, int agr2, String msg) {
			DebugLog.Log( "onEvent enter" );
			//以下代码用于调试,如果出现问题可以将sid提供给讯飞开发者,用于问题定位排查
			/*if(eventType == SpeechEvent.EVENT_SESSION_ID) {
				DebugLog.Log("sid=="+msg);
			}*/
		}
	};

# 2.3.2 使用音频文件听写示例

	public void RecognizePcmfileByte() {
		SpeechRecognizer recognizer = SpeechRecognizer.getRecognizer();
		recognizer.setParameter(SpeechConstant.AUDIO_SOURCE, "-1");
		//写音频流时,文件是应用层已有的,不必再保存
		//recognizer.setParameter(SpeechConstant.ASR_AUDIO_PATH,
		//		"./iat_test.pcm");
		recognizer.setParameter( SpeechConstant.RESULT_TYPE, "plain" );
		recognizer.startListening(recListener);
		
		FileInputStream fis = null;
		final byte[] buffer = new byte[64*1024];
		try {
			fis = new FileInputStream(new File("./test.pcm"));
			if (0 == fis.available()) {
				mResult.append("no audio avaible!");
				recognizer.cancel();
			} else {
				int lenRead = buffer.length;
				while( buffer.length==lenRead && !mIsEndOfSpeech ){
					lenRead = fis.read( buffer );
					recognizer.writeAudio( buffer, 0, lenRead );
				}//end of while			
				recognizer.stopListening();
			}
			
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				if (null != fis) {
					fis.close();
					fis = null;
				}
		} catch (IOException e) {
				e.printStackTrace();
			}
		}//end of try-catch-finally
		
	}

# 2.3.3 上传用户词表

上传用户词表可以提高词表内词汇的识别率,也可以提高语义的效果,每个用户终端设备对应一个词表,用户词表的格式及构造方法详见《MSC Reference Manual》UserWords类。

private void uploadUserWords() {
	SpeechRecognizer recognizer = SpeechRecognizer.getRecognizer();
	UserWords userwords = new UserWords(USER_WORDS);
	recognizer.setParameter( SpeechConstant.DATA_TYPE, "userword" );
	recognizer.updateLexicon("userwords", userwords.toString(), lexiconListener);
}

/**
 * 词表上传监听器
 */
LexiconListener lexiconListener = new LexiconListener() {
	@Override
	public void onLexiconUpdated(String lexiconId, SpeechError error) {
		if (error == null)
			DebugLog.Log("*************上传成功*************");
		else
			DebugLog.Log("*************" + error.getErrorCode()+ "*************");
	}
};

备注:用户级词表和应用级词表的区别,设置用户级热词只在已安装当前设备终端上生效对该应用下其他设备不生效,在控制台设置个性化热词(应用级)则对该应用下设备服务都生效。目前听写离线环境下暂不支持热词上传。

# 2.3.4 动态修正

  • 未开启动态修正:实时返回识别结果,每次返回的结果都是对之前结果的追加;
  • 开启动态修正:实时返回识别结果,每次返回的结果有可能是对之前结果的的追加,也有可能是要替换之前某次返回的结果(即修正);
  • 开启动态修正,相较于未开启,返回结果的颗粒度更小,视觉冲击效果更佳;
  • 使用动态修正功能需到控制台-流式听写-高级功能处点击开通,并设置相应参数方可使用,参数设置方法:this.mParamMap.put( SpeechConstant.DWA, DefaultValue.DWA );
  • 动态修正功能仅 中文 支持;

未开启与开启返回的结果格式不同,若开通了动态修正功能并设置了dwa=wpgs(仅中文支持),会有如下字段返回:

参数 类型 描述
pgs string 开启wpgs会有此字段
取值为 "apd"时表示该片结果是追加到前面的最终结果;取值为"rpl" 时表示替换前面的部分结果,替换范围为rg字段
rg array 替换范围,开启wpgs会有此字段
假设值为[2,5],则代表要替换的是第2次到第5次返回的结果

# 2.3.5 代理服务器设置方法

在createUtility接口的params参数中添加:

net_type=custom, proxy_ip=<host>, proxy_port=<port>
其中,<host>,<port>替换为实际的代理服务器地址和端口。

例如:SpeechUtility.createUtility(SpeechConstant.APPID + “=12345678” + “,” + “net_type=custom, proxy_ip=192.168.1.2, proxy_port=8080”); 注意:各参数间,以英文逗号分隔。

接口原型: public static SpeechUtility createUtility(java.lang.String params)

注意: 若在设置代理参数后,使用语音服务过程中,报错10204/10205/10212等网络异常错误时,请查阅以下内容,做出相关操作:

  • 讯飞语音SDK的通信协议使用的是标准HTTP1.1协议,其代理协议使用的是标准HTTP代理协议。
  • 代理服务器需要支持全双工多问多答方式,即 pipeline 模式。
  • 代理服务器不能对80端口做限制,不能对如下域名做拦截: hdns.openspeech.cn scs.openspeech.cn open.xf-yun.com dev.voicecloud.cn
  • 需要确保代理服务器只负责转发数据包,不能改变数据包的完整性和时序性。
  • 代理服务器在转发数据包时,不能在HTTP协议头部添加 IE6 标识头。

# 2.3.6 常用参数说明

参数名称 名称 说明
domain 应用领域 服务器为不同的应用领域,定制了不同的听写匹配引擎,使用对应的领域能获取更高的匹配率。短信和日常用语:iat (默认),视频:video ,地图:poi,音乐:music。
language 语言区域 选择要使用的语言区域,目前sdk支持中文:zh_cn,英文:en_us。
accent 方言 当前仅在LANGUAGE为简体中文时,支持方言选择,其他语言区域时, 请把此参数值设为null。默认值:中文普通话(mandarin),其他方言参数可在控制台方言一栏查看。
vad_bos 前端点超时 开始录入音频后,音频前面部分最长静音时长 听写默认值5000ms,取值范围[1000ms,10000ms]。
vad_eos 后端点超时 开始录入音频后,音频后面部分最长静音时长,听写默认值1800ms,取值范围[0,10000ms]。
sample_rate 采样率 音频的采样率是音频属性的其中一个,一般来说,采样率越高音频的质量越好,识别的匹配率越高,但上传带宽消耗也越大。听写:支持采样率{8KHZ,16KHZ}。
nbest 句子多侯选 通过设置此参数,获取在发音相似时的句子多侯选结果。设置多候选会影响性能,响应时间延迟200ms左右。取值范围:听写[1,5]。
注:该扩展功能若未授权无法使用,可到控制台-语音听写(流式版)-高级功能处免费开通;若未授权状态下设置该参数并不会报错,但不会生效。
wbest 词语多侯选 通过设置此参数,获取在发音相似时的词语多侯选结 果。设置多候选会影响性能,响应时间延迟200ms左右。取值范围:听写[1,5]。
注:该扩展功能若未授权无法使用,可到控制台-语音听写(流式版)-高级功能处免费开通;若未授权状态下设置该参数并不会报错,但不会生效。
result_type 结果类型 结果类型包括:xml, json, plain。xml和json即对应的结构化文本结构,plain即自然语言的文本。
ptt 标点 (仅中文支持)是否开启标点符号添加1:开启(默认值)0:关闭 ;示例:this.mParamMap.put( SpeechConstant.ASR_PTT, DefaultValue.PTT );

注: 多候选效果是由引擎决定的,并非绝对的。即使设置了多候选,如果引擎并没有识别出候选的词或句,返回结果也还是单个。
备注:以上均为SDK常用参数说明,更多详细参数请参考:MSC Java API 文档.

# 2.3.7 识别结果说明

JSON字段 英文全称 类型 说明
sn sentence number 第几句
ls last sentence boolean 是否最后一句
bg begin number 开始
ed end number 结束
ws words array
cw chinese word array 中文分词
w word string 单字
sc score number 分数

听写结果示例:

{
    "sn": 1,
    "ls": true,
    "bg": 0,
    "ed": 0,
    "ws": [
        {
            "bg": 0,
            "cw": [
                {
                    "w": "今天",
                    "sc": 0
                }
            ]
        },
        {
            "bg": 0,
            "cw": [
                {
                    "w": "的",
                    "sc": 0
                }
            ]
        },
        {
            "bg": 0,
            "cw": [
                {
                    "w": "天气",
                    "sc": 0
                }
            ]
        },
        {
            "bg": 0,
            "cw": [
                {
                    "w": "怎么样",
                    "sc": 0
                }
            ]
        },
        {
            "bg": 0,
            "cw": [
                {
                    "w": "。",
                    "sc": 0
                }
            ]
        }
    ]
}

多候选结果示例:

{
    "sn": 1,
    "ls": false,
    "bg": 0,
    "ed": 0,
    "ws": [
        {
            "bg": 0,
            "cw": [
                {
                    "w": "我想听",
                    "sc": 0
                }
            ]
        },
        {
            "bg": 0,
            "cw": [
                {
                    "w": "拉德斯基进行曲",
                    "sc": 0
                },
                {
                    "w": "拉得斯进行曲",
                    "sc": 0
                }
            ]
        }
    ]
}

# 3、常见问题

# 集成语音识别功能时,程序启动后没反应

答:请检查是否忘记使用SpeechUtility初始化。 也可以在听写监听器的onError函数中打印错误信息,根据信息提示,查找错误源。

# SDK是否支持本地语音能力

答:Java平台暂时不支持本地能力。

# Appid的使用规范

答:申请的Appid和对应下载的SDK具有一致性,请确保在使用过程中规范传入。一个Appid对应一个平台下的一个应用,如在多个平台开发同款应用,还需申请对应平台的Appid。

# 如何设置语音云服务URL?

答:在createUtility接口中添加:server_url = http://YourDomainName/msp.do (YourDomainName是指语音云服务域名,请开发者自行替换) 例如:SpeechUtility.createUtility(SpeechConstant.APPID + "=12345678" + "," + "server_url = http://sdk.openspeech.cn/msp.do"); 注意:各参数间,以英文逗号分隔。 接口原型: public static SpeechUtility createUtility(java.lang.String params)

# SDK形式是否支持多路并发?

答:sdk:客户端解决方案,支持Android、ios、windows、linux、Java平台,不支持并发; webapi:服务端解决方案,不限制平台、不限制语言,支持并发。

# 如何设置识别业务所需的额外参数(其它业务类似)?

答:如要设置参数,各类参数设置参考《MSC Reference Manual》SpeechConstant类

# 获取到语音听写结果为空或错误内容或者内容不全的原因是什么?

答:原因可能是:
1、音频格式不正确,客户端支持的音频编解码算法只支持16位Intel PCM格式的音频,请使用Cool Edit Pro工具(网页搜索下载即可)查看音频格式,sdk目前支持的格式是 pcm 和 wav 格式、音频采样率要是 16k 或者 8k、采样精度16 位、单声道音频。请使用cool edit软件(网页搜索下载此软件即可)查看音频格式是否满足相应的识别引擎类型
2、引擎的参数设置不正确,如没有设置好正确的引擎类型和采样率等。
3、音频中间有静音或者杂音音频超过了后端点(默认为2000ms)的设置,此时请使用Cool Edit Pro工具查看音频内容,并且设置后端点(vad_eos)为最大值10000ms
包含超过后端点最大值的静音或者杂音音频识别不完整是正常的。

# 语音听写支持识别多长时间的音频,支持的音频格式是什么?

答:语音听写的功能是可以识别60S以内的短音频,将音频转化成文本信息。
听写sdk目前支持的格式是 pcm 和 wav 格式、音频采样率要是 16k 或者 8k、采样精度16 位、单声道音频。请使用cool edit软件(网页搜索下载此软件即可)查看音频格式是否满足相应的识别引擎类型,否则识别为空或者识别为错误文本,格式必须正确,除上述格式均不识别,音频格式一定要满足要求。
具体可以参考:http://bbs.xfyun.cn/forum.php?mod=viewthread&tid=7051
另外我们识别的音频长度最大为 60S,在使用音频是要注意你的本地音频的参数要和代码里的读取音频参数保持一致

# Java听写sdk如何下载?

答:文档中心---快速指引有介绍步骤---根据步骤下载Java在线听写sdk

# 更多Java问题,请见论坛帖子

SDK常见问题:Java SDK 常见问题解答