Appearance
识别 API
TIP
- 使用此接口时需要指定 Content-Type 为 "multipart/form-data"
- 本接口同时支持识别指纹和音频
- 我们建议使用指纹来识别,这会减小带宽并且会加快识别的速度
- 我们建议识别的内容小于 12 秒, 且接口只会识别前 12 秒内容,多余的部分将会被丢弃。
接口和参数
API 地址:identify-cn-north-1.acrcloud.cn/v1/identify
请求方法: POST
参数:
参数名 | 类型 | 描述 |
---|---|---|
sample | object | 音频或者指纹文件的内容 |
sample_bytes | string | 音频或者指纹文件的大小 |
access_key | string | 控制台中的 access_key |
timestamp | string | 时间戳 |
data_type | string | audio 或者 fingerprint |
signature_version | number | 1 |
signature | string | 请求签名,用于合法性校验。 |
以下是签名的示例代码,您可以参考以下代码编写签名。
python
timestamp = time.time()
string_to_sign = http_method + "\n" + http_uri + "\n" + access_key + "\n" + data_type + "\n" + signature_version + "\n" + str(timestamp)
hmac_digest = hmac.new(access_secret.encode('ascii'), string_to_sign.encode('ascii'), digestmod=hashlib.sha1).digest()
sign = base64.b64encode(hmac_digest).decode('ascii')
示例代码
python
"""
This is a demo program which implements ACRCloud Identify Protocol V1 with the third party library "requests".
We recomment you implement your own app with "requests" too.
You can install this python library by:
1) sudo easy_install requests
2) sudo pip install requests
"""
import base64
import hashlib
import hmac
import os
import sys
import time
import requests
'''
Replace "###...###" below with your project's host, access_key and access_secret.
'''
access_key = "###YOUR_ACCESS_KEY###"
access_secret = "###YOUR_ACCESS_SECRET###"
requrl = "http://###YOUR_HOST###/v1/identify"
http_method = "POST"
http_uri = "/v1/identify"
# default is "fingerprint", it's for recognizing fingerprint,
# if you want to identify audio, please change data_type="audio"
data_type = "audio"
signature_version = "1"
timestamp = time.time()
string_to_sign = http_method + "\n" + http_uri + "\n" + access_key + "\n" + data_type + "\n" + signature_version + "\n" + str(
timestamp)
sign = base64.b64encode(hmac.new(access_secret.encode('ascii'), string_to_sign.encode('ascii'),
digestmod=hashlib.sha1).digest()).decode('ascii')
# suported file formats: mp3,wav,wma,amr,ogg, ape,acc,spx,m4a,mp4,FLAC, etc
# File size: < 1M , You'de better cut large file to small file, within 15 seconds data size is better
f = open(sys.argv[1], "rb")
sample_bytes = os.path.getsize(sys.argv[1])
files = [
('sample', ('test.mp3', open('/Users/olym/Downloads/test.mp3', 'rb'), 'audio/mpeg'))
]
data = {'access_key': access_key,
'sample_bytes': sample_bytes,
'timestamp': str(timestamp),
'signature': sign,
'data_type': data_type,
"signature_version": signature_version}
r = requests.post(requrl, files=files, data=data)
r.encoding = "utf-8"
print(r.text)
php
<?php
$http_method = "POST";
$http_uri = "/v1/identify";
$data_type = "audio";
$signature_version = "1" ;
$timestamp = time() ;
// Replace "###...###" below with your project's host, access_key and access_secret.
$requrl = "http://###YOUR_HOST###/v1/identify";
$access_key = '###YOUR_ACCESS_KEY###';
$access_secret = '###YOUR_ACCESS_SECRET###';
$string_to_sign = $http_method . "\n" .
$http_uri ."\n" .
$access_key . "\n" .
$data_type . "\n" .
$signature_version . "\n" .
$timestamp;
$signature = hash_hmac("sha1", $string_to_sign, $access_secret, true);
$signature = base64_encode($signature);
// suported file formats: mp3,wav,wma,amr,ogg, ape,acc,spx,m4a,mp4,FLAC, etc
// File size: < 1M , You'de better cut large file to small file, within 15 seconds data size is better
$file = $argv[1];
$filesize = filesize($file);
$cfile = new CURLFile($file, "mp3", basename($argv[1]));
$postfields = array(
"sample" => $cfile,
"sample_bytes"=>$filesize,
"access_key"=>$access_key,
"data_type"=>$data_type,
"signature"=>$signature,
"signature_version"=>$signature_version,
"timestamp"=>$timestamp);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $requrl);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postfields);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$result = curl_exec($ch);
echo $result;
//$response = curl_exec($ch);
//if ($response == true) {
// $info = curl_getinfo($ch);
//} else {
// $errmsg = curl_error($ch);
// print $errmsg;
//}
curl_close($ch);
?>
java
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Map;
import javax.crypto.Mac;
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) {
try {
SecretKeySpec signingKey = new SecretKeySpec(key, "HmacSHA1");
Mac mac = Mac.getInstance("HmacSHA1");
mac.init(signingKey);
byte[] rawHmac = mac.doFinal(data);
return encodeBase64(rawHmac);
} catch (Exception e) {
e.printStackTrace();
}
return "";
}
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 res = "";
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\"" +
"\r\n\r\n%s\r\n";
String filePartHeader = BOUNDARY +
"Content-Disposition: form-data; name=\"%s\"; filename=\"%s\"\r\n" +
"Content-Type: application/octet-stream\r\n\r\n";
URL url = null;
HttpURLConnection conn = null;
BufferedOutputStream out = null;
BufferedReader reader = null;
ByteArrayOutputStream postBufferStream = new ByteArrayOutputStream();
try {
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());
url = new URL(posturl);
conn = (HttpURLConnection) url.openConnection();
conn.setConnectTimeout(timeOut);
conn.setReadTimeout(timeOut);
conn.setRequestMethod("POST");
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setRequestProperty("Accept-Charset", "utf-8");
conn.setRequestProperty("Content-type", "multipart/form-data;boundary=" + BOUNDARYSTR);
conn.connect();
out = new BufferedOutputStream(conn.getOutputStream());
out.write(postBufferStream.toByteArray());
out.flush();
int response = conn.getResponseCode();
if (response == HttpURLConnection.HTTP_OK) {
reader = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8"));
String tmpRes = "";
while ((tmpRes = reader.readLine()) != null) {
if (tmpRes.length() > 0)
res = res + tmpRes;
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (postBufferStream != null) {
postBufferStream.close();
postBufferStream = null;
}
if (out != null) {
out.close();
out = null;
}
if (reader != null) {
reader.close();
reader = null;
}
if (conn != null) {
conn.disconnect();
conn = null;
}
} catch (IOException e) {
e.printStackTrace();
}
}
return res;
}
public String recognize(String host, String accessKey, String secretKey, byte[] queryData, String queryType, int timeout)
{
String method = "POST";
String httpURL = "/v1/identify";
String dataType = queryType;
String sigVersion = "1";
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);
return res;
}
public static void main(String[] args) {
File file = new File("E://sample.wav");
byte[] buffer = new byte[1024 * 1024];
if (!file.exists()) {
return;
}
FileInputStream fin = null;
int bufferLen = 0;
try {
fin = new FileInputStream(file);
bufferLen = fin.read(buffer, 0, buffer.length);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (fin != null) {
fin.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
System.out.println("bufferLen=" + bufferLen);
if (bufferLen <= 0)
return;
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);
}
}
java
import org.apache.http.HttpEntity;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import java.io.*;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import org.apache.commons.codec.binary.Base64;
import org.apache.http.util.EntityUtils;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
public class Recognizer {
private String host = "identify-cn-north-1.acrcloud.cn";
private String protocol = "https";
private String endpoint = "/v1/identify";
private String accessKey = "xxx";
private String accessSecret = "xxx";
private int timeout = 5 * 1000; // ms
private String encodeBase64(byte[] bstr) {
Base64 base64 = new Base64();
return new String(base64.encode(bstr));
}
private String encryptByHMACSHA1(byte[] data, byte[] key) {
try {
SecretKeySpec signingKey = new SecretKeySpec(key, "HmacSHA1");
Mac mac = Mac.getInstance("HmacSHA1");
mac.init(signingKey);
byte[] rawHmac = mac.doFinal(data);
return encodeBase64(rawHmac);
} catch (Exception e) {
e.printStackTrace();
}
return "";
}
public String recognizeByFile(String filePath, String dataType) {
File file = new File(filePath);
String method = "POST";
String sigVersion = "1";
String timestamp = System.currentTimeMillis() + "";
String sigStr = method + "\n" + endpoint + "\n" + accessKey + "\n" + dataType + "\n" + sigVersion + "\n" + timestamp;
String signature = encryptByHMACSHA1(sigStr.getBytes(), accessSecret.getBytes());
CloseableHttpClient httpClient = HttpClients.createDefault();
RequestConfig requestConfig = RequestConfig.custom()
.setConnectTimeout(timeout).setConnectionRequestTimeout(timeout)
.setSocketTimeout(timeout).build();
String reqUrl = protocol + "://" + host + "/" + endpoint;
HttpPost httpPost = new HttpPost(reqUrl);
httpPost.setConfig(requestConfig);
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
builder.setCharset(Charset.forName("UTF-8"));
builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
builder.addTextBody("access_key", accessKey);
builder.addTextBody("sample_bytes", file.length() + "");
builder.addTextBody("timestamp", timestamp);
builder.addTextBody("signature", signature);
builder.addTextBody("data_type", dataType);
builder.addTextBody("signature_version", sigVersion);
builder.addBinaryBody("sample", file, ContentType.DEFAULT_BINARY, "sample");
HttpEntity entity = builder.build();
httpPost.setEntity(entity);
String responseStr = "";
try {
CloseableHttpResponse response = httpClient.execute(httpPost);
HttpEntity responseEntity = response.getEntity();
if (responseEntity != null) {
responseStr = EntityUtils.toString(responseEntity, StandardCharsets.UTF_8);
System.out.println("Result:" + responseStr);
}
} catch (IOException e) {
e.printStackTrace();
}
return responseStr;
}
public static void main(String[] args) {
Recognizer rec = new Recognizer();
String result = rec.recognizeByFile("x.mp3", "audio");
System.out.println(result);
}
}
javascript
var url = require('url');
var fs = require('fs');
var crypto = require('crypto');
//npm install request
var request = require('request');
// Replace "###...###" below with your project's host, access_key and access_secret.
var defaultOptions = {
host: '###YOUR_HOST###',
endpoint: '/v1/identify',
signature_version: '1',
data_type:'audio',
secure: true,
access_key: '###YOUR_ACCESS_KEY###',
access_secret: '###YOUR_ACCESS_SECRET###'
};
function buildStringToSign(method, uri, accessKey, dataType, signatureVersion, timestamp) {
return [method, uri, accessKey, dataType, signatureVersion, timestamp].join('\n');
}
function sign(signString, accessSecret) {
return crypto.createHmac('sha1', accessSecret)
.update(Buffer.from(signString, 'utf-8'))
.digest().toString('base64');
}
/**
* Identifies a sample of bytes
*/
function identify(data, options, cb) {
var current_data = new Date();
var timestamp = current_data.getTime()/1000;
var stringToSign = buildStringToSign('POST',
options.endpoint,
options.access_key,
options.data_type,
options.signature_version,
timestamp);
var signature = sign(stringToSign, options.access_secret);
var formData = {
sample: data,
access_key:options.access_key,
data_type:options.data_type,
signature_version:options.signature_version,
signature:signature,
sample_bytes:data.length,
timestamp:timestamp,
}
request.post({
url: "http://"+options.host + options.endpoint,
method: 'POST',
formData: formData
}, cb);
}
function identify_v2(data, options, cb) {
//npm install form-data
var FormData = require('form-data');
//npm install node-fetch
var fetch = require('node-fetch');
var current_data = new Date();
var timestamp = current_data.getTime()/1000;
var stringToSign = buildStringToSign('POST',
options.endpoint,
options.access_key,
options.data_type,
options.signature_version,
timestamp);
var signature = sign(stringToSign, options.access_secret);
var form = new FormData();
form.append('sample', data);
form.append('sample_bytes', data.length);
form.append('access_key', options.access_key);
form.append('data_type', options.data_type);
form.append('signature_version', options.signature_version);
form.append('signature', signature);
form.append('timestamp', timestamp);
fetch("http://"+options.host + options.endpoint,
{method: 'POST', body: form })
.then((res) => {return res.text()})
.then((res) => {cb(res, null)})
.catch((err) => {cb(null, err)});
}
var bitmap = fs.readFileSync('sample.wav');
identify(Buffer.from(bitmap), defaultOptions, function (err, httpResponse, body) {
if (err) console.log(err);
console.log(body);
});
ruby
require 'openssl'
require 'base64'
require 'net/http/post/multipart'
# Replace "###...###" below with your project's host, access_key and access_secret.
requrl = "http://###YOUR_HOST###/v1/identify"
access_key = "###YOUR_ACCESS_KEY###"
access_secret = "###YOUR_ACCESS_SECRET###"
http_method = "POST"
http_uri = "/v1/identify"
data_type = "audio"
signature_version = "1"
timestamp = Time.now.utc().to_i.to_s
string_to_sign = http_method+"\n"+http_uri+"\n"+access_key+"\n"+data_type+"\n"+signature_version+"\n"+timestamp
digest = OpenSSL::Digest.new('sha1')
signature = Base64.encode64(OpenSSL::HMAC.digest(digest, access_secret, string_to_sign))
file_name = ARGV[0]
sample_bytes = File.size(file_name)
url = URI.parse(requrl)
File.open(file_name) do |file|
req = Net::HTTP::Post::Multipart.new url.path,
"sample" => UploadIO.new(file, "audio/mp3", file_name),
"access_key" =>access_key,
"data_type"=> data_type,
"signature_version"=> signature_version,
"signature"=>signature,
"sample_bytes"=>sample_bytes,
"timestamp" => timestamp
res = Net::HTTP.start(url.host, url.port) do |http|
http.request(req)
end
puts(res.body)
end