import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.util.Calendar;
import java.util.HashMap;
import javax.crypto.spec.SecretKeySpec;
// import commons-codec-<version>.jar, download from http://commons.apache.org/proper/commons-codec/download_codec.cgi
import org.apache.commons.codec.binary.Base64;
public class IdentifyProtocolV1 {
private String encodeBase64(byte[] bstr) {
Base64 base64 = new Base64();
return new String(base64.encode(bstr));
private String encryptByHMACSHA1(byte[] data, byte[] key) {
SecretKeySpec signingKey = new SecretKeySpec(key, "HmacSHA1");
Mac mac = Mac.getInstance("HmacSHA1");
byte[] rawHmac = mac.doFinal(data);
return encodeBase64(rawHmac);
private String getUTCTimeSeconds() {
Calendar cal = Calendar.getInstance();
int zoneOffset = cal.get(Calendar.ZONE_OFFSET);
int dstOffset = cal.get(Calendar.DST_OFFSET);
cal.add(Calendar.MILLISECOND, -(zoneOffset + dstOffset));
return cal.getTimeInMillis()/1000 + "";
private String postHttp(String posturl, Map<String, Object> params, int timeOut) {
String BOUNDARYSTR = "*****2015.03.30.acrcloud.rec.copyright." + System.currentTimeMillis() + "*****";
String BOUNDARY = "--" + BOUNDARYSTR + "\r\n";
String ENDBOUNDARY = "--" + BOUNDARYSTR + "--\r\n\r\n";
String stringKeyHeader = BOUNDARY +
"Content-Disposition: form-data; name=\"%s\"" +
String filePartHeader = BOUNDARY +
"Content-Disposition: form-data; name=\"%s\"; filename=\"%s\"\r\n" +
"Content-Type: application/octet-stream\r\n\r\n";
HttpURLConnection conn = null;
BufferedOutputStream out = null;
BufferedReader reader = null;
ByteArrayOutputStream postBufferStream = new ByteArrayOutputStream();
for (String key : params.keySet()) {
Object value = params.get(key);
if (value instanceof String || value instanceof Integer) {
postBufferStream.write(String.format(stringKeyHeader, key, (String)value).getBytes());
} else if (value instanceof byte[]) {
postBufferStream.write(String.format(filePartHeader, key, key).getBytes());
postBufferStream.write((byte[]) value);
postBufferStream.write("\r\n".getBytes());
postBufferStream.write(ENDBOUNDARY.getBytes());
conn = (HttpURLConnection) url.openConnection();
conn.setConnectTimeout(timeOut);
conn.setReadTimeout(timeOut);
conn.setRequestMethod("POST");
conn.setRequestProperty("Accept-Charset", "utf-8");
conn.setRequestProperty("Content-type", "multipart/form-data;boundary=" + BOUNDARYSTR);
out = new BufferedOutputStream(conn.getOutputStream());
out.write(postBufferStream.toByteArray());
int response = conn.getResponseCode();
if (response == HttpURLConnection.HTTP_OK) {
reader = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8"));
while ((tmpRes = reader.readLine()) != null) {
if (postBufferStream != null) {
postBufferStream.close();
} catch (IOException e) {
public String recognize(String host, String accessKey, String secretKey, byte[] queryData, String queryType, int timeout)
String httpURL = "/v1/identify";
String dataType = queryType;
String timestamp = getUTCTimeSeconds();
String reqURL = "http://" + host + httpURL;
String sigStr = method + "\n" + httpURL + "\n" + accessKey + "\n" + dataType + "\n" + sigVersion + "\n" + timestamp;
String signature = encryptByHMACSHA1(sigStr.getBytes(), secretKey.getBytes());
Map<String, Object> postParams = new HashMap<String, Object>();
postParams.put("access_key", accessKey);
postParams.put("sample_bytes", queryData.length + "");
postParams.put("sample", queryData);
postParams.put("timestamp", timestamp);
postParams.put("signature", signature);
postParams.put("data_type", queryType);
postParams.put("signature_version", sigVersion);
String res = postHttp(reqURL, postParams, timeout);
public static void main(String[] args) {
File file = new File("E://sample.wav");
byte[] buffer = new byte[1024 * 1024];
FileInputStream fin = null;
fin = new FileInputStream(file);
bufferLen = fin.read(buffer, 0, buffer.length);
} catch (IOException e) {
System.out.println("bufferLen=" + bufferLen);
byte[] postDatas = new byte[bufferLen];
System.arraycopy(buffer, 0, postDatas, 0, bufferLen);
IdentifyProtocolV1 a = new IdentifyProtocolV1();
// Replace "###...###" below with your project's host, access_key and access_secret.
// recognize(String host, String accessKey, String secretKey, byte[] queryData, String queryType, int timeout)
String result = a.recognize("###YOUR_HOST###", "###YOUR_KEY###", "###YOUR_SECRET###", postDatas, "audio", 10000);
System.out.println(result);