2019-08-15 11:18:50 minthemir 阅读数 814
  • 微信h5支付开发-php开发微信h5支付demo

    会员免费看,http://edu.csdn.net/lecturer/842右侧可办理会员卡。微信h5支付开发是子恒老师《子恒说微信开发》视频教程的第17部。详细讲解了微信H5支付开发,内容包含开通H5支付,实现微信h5支付,订单查询,关闭订单等等。欢迎反馈,微信号:QQ68183131

    8011 人正在学习 去看看 秦子恒
最近在学习如何应用API来实现语言交互系统的功能,所以打算写一篇文章来整理和记录自己了解API使用的过程。
有很多平台提供语音识别等功能的API,文章使用的是科大讯飞开发的API。

讯飞开放平台简介

本文所使用的资料和基础代码均来自科大讯飞的 讯飞开放平台开放平台论坛社区讯飞开放平台上提供了很多产品和项目解决方案,一些SDK以及基础使用方法。你只需注册一个账号(或进一步实名制来申请更多资源)就可获取一个APPID,就可以在一定的每日免费使用量下完成本文的demo。

讯飞开放平台
讯飞开放平台–论坛社区

SDK的下载

实际上讯飞开放平台提供的SDK会根据你的选中的功能自动生成一个包含你APPID的压缩包,里面会有已经实现你选中功能的例程sample的整个工程:
如果使用语音唤醒需要提前在控制台的页面内设置唤醒词,然后再下载SDK
在这里插入图片描述
平台已经提供了相关的文档来支持你跑动所有你可以下载到的例程,并且你的APPID已经设置到相应的文件里,你无需再自行修改(如果出现问题,可参照平台文档内流程设置或重新下载SDK)。本文默认认为你已经了解讯飞开放平台的基本使用方法因此这里就不再过多的提及。
由于文章写的是Windows平台的demo,所以在这里贴一个Windows下的API文档:

MSC for Windows&Linux API

文档里面详尽的提供了API文档应该提供的内容,但是如果之前没有相关经验或者和我一样是那种没有认真写过代码的CS本科生,那么你需要通过一定的实践和认真阅读代码来熟悉和理解。

Visual Studio工程

在这里插入图片描述
如你所见,压缩包里的工程已经整理好你所选中的所有功能,你可以每一个都把玩一下,看看他们运行起来的样子。这有助于理解API函数运行的逻辑,并给你提供一个设计应用的思路。
如你所见,官方提供的Windows\Linux平台API全部都是C语言编写,如果你要根据具体项目开发使用其他编程语言(或许可以使用WebAPI)。
同时,例程项目都是单独生成的,因此每一个功能的例程都是单独运行的。

离线语音识别

我实现的demo是通过本地离线命令词识别来进行语音识别,讯飞开放平台对这个原理的介绍如下:

语法(命令词)识别,是基于语法规则,将与语法一致的自然语言音频转换为文本输出的技术。语法识别的结果值域只在语法文件所列出的规则里,故有很好的匹配率,另外,语法识别结果携带了结果的置信度,应用可以根据置信分数,决定这个结果是否有效。语法识别多用于要更准确结果且有限说法的语音控制,如空调的语音控制等。在使用语法识别时,应用需要先编写一个语法文件,然后通过调用QISRBuildGrammar接口编译本地语法文件,以及获得语法ID,并在会话时,传入语法ID,以使用该语法。

后面我会在讲语法开发怎么做,首先要把拼凑出来的代码跑通。

主函数

int main(int argc, char* argv[])
{
	const char *login_config    = "appid = 123456789"; //登录参数,这里写你的APPID
	UserData asr_data; 
	int ret                    = 0 ;

	ret = MSPLogin(NULL, NULL, login_config); //第一个参数为用户名,第二个参数为密码,传NULL即可,第三个参数是登录参数
	if (MSP_SUCCESS != ret) {
		printf("登录失败:%d\n", ret);
		goto exit;
	}

	memset(&asr_data, 0, sizeof(UserData));
	printf("构建离线识别语法网络...\n");
	ret = build_grammar(&asr_data);  //第一次使用某语法进行识别,需要先构建语法网络,获取语法ID,之后使用此语法进行识别,无需再次构建
	if (MSP_SUCCESS != ret) {
		printf("构建语法调用失败!\n");
		goto exit;
	}
	while (1 != asr_data.build_fini)
		_sleep(300);
	if (MSP_SUCCESS != asr_data.errcode)
		goto exit;
	printf("离线识别语法网络构建完成,开始识别...\n");	
	ret = run_asr(&asr_data);		//执行封装好的语音识别函数
	if (MSP_SUCCESS != ret) {
		printf("离线语法识别出错: %d \n", ret);
		goto exit;
	}

	printf("请按任意键继续\n");
	_getch();
	printf("更新离线语法词典...\n");
	ret = update_lexicon(&asr_data);  //当语法词典槽中的词条需要更新时,调用QISRUpdateLexicon接口完成更新
	if (MSP_SUCCESS != ret) {
		printf("更新词典调用失败!\n");
		goto exit;
	}
	while (1 != asr_data.update_fini)
		_sleep(300);
	if (MSP_SUCCESS != asr_data.errcode)
		goto exit;
	printf("更新离线语法词典完成,开始识别...\n");
	ret = run_asr(&asr_data);
	if (MSP_SUCCESS != ret) {
		printf("离线语法识别出错: %d \n", ret);
		goto exit;
	}

exit:
	MSPLogout();
	printf("请按任意键退出...\n");
	_getch();
	return 0;
}

API提供的函数,几乎所有的函数返回值都是通过宏定义的错误码,而这个错误码可以在官方的查询链接里查询:
错误码查询–讯飞开放平台
对于错误码的及时和解决方法都说的比较笼统,如果你跟我一样缺乏相关经验,估计要花时间来猜测分析错误的原因。

run_asr运行整套流程:

int run_asr(UserData *udata)
{
	char asr_params[MAX_PARAMS_LEN]    = {NULL};
	//离线唤醒的参数设置
	const char *ssb_param = "ivw_threshold=0:1450,sst=wakeup,ivw_res_path =fo|res/ivw/wakeupresource.jet";
	const char *rec_rslt               = NULL;
	const char *session_id             = NULL;
	const char *asr_audiof             = NULL;
	FILE *f_pcm                        = NULL;
	char *pcm_data                     = NULL;
	long pcm_count                     = 0;
	long pcm_size                      = 0;
	int last_audio                     = 0;
	int aud_stat                       = MSP_AUDIO_SAMPLE_CONTINUE;
	int ep_status                      = MSP_EP_LOOKING_FOR_SPEECH;
	int rec_status                     = MSP_REC_STATUS_INCOMPLETE;
	int rss_status                     = MSP_REC_STATUS_INCOMPLETE;
	int errcode                        = -1;
	int aud_src                        = 0;
	const char res[] = "id=\"001\"";
	//离线语法识别参数设置
	_snprintf(asr_params, MAX_PARAMS_LEN - 1, 
		"engine_type = local, \
		asr_res_path = %s, sample_rate = %d, \
		grm_build_path = %s, local_grammar = %s, \
		result_type = xml, result_encoding = GB2312,vad_eos=1000 ",
		ASR_RES_PATH,
		SAMPLE_RATE_16K,
		GRM_BUILD_PATH,
		udata->grammar_id
		);
	//printf("音频数据在哪? \n0: 从文件读入\n1:从MIC说话\n");
	//scanf("%d", &aud_src);
	
	//Getid(res);
	if(1) {
		while (1) //保持运行
		{
			printf("等待唤醒:\n");
			run_ivw(NULL, ssb_param);	//运行唤醒函数
			SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 12);
			printf("你好!小恩正在听……\n");	
			SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 15);
			run_asr_mic(asr_params);	//运行麦克风语音识别
		}
	} else {
		asr_audiof = get_audio_file();	//获取本地录音文件
		demo_file(asr_audiof, asr_params); 	//运行本地录音识别
	}
	return 0;
}

在原版的例程中是有一个函数是用本地录音进行语音识别,你也可以去掉或者保留用作调试。

唤醒功能的参数设置:

const char *ssb_param = "ivw_threshold=0:1450,\
sst=wakeup,\
ivw_res_path =fo|res/ivw/wakeupresource.jet";

识别功能的参数设置:

_snprintf(asr_params, MAX_PARAMS_LEN - 1, 
		"engine_type = local, \
		asr_res_path = %s, sample_rate = %d, \
		grm_build_path = %s, local_grammar = %s, \
		result_type = xml, result_encoding = GB2312,vad_eos=1000 ",
		ASR_RES_PATH,
		SAMPLE_RATE_16K,
		GRM_BUILD_PATH,
		udata->grammar_id
		);

我在这里将engine_type 参数设置为 local,表示我使用的是本地离线识别。
结果类型为XML类型,result_type = xml,结果编码为result_encoding = GB2312。你也可以设置为json或plain,但要注意更改encoding的类型
这里我增加了允许尾部静音的最长时间这个参数,vad_eos=1000,主要是根据我的需要,默认值为2000。(单位毫秒)

run_ivw运行唤醒:

//======================================================唤醒部分=====================================================
int awkeFlag = 0;	//唤醒状态flag,默认0未唤醒,1已换醒	
struct recorder *recorder;	//初始化录音对象
int record_state = MSP_AUDIO_SAMPLE_FIRST;	//初始化录音状态
int ISR_STATUS = 0;//oneshot专用,用来标识命令词识别结果是否已返回。

//唤醒状态消息提示,喂给回调函数QIVWRegisterNotify
int cb_ivw_msg_proc(const char *sessionID, int msg, int param1, int param2, const void *info, void *userData)
{
	if (MSP_IVW_MSG_ERROR == msg) //唤醒出错消息
	{
		//printf("\n\nMSP_IVW_MSG_ERROR errCode = %d\n\n", param1);
		printf("唤醒失败!");
		awkeFlag = 0;
	}
	else if (MSP_IVW_MSG_WAKEUP == msg) //唤醒成功消息
	{
		//printf("\n\nMSP_IVW_MSG_WAKEUP result = %s\n\n", info);
		SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 14);
		printf("唤醒成功!");
		SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 15);
		awkeFlag = 1;		
	}
	
	return 0;
}

//读取录音内容的函数,用于喂给创建录音的函数create_recorder
static void iat_cb(char *data, unsigned long len, void *user_para)
{
	int errcode;
	int ret = 0;
	const char *session_id = (const char *)user_para;//初始化本次识别的句柄。
	//printf("进入录音读取");
	if (len == 0 || data == NULL)
		return;
	
	errcode = QIVWAudioWrite(session_id, (const void *)data, len, record_state);
	
	if (MSP_SUCCESS != errcode)
	{
		printf("QIVWAudioWrite failed! error code:%d\n", errcode);
		ret = stop_record(recorder);
		if (ret != 0) {
			printf("Stop failed! \n");
			//return -E_SR_RECORDFAIL;
		}
		wait_for_rec_stop(recorder, (unsigned int)-1);
		QIVWAudioWrite(session_id, NULL, 0, MSP_AUDIO_SAMPLE_LAST);
		record_state = MSP_AUDIO_SAMPLE_LAST;
		//g_is_awaken_succeed = FALSE;
	}
	if (record_state == MSP_AUDIO_SAMPLE_FIRST) {
		record_state = MSP_AUDIO_SAMPLE_CONTINUE;
	}
}

//运行唤醒的本体
void run_ivw(const char *grammar_list, const char* session_begin_params)//运行唤醒步骤
{
	const char *session_id = NULL;	
	int err_code = MSP_SUCCESS;
	WAVEFORMATEX wavfmt = DEFAULT_FORMAT;
	char sse_hints[128];	//用于设置结束时显示的信息
	int count = 0;
	
	//开始唤醒session
	session_id = QIVWSessionBegin(grammar_list, session_begin_params, &err_code);
	if (err_code != MSP_SUCCESS)
	{
		printf("QIVWSessionBegin failed! error code:%d\n", err_code);
		goto exit;
	}
	err_code = QIVWRegisterNotify(session_id, cb_ivw_msg_proc, NULL);	//为避免丢失句柄,回掉函数应当在此调用
	if (err_code != MSP_SUCCESS)
	{
		_snprintf(sse_hints, sizeof(sse_hints), "QIVWRegisterNotify errorCode=%d", err_code);
		printf("QIVWRegisterNotify failed! error code:%d\n", err_code);
		goto exit;
	}
	//开始录音
	err_code = create_recorder(&recorder, iat_cb, (void*)session_id);
	err_code = open_recorder(recorder, get_default_input_dev(), &wavfmt);
	err_code = start_record(recorder);
	
	//循环监听,保持录音状态
	while (record_state != MSP_AUDIO_SAMPLE_LAST)
	{
		Sleep(200); //阻塞直到唤醒结果出现
		//printf("正在监听%d\n", record_state);
		if (awkeFlag == 1)
		{
			awkeFlag = 0;	//恢复标志位方便下次唤醒
			break;			//跳出循环
		}
		count++;
		if (count == 20)	//为了防止循环监听时写入到缓存中的数据过大
		{
			//先释放当前录音资源
			stop_record(recorder);
			close_recorder(recorder);
			destroy_recorder(recorder);
			recorder = NULL;
			//printf("防止音频资源过大,重建\n");
			//struct recorder *recorder;
			//重建录音资源
			err_code = create_recorder(&recorder, iat_cb, (void*)session_id);
			err_code = open_recorder(recorder, get_default_input_dev(), &wavfmt);
			err_code = start_record(recorder);
			count = 0;
		}
	}

exit:
	if (recorder) {
		if (!is_record_stopped(recorder))
			stop_record(recorder);
		close_recorder(recorder);
		destroy_recorder(recorder);
		recorder = NULL;
	}
	if (NULL != session_id)
	{
		QIVWSessionEnd(session_id, sse_hints); //结束一次唤醒会话
	}
}

QIVWAudioWrite()其实在流程中基本都是在循环调用的:

写入本次唤醒的音频,本接口需要反复调用直到音频写完为止。调用本接口时,推荐用户在写入音频时采取"边录边写"的方式,即每隔一小段时间将采集到的音频通过本接口写入MSC。

得到唤醒结果后,会通过回调注册的函数QIVWRegisterNotify()这样一个异步的机制给你返回结果。
所以QIVWRegisterNotify()函数应当在QIVWSessionBegin()函数执行过后就立即执行。否则会出现丢失句柄的状况。
建议在每执行一个接口后就进行error_code的判断和返回。由于函数的数据传递过程都封装好了,这样可以方便进行调试。
QIVWSessionEnd()主要用于释放这个会话的资源,同时可以给你展示一个你自己定义的结束信息,意味着它正常结束。
当你流程的接口调用方法和顺序不当时,多半会返回这个错误码:
在这里插入图片描述

run_asr_mic麦克风语音识别:

static void run_asr_mic(const char* session_begin_params)
{
	int errcode;
	int i = 0;
	HANDLE helper_thread = NULL;

	struct speech_rec asr;
	DWORD waitres;
	char isquit = 0;
	struct speech_rec_notifier recnotifier = {
		on_result,
		on_speech_begin,
		on_speech_end
	};
	errcode = sr_init(&asr, session_begin_params, SR_MIC, DEFAULT_INPUT_DEVID, &recnotifier);
	if (errcode = sr_start_listening(&asr)) {
		printf("start listen failed %d\n", errcode);
		isquit = 1;
	}
	//Sleep(3000);

	if (errcode = sr_stop_listening(&asr)) {
		printf("stop listening failed %d\n", errcode);
		isquit = 1;
	}
	sr_stop_listening(&asr);
	sr_uninit(&asr);
}

你可以通过单独建立一个Sleep()延时来设置一个你规定的录音时间,
也可以完全依赖API的VAD机制。
官方例程采用的方式是通过按键开始,按键结束这样一个方法来限定录音的时间。
为了有更好的体验,我在sr_stop_listening()函数中,是用了VAD:

int sr_stop_listening(struct speech_rec *sr)
{
	int ret = 0;
	const char * rslt = NULL;
	char rslt_str[2048] = { '\0' };
	int count = 0;
	//如果未开始录音就错误调用了本函数那么返回报错
	if (sr->state < SR_STATE_STARTED) {
		sr_dbg("Not started or already stopped.\n");
		return 0;
	}

	while (1)			//进程阻塞
	{
		if (sr->ep_stat == MSP_EP_AFTER_SPEECH)		//VAD检测为音频末尾
		{
			break;
		}
		
	}
	//采用录音参数为NULL,0,MSP_AUDIO_SAMPLE_LAST
	ret = QISRAudioWrite(sr->session_id, NULL, 0, MSP_AUDIO_SAMPLE_LAST, &sr->ep_stat, &sr->rec_stat);
	if (ret != 0) {
		sr_dbg("write LAST_SAMPLE failed: %d\n", ret);
		QISRSessionEnd(sr->session_id, "write err");
		return ret;
	}

	//反复调用结果函数,直至获取结果
	while (sr->rec_stat != MSP_REC_STATUS_COMPLETE) {
		rslt = QISRGetResult(sr->session_id, &sr->rec_stat, 0, &ret);
		if (MSP_SUCCESS != ret)	{
			sr_dbg("\nQISRGetResult failed! error code: %d\n", ret);
			end_sr_on_error(sr, ret);
			return ret;
		}
		if (NULL != rslt && sr->notif.on_result)
			sr->notif.on_result(rslt, sr->rec_stat == MSP_REC_STATUS_COMPLETE ? 1 : 0);
		Sleep(100);
	}
	strcat(rslt_str, rslt);	//存储结果内容
	printf(rslt_str);	//展示结果
	Getid(rslt_str);	//解析出ID
	GetRawText(rslt_str);	//解析出原文
	//结束本次录音,释放资源
	if (sr->aud_src == SR_MIC) {
		ret = stop_record(sr->recorder);
#ifdef __FILE_SAVE_VERIFY__
		safe_close_file();
#endif
		if (ret != 0) {
			sr_dbg("Stop failed! \n");
			return -E_SR_RECORDFAIL;
		}
		wait_for_rec_stop(sr->recorder, (unsigned int)-1);
	}
	sr->state = SR_STATE_INIT;
	QISRSessionEnd(sr->session_id, "normal");
	sr->session_id = NULL;
	return 0;
}

语法规则:

本文使用的是离线命令词识别,官方使用的语法规则是巴克斯范式BNF。
可以在论坛下载pdf文件去系统学习如何定义规则:
语法开发指南
当你是用本地语法规则是,应当将你的BNF文件编辑好,并在代码中指定文件路径:
在这里插入图片描述
在这里插入图片描述
例程中附带BNF可以给你一个很好范本,作为你“照葫芦画瓢”的对象。

运行效果:

在这里插入图片描述
实际上API只会给你返回一个XML的字符串,如果你要解析你需要的信息,可以尝试用一些库去尝试。其中需要注意的是,如果你的部分语法中的词汇没有指定id,那么在xml中会返回一个默认的最大值65535。所以在编制id的时候应当避免编制到65535这个最大的数值,而且尽量在解析的时候滤除65535的关键词。

2016-12-27 11:04:56 weixin_36429334 阅读数 6197
  • 微信h5支付开发-php开发微信h5支付demo

    会员免费看,http://edu.csdn.net/lecturer/842右侧可办理会员卡。微信h5支付开发是子恒老师《子恒说微信开发》视频教程的第17部。详细讲解了微信H5支付开发,内容包含开通H5支付,实现微信h5支付,订单查询,关闭订单等等。欢迎反馈,微信号:QQ68183131

    8011 人正在学习 去看看 秦子恒

1,首先打开百度语音识别官网,注册一个账户成为开发者,接着创建一个应用,下载百度提供源代码 。

下载地址: http://yuyin.baidu.com/sdk/
官方文档地址:http://yuyin.baidu.com/docs/asr/54

sdk下载

下载demo

2,打开源代码,进行配置参数或修改要识别的语言文件

demo1

<?php 
define('AUDIO_FILE', "./text2audio_1.wav"); //语音文件地址,值支持本地

$url = "http://vop.baidu.com/server_api";

//put your params here
$cuid = "";
$apiKey = "";
$secretKey = "";

$auth_url = "https://openapi.baidu.com/oauth/2.0/token?grant_type=client_credentials&client_id=".$apiKey."&client_secret=".$secretKey;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $auth_url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
$response = curl_exec($ch);
if(curl_errno($ch))
{
    print curl_error($ch);
}
curl_close($ch);
$response = json_decode($response, true);
$token = $response['access_token'];

$audio = file_get_contents(AUDIO_FILE);
$base_data = base64_encode($audio);
$array = array(
        "format" => "wav",
        "rate" => 8000,
        "channel" => 1,
//        "lan" => "zh",
        "token" => $token,
        "cuid"=> $cuid,
        //"url" => "http://www.xxx.com/sample.pcm",
        //"callback" => "http://www.xxx.com/audio/callback",
        "len" => filesize(AUDIO_FILE),
        "speech" => $base_data,
        );
$json_array = json_encode($array);
$content_len = "Content-Length: ".strlen($json_array);
$header = array ($content_len, 'Content-Type: application/json; charset=utf-8');

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
curl_setopt($ch, CURLOPT_POSTFIELDS, $json_array);
$response = curl_exec($ch);
if(curl_errno($ch))
{
    print curl_error($ch);
}
curl_close($ch);
echo $response;
$response = json_decode($response, true);
var_dump($response);

demo2


define('AUDIO_FILE', "./text.wav");

//put your params here
$cuid = "";
$apiKey = "";
$secretKey = "";

$auth_url = "https://openapi.baidu.com/oauth/2.0/token?grant_type=client_credentials&client_id=".$apiKey."&client_secret=".$secretKey;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $auth_url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
$response = curl_exec($ch);
if(curl_errno($ch))
{
    print curl_error($ch);
}
curl_close($ch);
$response = json_decode($response, true);
$token = $response['access_token'];

$url = "http://vop.baidu.com/server_api?cuid=".$cuid."&token=".$token;
$url = $url."&lan=zh";
$audio = file_get_contents(AUDIO_FILE);
$content_len = "Content-Length: ".strlen($audio);
$header = array ($content_len,'Content-Type: audio/pcm; rate=8000',);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
curl_setopt($ch, CURLOPT_POSTFIELDS, $audio);
$response = curl_exec($ch);
if(curl_errno($ch))
{
    print curl_error($ch);
}
curl_close($ch);
echo $response;
$response = json_decode($response, true);
echo '<pre>';
var_dump($response);

3、运行文件识别,运行后发现调取接口成功,但是识别出来的正确率百分之一都不到,于是查看原因发现,百度语音识别只支持 8k/16k 采样率 16bit 位深的单声道语音,进行音频格式转换后正确率可达成80% 。

注意事项:
语音识别接口支持 POST 方式
目前 API 仅支持整段语音识别的模式,即需要上传整段语音进行识别
语音数据上传方式有两种:隐示发送和显示发送
原始语音的录音格式目前只支持评测 8k/16k 采样率 16bit 位深的单声道语音
压缩格式支持:pcm(不压缩)、wav、opus、speex、amr、x-flac
系统支持语言种类:中文(zh)、粤语(ct)、英文(en)

4、因为是调用接口测试所以在转换音频格式使用的是格式工厂,如果项目需要可使用代码自动转换(自行百度)

这里写图片描述

这里写图片描述

这里写图片描述

然后进行确认转换得出来的格式再进行测试即可,谢谢~

2018-10-10 19:01:28 m0_37605956 阅读数 377
  • 微信h5支付开发-php开发微信h5支付demo

    会员免费看,http://edu.csdn.net/lecturer/842右侧可办理会员卡。微信h5支付开发是子恒老师《子恒说微信开发》视频教程的第17部。详细讲解了微信H5支付开发,内容包含开通H5支付,实现微信h5支付,订单查询,关闭订单等等。欢迎反馈,微信号:QQ68183131

    8011 人正在学习 去看看 秦子恒

摘要: 百度语音识别demo接入至vr设备:
项目所需,要测试百度语音识别对某些特定指令语言在vr设备上的识别正确率,需要首先研究百度语音识别的demo使用,特将整个学习过程记录:

一:百度语音android sdk下载地址
http://ai.baidu.com/sdk#asr
我下载了“离在线融合SDK”的android版本
上述链接的页面点击"使用说明"链接,进入SDK说明页面:
http://ai.baidu.com/docs#/ASR-Android-SDK/top

SDK下载后,参考了两个重要的文档,
第一个是目录下的readme_README_IMPORTANT
第二个是doc_integration_DOCUMENT目录下的"ASR-INTEGRATION-helloworld-V2.0",

二:根据上述文档集成百度asr至helloworld工程
由于下载下来的sdk直接导入到android studio中没有编译通过,所以直接新建项目集成语音识别功能,依据ASR-INTEGRATION-helloworld-V2.0文档,

首先新建一个android helloworld工程:
为了节约时间,没有在官网中注册应用。使用百度demo的各个参数。在工程新建过程中,完全按文档中的进行,包括company domain, appId,appkey,secretkey以及applicationId。在选择activity模板时候,选择了"Empty activity",android的版本号选择了默认的15

其次:工程建好编译通过后,按文档导入原demo的core模块并设置app依赖core,编译时候出现以下错误:
Android dependency ‘com.android.support:appcompat-v7’ has different version for the compile (26.1.0) and runtime (27.1.1) classpath. You should manually set the same version via DependencyResolution

网上搜索原因发现:
是由于app和core两个模块使用的依赖库(appcompat-v7)的版本号不同导致,
app的gradle:
dependencies {
implementation fileTree(include: [’
.jar’], dir: ‘libs’)
implementation ‘com.android.support:appcompat-v7:26.1.0’
implementation ‘com.android.support.constraint:constraint-layout:1.1.3’
testImplementation ‘junit:junit:4.12’
androidTestImplementation ‘com.android.support.test?1.0.2’
androidTestImplementation ‘com.android.support.test.espresso:espresso-core:3.0.2’
implementation project(’:core’)
}*
core的gradle:
dependencies {
api fileTree(include: [’
.jar’], dir: ‘libs’)
implementation ‘com.android.support:appcompat-v7:27.1.1’
}*

于是修改了app模块的库版本至:27.1.1,与core保持一致。
同时修改app模块build.gradle里的compileSdkVersion 27,targetSdkVersion 27,之后编译通过。

之后修改mainactivity如下:
public class MainActivity extends ActivityMiniRecog {

}

编译后安装到android手机可以进行语音识别

三: 将该demo移植至vr设备:
需要修改manifest,在MainActivity的intent-filter下增加:
category android:name=“com.***.intent.category.VRAPP”
这样安装后可以看到该AP

四: vr设备如何测试:
由于不能直接点击,所以在使用controller打开AP后,需要一个辅助软件vysor进行投屏,然后在电脑上面进行点击测试操作。

2013-07-17 17:41:17 l294333475 阅读数 8775
  • 微信h5支付开发-php开发微信h5支付demo

    会员免费看,http://edu.csdn.net/lecturer/842右侧可办理会员卡。微信h5支付开发是子恒老师《子恒说微信开发》视频教程的第17部。详细讲解了微信H5支付开发,内容包含开通H5支付,实现微信h5支付,订单查询,关闭订单等等。欢迎反馈,微信号:QQ68183131

    8011 人正在学习 去看看 秦子恒
<html>
	<head>
	
	<script type='text/javascript'>
	if (document.createElement("input").webkitSpeech === undefined) {  
		alert("很遗憾,你的浏览器不支持语音识别。");
		}
	else{
		alert("尝试使用语言识别来输入内容吧");
		}

	//事件的触发(可使用下面的js调用完成)
	/*
	input.onwebkitspeechchange = function() {
			alert("aaa");
	*/
	};
	</script>
	<script>//这里的作用是文本框(搜索框)失去焦点的时候,值重新赋了下。这样语音再次输入就不会将以前的值去掉
		document.querySelector("input[name='s']").addEventListener("blur",function(){this.value=this.value;});
	</script>
	</head>
	<body>
	<!--
		<input name="s" type="text" x-webkit-speech x-webkit-grammar="builtin:translate" />
		<input x-webkit-speech lang="zh-CN" />
		<input x-webkit-speech x-webkit-grammar="bUIltin:search" />
	-->
	<form action="http://www.google.com/search" >
		<input type="search" name="q" lang="zh-CN" x-webkit-speech x-webkit-grammar="builtin:search" onwebkitspeechchange="startSearch(event)"/>
	</form>
	</body>
</html>

2018-04-19 14:14:12 ljl86400 阅读数 104
  • 微信h5支付开发-php开发微信h5支付demo

    会员免费看,http://edu.csdn.net/lecturer/842右侧可办理会员卡。微信h5支付开发是子恒老师《子恒说微信开发》视频教程的第17部。详细讲解了微信H5支付开发,内容包含开通H5支付,实现微信h5支付,订单查询,关闭订单等等。欢迎反馈,微信号:QQ68183131

    8011 人正在学习 去看看 秦子恒

为语音识别的demo添加单选项提示对话:

mVoicesFilesList = new ArrayList<>();                // 将存放语音文件信息的列表实例化
        mVoicesFilesListView = findViewById(R.id.voidList);    // 设置显示语音列表内容的界面
        /**
         * 为列表中的选项添加按键响应,跳出一个单选列表项提示对话框
         */
        mVoicesFilesListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {


            @Override
            public void onItemClick (AdapterView<?> adapterView, View view, int position, long id) {
                DialogButtonOnClick dialogButtonOnClick = new DialogButtonOnClick(0);       // 默认选中了第一个选项(播放)
                Uri fileUri = Uri.parse("file://" + mVoicesFilesList.get(position));   // 可以使用Uri格式的
                dialogButtonOnClick.setUri(fileUri);
                AlertDialog.Builder mVoiceFilesProcessorDialog = new AlertDialog.Builder(MainActivity.this)
                        .setTitle("选择功能")
                        .setSingleChoiceItems(functionItems, 0,dialogButtonOnClick)
                        .setPositiveButton("确认",dialogButtonOnClick)
                        .setNegativeButton("取消",dialogButtonOnClick);
                mVoiceFilesProcessorDialog.create().show();
            }
        });

响应按键的类如下:

/**
     * 定义一个监听器,用来监听提示对话框的点击动作
     */
    private class DialogButtonOnClick implements DialogInterface.OnClickListener
    {

        private int index; // 表示选项的索引
        private Uri uri ;

        private DialogButtonOnClick(int index)
        {
            this.index = index;
        }

        public void setUri(Uri uri){
            this.uri = uri;
        }

        @Override
        public void onClick(DialogInterface dialog, int which)
        {
            switch (which){
                case 0:
                case 1:
                case 2:
                    index = which;
                    Log.d(TAG, "onClick:which " + which);
                    Log.d(TAG, "onClick:index " + index);
                    break;
                case DialogInterface.BUTTON_POSITIVE:
                    switch (index){
                        case 0:
                            playSound(uri);
                            break;
                        case 1:
                            showTip("识别功能待添加");
                            break;
                        case 2:
                            showTip("删除功能待添加");
                            break;
                        default:
                            break;
                    }
                    break;
                case DialogInterface.BUTTON_NEGATIVE:
                    showTip("取消并退出");
                    break;
                default:
                    break;
            }
        }
    }



android语音识别Demo

阅读数 6023

没有更多推荐了,返回首页