Skip to content

识别 API

TIP

  • 使用此接口时需要指定 Content-Type 为 "multipart/form-data"
  • 本接口同时支持识别指纹和音频
  • 我们建议使用指纹来识别,这会减小带宽并且会加快识别的速度
  • 我们建议识别的内容小于 12 秒, 且接口只会识别前 12 秒内容,多余的部分将会被丢弃。

接口和参数

API 地址:identify-cn-north-1.acrcloud.cn/v1/identify

请求方法: POST

参数:

参数名类型描述
sampleobject音频或者指纹文件的内容
sample_bytesstring音频或者指纹文件的大小
access_keystring控制台中的 access_key
timestampstring时间戳
data_typestringaudio 或者 fingerprint
signature_versionnumber1
signaturestring请求签名,用于合法性校验。

以下是签名的示例代码,您可以参考以下代码编写签名。

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