百度语音识别API-记录

本文介绍如何使用百度语音识别服务,包括注册成为开发者、获取Access Token及实现语音识别的完整流程。通过Java代码示例展示了如何配置语音识别参数并发送语音文件进行识别。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

参考:官方文档http://blog.youkuaiyun.com/lw_power/article/details/51771267

1、注册成为百度开发者,创建应用,得到 API Key 和 Secret Key

    略。

2、开通语音识别服务。

    略

3、获取 Access Token,语音解析关键代码:

package com.robin;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.xml.bind.DatatypeConverter;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.ParseException;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

import com.alibaba.fastjson.JSON;

public class VoiceDemo {

	/**
	 * 请求语音识别的时候使用
	 */
	private static final String speech_recognition_url = "http://vop.baidu.com/server_api";
	
	/**
	 * getLocalMac <获取本地mac> 
	 * <这里描述这个方法适用条件>
	 * @param ia
	 * @throws SocketException   
	 * void  
	 * @exception   
	 * @since [产品/模块版本]
	 */
	private static String getLocalMac(InetAddress ia) throws SocketException {
		// TODO Auto-generated method stub
		//获取网卡,获取地址
		byte[] mac = NetworkInterface.getByInetAddress(ia).getHardwareAddress();
		//System.out.println("mac数组长度:"+mac.length);
		StringBuffer sb = new StringBuffer("");
		for(int i=0; i<mac.length; i++) {
			if(i!=0) {
				sb.append("-");
			}
			//字节转换为整数
			int temp = mac[i]&0xff;
			String str = Integer.toHexString(temp);
			//System.out.println("每8位:"+str);
			if(str.length()==1) {
				sb.append("0"+str);
			}else {
				sb.append(str);
			}
		}
		//System.out.println("本机MAC地址:"+sb.toString().toUpperCase());
		return sb.toString().toUpperCase();
	}

	/**
	 * 
	 * getToken <获取token> <这里描述这个方法适用条件>
	 * 
	 * @return Map<String,Object> 返回MAP对象
	 * @exception @since
	 *                [产品/模块版本]
	 */
	@SuppressWarnings("unchecked")
	public static Map<String, Object> getToken() {
		Map<String, Object> map = new HashMap<String, Object>();
		String apiKey = "申请的apiKey";
		String secretKey = "申请的secretKey";

		try {
			CloseableHttpClient httpClient = HttpClients.createDefault();
			HttpPost httpPost = new HttpPost("https://openapi.baidu.com/oauth/2.0/token");
			List<NameValuePair> nvps = new ArrayList<>();
			nvps.add(new BasicNameValuePair("grant_type", "client_credentials"));
			nvps.add(new BasicNameValuePair("client_id", apiKey));
			nvps.add(new BasicNameValuePair("client_secret", secretKey));
			httpPost.setEntity(new UrlEncodedFormEntity(nvps));
			ResponseHandler<String> responseHandler = new ResponseHandler<String>() {

				@Override
				public String handleResponse(HttpResponse response) throws ClientProtocolException, IOException {
					int status = response.getStatusLine().getStatusCode();
					if (status >= 200 && status < 300) {
						HttpEntity entity = response.getEntity();
						try {
							return entity != null ? EntityUtils.toString(entity) : null;
						} catch (ParseException ex) {
							throw new ClientProtocolException(ex);
						}
					} else {
						throw new ClientProtocolException("Unexpected response status: " + status);
					}
				}
			};
			String responseBody = httpClient.execute(httpPost, responseHandler);
			//System.out.println(responseBody);
			map = (Map<String, Object>) JSON.parse(responseBody);
			/*Set<String> setKey = map.keySet();
			Iterator<String> it = setKey.iterator();
			while (it.hasNext()) {
				String str = it.next();
				System.out.println(str + "=" + map.get(str));
			}*/

		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} catch (ClientProtocolException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return map;
	}

	/**
	 * 
	 * recognize <语音识别> <这里描述这个方法适用条件>
	 * 
	 * @param wavName
	 *            文件路径
	 * @param language
	 *            语言
	 * @throws Exception
	 *             void
	 * @exception @since
	 *                [产品/模块版本]
	 */
	private static void recognize(String audioName, String language) throws Exception {
		File audioFile = new File(audioName);
		HttpPost httpPost = null;
		//CloseableHttpResponse response = null;
		CloseableHttpClient httpClient = HttpClients.createDefault();
		httpPost = new HttpPost(speech_recognition_url);
		SpeechRecognitionRequestEntity requestEntity = new SpeechRecognitionRequestEntity();
		// 语音压缩的格式:请按照官网文档填写 pcm(不压缩)、wav、opus、speex、amr、x-flac 之一,不区分大小写
		requestEntity.setFormat("pcm");
		// 声道数,仅支持单声道,请填写 1
		requestEntity.setChannel("1");
		// 采样率,支持 8000 或者 16000 (这个类型是 int ,不能设置为 String 类型,关于采样率如何转换,请见下文)
		requestEntity.setRate(16000);
		// todo 这里应判断 AccessToken 是否过期,处理异常,如果过期了,应该重新获取 accessToken
		
		requestEntity.setToken(getToken().get("access_token").toString());
		// Cuid 推荐使用设备 mac 地址 手机 IMEI 等设备唯一性参数
		InetAddress ia = InetAddress.getLocalHost();
		requestEntity.setCuid(getLocalMac(ia));

		requestEntity.setLen(audioFile.length());
		// 官网说: speech 要传递真实的语音数据,需要进行 base64 编码
		// 重点关注:请见后面封装的方法,就是把一个文件转换成为指定格式的字节数组
		requestEntity.setSpeech(DatatypeConverter.printBase64Binary(handlerAudioFile(audioFile)));
		// 语种选择,中文=zh、粤语=ct、英文=en,不区分大小写,默认中文
		requestEntity.setLan(language);
		// 关键点 1 :将请求参数转换为 json 格式
		String requestEntityJson = JSON.toJSONString(requestEntity);
		// 关键点 2 :封装 StringEntity ,为解决中文乱码问题,应该设置编码
		StringEntity entity = new StringEntity(requestEntityJson.toString(), "UTF-8");
		entity.setContentEncoding("UTF-8");
		// 关键点 3 :设置 StringEntity 的 ContentType
		entity.setContentType("application/json");
		httpPost.setEntity(entity);
		ResponseHandler<String> responseHandler = new ResponseHandler<String>() {
			@Override
			public String handleResponse(HttpResponse response) throws ClientProtocolException, IOException {
				String resData = null;
				int statusCode = response.getStatusLine().getStatusCode();
				if (statusCode >= 200 && statusCode < 300) {
					HttpEntity httpEntity = response.getEntity();
					resData = EntityUtils.toString(httpEntity, "utf-8");
					EntityUtils.consume(httpEntity);
				}
				return resData;
			}
		};
		try {
			String responseStr = httpClient.execute(httpPost, responseHandler);
			System.out.println(responseStr);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 
	 * handlerAudioFile <语音转码> 
	 * <这里描述这个方法适用条件>
	 * @param file
	 * @return
	 * @throws Exception   
	 * byte[]  
	 * @exception   
	 * @since [产品/模块版本]
	 */
	public static byte[] handlerAudioFile(File file) throws Exception {
		InputStream is = new FileInputStream(file);
		long length = file.length();
		byte[] bytes = new byte[(int) length];
		int offset = 0;
		int numRead = 0;
		while (offset < bytes.length && (numRead = is.read(bytes, offset, bytes.length - offset)) >= 0) {
			offset += numRead;
		}
		if (offset < bytes.length) {
			is.close();
			throw new IOException("Could not completely read file " + file.getName());
		}
		is.close();
		return bytes;
	}

	public static void main(String[] args) throws Exception {
		recognize("C:\\Users\\bbjiang\\Downloads\\16k.pcm", "zh");
	}
}

4、用到的实体类:

package com.robin;

public class SpeechRecognitionRequestEntity {
	 // 语音压缩的格式
    private String format;

    /**
     * 注意,采样率的数据类型一定是 int,不能是 String
     */
    // 采样率,支持 8000 或者 16000,在我们的项目中,写 16000
    private int rate;
    // 声道数,仅支持单声道,请填写 1
    private String channel;
    // 开发者身份验证密钥
    private String token;
    // 用户 ID,推荐使用设备 mac 地址 手机 IMEI 等设备唯一性参数
    // todo 貌似可以随意填写,唯一即可
    private String cuid;

    /**
     * 注意:这里填写的是原始语音的长度,不是使用 base64 编码的语音长度
     */
    // 原始语音长度,单位字节
    private long len;
    // 真实的语音数据,需要进行 base64 编码
    private String speech;
    // 语种选择,中文=zh、粤语=ct、英文=en,不区分大小写,默认中文
    private String lan;
	public String getFormat() {
		return format;
	}
	public void setFormat(String format) {
		this.format = format;
	}
	public int getRate() {
		return rate;
	}
	public void setRate(int rate) {
		this.rate = rate;
	}
	public String getChannel() {
		return channel;
	}
	public void setChannel(String channel) {
		this.channel = channel;
	}
	public String getToken() {
		return token;
	}
	public void setToken(String token) {
		this.token = token;
	}
	public String getCuid() {
		return cuid;
	}
	public void setCuid(String cuid) {
		this.cuid = cuid;
	}
	public long getLen() {
		return len;
	}
	public void setLen(long len) {
		this.len = len;
	}
	public String getSpeech() {
		return speech;
	}
	public void setSpeech(String speech) {
		this.speech = speech;
	}
	public String getLan() {
		return lan;
	}
	public void setLan(String lan) {
		this.lan = lan;
	}
    
}

5、用到的JAR包:

6、用到的示例文件:

转载于:https://my.oschina.net/robinjiang/blog/1580503

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值