logo
电话400 898 2016
预约试用
开放平台
En
尊敬的开发者,您好! 标贝科技的开发文档已更换新的地址,旧版文档地址将会在2023年12月31日下线, 给您带来不便,敬请谅解! 立即查看
产品简介 产品简介
基本概念 基本概念
平台新手指引 平台新手指引
计价模式 计价模式
开发者文档下拉
开放平台计价
定制服务计价
获取访问令牌 获取访问令牌
语音合成 语音合成
开发者文档下拉
接口说明
发音人列表
短文本合成 开发者文档下拉
Android SDK
iOS SDK
C++(Linux) SDK
RESTful API
Websocket API
长文本合成 开发者文档下拉
长文本合成RESTful API
长文本合成Websocket API
离线合成 开发者文档下拉
模型文件说明
离线合成(普通版) Android SDK
离线合成(普通版) iOS SDK
离线合成(精品版) Android SDK
离线合成(精品版) iOS SDK
XML标签
SSML标签
语音合成时间戳功能
语音识别 语音识别
开发者文档下拉
音频格式说明
一句话识别 开发者文档下拉
RESTful API
Websocket API
Android SDK
iOS SDK
实时长语音识别 开发者文档下拉
Websocket API
Android SDK
iOS SDK
录音文件识别 开发者文档下拉
RESTful API
自学习工具 开发者文档下拉
热词
个性化模型
声音复刻 声音复刻
开发者文档下拉
定制模型 开发者文档下拉
RESTful API
Android SDK
iOS SDK
定制声音合成 开发者文档下拉
短文本合成RESTful API
长文本合成Websocket API
声音转换 声音转换
开发者文档下拉
发音人列表
Websocket API
Android SDK
iOS SDK
离线声音转换 离线声音转换
开发者文档下拉
发音人列表
Android SDK
iOS SDK
声纹识别 声纹识别
开发者文档下拉
RESTful API
声音理解 声音理解
开发者文档下拉
RESTful API
协议规则 协议规则
开发者文档下拉
平台服务协议
平台通用规则
法律声明及隐私政策
服务等级协议SLA
常见问题 常见问题
开发者文档下拉
语音合成
语音识别

录音文件识别Restful API

功能介绍

录音文件识别时针对已经录制的音频文件,进行文字转写。录音文件识别是非实时的,通过接口提交录音文件或可以直接下载的文件URL,系统接收后进行识别转文字。

录音文件识别采用异步调用(非实时),音频文件上传成功后进入等待队列,识别成功后可以采用主动轮询或者回调的方式获得识别结果,返回结果时间受音频时长以及排队任务量的影响。 如遇识别耗时比平时延长,大概率表示当前时间段出现识别高峰,请耐心等待,免费用户在24小时内完成并返回识别结果;付费用户在3小时内完成并返回识别结果。

音频要求

  • 直接上传音频数据方式一次最多不能超过64MB
  • 通过提交音频URL方式文件大小不超过512MB
  • 单声道:wav,pcm,mp3,ogg,flac
  • 双声道:wav,mp3,ogg,flac
  • 音频采样率:8000Hz,16000Hz(音频采样率如果大于16000,会强制降采样到参数指定采样率,再进行识别)
  • 位深:16bits

使用方法

1. 创建账号和应用,详见平台新手指引,通过标贝开放平台/应用/服务获取client_id,client_secret

2. 发送请求获取access_token,详见获取访问令牌

3. 发送新建任务请求:发送新建任务请求,具体参数详见请求参数

4. 接收返回结果:发送请求成功后会立即收到返回响应,采用JSON格式封装,在“taskid"字段中获取任务id,具体参数详见新建任务响应结果

5. 发送查询识别结果请求:使用“taskid”发送查询识别结果请求,具体参数详见查询识别结果

6. 接收识别结果:发送请求成功后会立即收到返回响应,采用JSON格式封装,识别结果在“text"字段内,具体参数详见响应识别结果

服务地址

访问类型 说明 URL Host
外网访问 新建任务 https://openapi.data-baker.com/asr/starttask? openapi.data-baker.com
外网访问 查询结果
(主动轮询)
https://openapi.data-baker.com/asr/taskresult? openapi.data-baker.com

交互流程

1. 主动轮询 2. 回调通知

测试音频

测试音频

请求参数

1. 请求headers
参数名称 名称 是否必填 说明
access_token String Yes 通过client_id,client_secret调用授权服务获得见获取访问令牌
file_url String No 录音文件URL,外网可访问。 如未指定该参数,则把音频方与请求体中上传
callback_url String No 识别结果回调URL
如有,则识别结束后通过回调通知
否则,则通过查询结果进行轮询
channel Integer No 录音文件声道数
1:单声道
2:双声道
audio_format String Yes 音频格式
单声道:wav,pcm,mp3,ogg,flac
双声道:wav,mp3,ogg,flac
sample_rate String Yes 音频采样率支持
8000Hz
16000Hz
(音频采样率如果大于16000,会强制降采样到参数指定采样率,再进行识别)
domain String no 模型名称
16k采样率支持模型:
中文通用模型 "common",默认值
中英自由说模型 "cn-en-mixed"
英文模型 "english",
粤语模型 "cantonese",
维语模型 "uighur",
8k采样率支持模型:
中文客服模型 "kefu"
add_pct String no true: 加标点,默认值
false:不添加标点
hotwordid String no 配置的热词组的id
diylmid String no asr个性化模型的id
enable_itn String no 中文数字转换为阿拉伯数字(仅支持3位及以上数字串)
‘true’: 开启
‘false’: 关闭
auto_split String no 开启说话人分离(该功能处于测试阶段,支持2个说话人分离,效果持续优化中)
‘true’: 开启
‘false’: 关闭
2. 请求体

当未指定file_url参数时,请将二进制音频数据放到HTTP请求体中;

当指定file_url参数时,服务端将忽略HTTP请求体,并从指定的url处下载音频文件

请求示例

curl -X POST \
-H "access_token:xxxxxxxxxx" \
-H "audio_format:wav" \
-H "sample_rate:16000" \
--data-binary "@wav_16k.wav" \
"https://openapi.data-baker.com/asr/starttask?"

Python示例代码

代码地址:Github

Python3示例如下:

#!/usr/bin/env python
# coding: utf-8

import argparse
import time
import requests
import json


# 获取access_token用于鉴权
def get_access_token(client_secret, client_id):
    grant_type = "client_credentials"
    url = "https://openapi.data-baker.com/oauth/2.0/token?grant_type={}&client_secret={}&client_id={}".format(
        grant_type, client_secret, client_id)
    response = requests.post(url)
    access_token = json.loads(response.text).get('access_token')

    return access_token


# 查询识别结果
def get_text(headers):
    url = "https://asr.data-baker.com/asr/taskresult"
    response = requests.post(url, headers=headers)
    text = json.loads(response.text).get("text")
    code = json.loads(response.text).get("code")
    if code == 20000 or code == 20001 or code == 20005:
        return text
    else:
        raise Exception(response.text)


# 创建识别任务,发送识别文件
def create_task(file, headers):
    url = "https://asr.data-baker.com/asr/starttask?"
    response = requests.post(url, data=file, headers=headers)
    task_id = json.loads(response.text).get("taskid")
    code = json.loads(response.text).get("code")
    if code != 20000:
        raise Exception(response.text)

    return task_id


# 获取命令行输入参数
def get_args():
    parser = argparse.ArgumentParser(description='ASR')
    parser.add_argument('-client_secret', type=str, required=True)
    parser.add_argument('-client_id', type=str, required=True)
    parser.add_argument('-file_path', type=str, required=True)
    parser.add_argument('--audio_format', type=str, default='wav')
    parser.add_argument('--sample_rate', type=str, default='16000')
    args = parser.parse_args()

    return args


if __name__ == '__main__':
    try:
        args = get_args()

        # 获取access_token
        client_secret = args.client_secret
        client_id = args.client_id
        access_token = get_access_token(client_secret, client_id)

        # 新建任务
        file = open(args.file_path, 'rb')
        audio_format = args.audio_format
        sample_rate = args.sample_rate
        headers = {'access_token': access_token, 'audio_format': audio_format, 'sample_rate': sample_rate, 'domain': 'common'}
        task_id = create_task(file, headers)


        # 主动轮询查询识别结果
        recognition_headers = {'access_token': access_token, 'taskid': task_id}
        while True:
            text = get_text(recognition_headers)
            if text:
                break
            else:
                time.sleep(2)
                print('task is processing')
        print(text['left_result'])
    except Exception as e:
        print(e)

命令行执行: 默认wav格式,16000采样率

python audio_file_recognition.py -client_secret=你的client_secret -client_id=你的client_secret -file_path=test.wav

如有主要可自行修改参数

python audio_file_recognition.py -client_secret=你的client_secret -client_id=你的client_id -file_path=test.wav --audio_format=wavmple_rate=16000

PHP示例代码

<?php
//获取访问令牌
$client_secret = '***'; //应用secret
$client_id = '***'; //应用id
$grant_type = 'client_credentials'; //固定格式

//1.获取token
$url = 'https://openapi.data-baker.com/oauth/2.0/token?grant_type='.$grant_type.'&client_id='.$client_id.'&client_secret='.$client_secret;

//curl get请求
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); //信任任何证书
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); // 检查证书中是否设置域名,0不验证
$token_res = curl_exec($ch);

//如果错误 查看错误信息
if(curl_errno($ch))
{
    print curl_error($ch);
}
curl_close($ch);

//进行token信息解析
$token_info = json_decode($token_res,1);
$access_token = $token_info['access_token'];    //获取到的token信息
//var_dump($access_token);die;
//$access_token = '***';

//2.录音文件新建任务 说明(支持录音文件url方式,支持识别结果回调方式。本demo采用本地文件发送请求体识别,主动轮询识别结果方式。)
$url = 'https://openapi.data-baker.com/asr/starttask?';

//curl post请求
$audio_format = 'wav';  //音频格式
$sample_rate = 16000;   //采样率
$Content_Type = 'application/json; charset=utf-8';
$headers = array(
    'access_token:'.$access_token,
    'audio_format:'.$audio_format,
    'sample_rate:'.$sample_rate,
    'Content-Type:'.$Content_Type
);

$file_path = './test.wav';
//第一种方式读取
$post_audio = file_get_contents($file_path);

//第二种方式读取
//$file_size = filesize($file_path);
//$post_audio = fread(fopen($file_path, "r"), $file_size);

$ch = curl_init();
curl_setopt($ch, CURLINFO_HEADER_OUT, true);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_audio);
$audio_res = curl_exec($ch);

//$request_header = curl_getinfo($ch, CURLINFO_HEADER_OUT);

if(curl_errno($ch))
{
    print curl_error($ch);
}
curl_close($ch);

$audio_info = json_decode($audio_res,1);
$task_id = $audio_info['taskid'];    //新建任务后返回的全局唯一任务ID


//3.查询识别结果

function queryRes($access_token,$task_id){
    sleep(10);   //等待10s后查询识别结果(可以队列方式)
    $url = 'https://openapi.data-baker.com/asr/taskresult?';

    //curl post请求
    $Content_Type = 'application/json; charset=utf-8';
    $headers = array(
        'access_token:'.$access_token,
        'taskid:'.$task_id,
        'Content-Type:'.$Content_Type
    );

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    $result = curl_exec($ch);
    if(curl_errno($ch))
    {
        print curl_error($ch);
    }
    curl_close($ch);

    $result_info = json_decode($result,1);

    //如果响应结果不成功递归调用
    if($result_info['code']!=20000){
        queryRes($access_token,$task_id);
    }else{
        $text = $result_info['text'];    //录音文件识别结果 json 类型
        var_dump($text);die;
    }
}

queryRes($access_token,$task_id);

C示例代码

代码地址:Github

JAVA示例代码

package com.databaker.web.asr;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import okhttp3.*;
import org.apache.commons.lang3.StringUtils;

import java.io.File;
import java.io.FileInputStream;


/**
 * 录音文件识别RESTFUL API接口调用示例
 * 附:录音文件识别RESTFUL API文档 【https://www.data-baker.com/specs/file/asr_file_api_restful】
 *
 * 注意:
 * 1.仅作为demo示例,失败重试、token过期重新获取、日志打印等优化工作需要开发者自行完成
 * 2.录音文件识别中的录音文件有两种提交方式:A.在header中通过音频下载链接方式提交 B.在body中通过音频文件流方式提交。服务端优先使用方式A提供的音频。
 * 3.录音文件识别是非实时接口,提供了两种方式获取结果:A.开发者提供回调接口 B.开发者主动查询进度接口。开发者可自由选择,主动查询时注意频率不要太高。
 *
 * @author data-baker
 */
public class AsrFileRestApiDemo {
    /**
     * 授权:需要在开放平台获取【https://ai.data-baker.com/】
     */
    private static final String clientId = "YOUR_CLIENT_ID";
    private static final String clientSecret = "YOUR_CLIENT_SECRET";

    /**
     * 获取token的地址信息
     */
    public static String tokenUrl = "https://openapi.data-baker.com/oauth/2.0/token?grant_type=client_credentials&client_secret=%s&client_id=%s";
    /**
     * 录音文件识别API地址
     */
    public static String asrSubmitTaskUrl = "https://openapi.data-baker.com/asr/starttask";
    /**
     * 录音文件识别API地址
     */
    public static String asrQueryTaskUrl = "https://openapi.data-baker.com/asr/taskresult";
    /**
     * 文件流方式上传音频,最大支持64M;音频URL方式上传,最大支持512M
     */
    public static Integer MAX_FILE_SIZE = 64 * 1024 * 1024;

    /**
     * 仅作为demo示例
     * 失败重试、token过期重新获取、日志打印等优化工作需要开发者自行完成
     **/
    public static void main(String[] args) {
        String accessToken = getAccessToken();
        if (StringUtils.isNotEmpty(accessToken)) {
            //支持两种上传音频方式:url或文件流;支持三种音频格式:pcm、wav、mp3
            //1.url方式
            //String audioFileInfo = "YOUR_AUDIO_FILE_URL";
            //String taskId = submitFileAsrTask(accessToken, audioFileInfo, AudioFileTypeEnum.UrlType, "mp3", 16000, "");

            //2.文件流方式
            String audioFileInfo = "YOUR_AUDIO_FILE_FULL_PATH";
            String taskId = submitFileAsrTask(accessToken, audioFileInfo, AudioFileTypeEnum.FileType, "pcm", 16000, "");

            //查询识别结果
            try {
                if (StringUtils.isNotEmpty(taskId)) {
                    Thread.sleep(10 * 1000);
                    queryFileAsrTaskResult(accessToken, taskId);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 提交录音文件识别任务
     */
    public static String submitFileAsrTask(String accessToken, String audioFileInfo, AudioFileTypeEnum fileType, String audioFormat, Integer sampleRate, String callback_url) {
        try {
            OkHttpClient client = new OkHttpClient();
            MediaType mediaType = MediaType.parse("application/octet-stream");
            //requestBody默认为空
            RequestBody requestBody = RequestBody.create(null, new byte[0]);
            //如果以文件流方式上传,文件流放在requestBody里面
            if (AudioFileTypeEnum.FileType.equals(fileType)) {
                File audioFile = new File(audioFileInfo);
                if (!audioFile.exists() || audioFile.length() > MAX_FILE_SIZE) {
                    return "";
                }
                FileInputStream in = new FileInputStream(audioFile);
                byte[] fileByte = new byte[(int) audioFile.length()];
                int realLen = in.read(fileByte);
                //确保音频文件内容全部被读取
                if (realLen == (int) audioFile.length()) {
                    requestBody = RequestBody.create(mediaType, fileByte);
                }
            }
            //构造完整request
            Request request = new Request.Builder()
                    .url(asrSubmitTaskUrl)
                    .addHeader("access_token", accessToken)
                    .addHeader("file_url", AudioFileTypeEnum.UrlType.equals(fileType) ? audioFileInfo : "")
                    .addHeader("audio_format", audioFormat)
                    .addHeader("sample_rate", String.valueOf(sampleRate))
                    .addHeader("domain", "common")
                    .addHeader("callback_url", callback_url)
                    .method("POST", requestBody)
                    .build();
            Response response = client.newCall(request).execute();
            if (response.isSuccessful()) {
                JSONObject jsonObject = JSON.parseObject(response.body().string());
                System.out.println("提交识别任务成功,任务id:" + (jsonObject == null ? "" : jsonObject.getString("taskid")));
                return jsonObject == null ? "" : jsonObject.getString("taskid");
            } else {
                System.out.println("提交识别任务失败,错误信息:" + response.body().string());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "";
    }

    /**
     * 查询录音文件识别任务的结果
     */
    public static void queryFileAsrTaskResult(String accessToken, String taskId) {
        try {
            OkHttpClient client = new OkHttpClient();
            //requestBody默认为空
            RequestBody requestBody = RequestBody.create(null, new byte[0]);
            Request request = new Request.Builder()
                    .url(asrQueryTaskUrl)
                    .addHeader("access_token", accessToken)
                    .addHeader("taskid", taskId)
                    .method("POST", requestBody)
                    .build();
            Response response = client.newCall(request).execute();
            if (response.isSuccessful()) {
                JSONObject jsonObject = JSON.parseObject(response.body().string());
                // 返回的结构开发者可参考接口文档【https://www.data-baker.com/specs/file/asr_file_api_restful】中的“响应识别结果”部分。
                // 本demo测试时使用的是单声道音频,故仅获取left_result作为示例。开发者请根据音频情况自行解析。
                if (jsonObject == null) {
                    System.out.println("查询识别任务成功,结果信息:null");
                } else {
                    jsonObject = jsonObject.getJSONObject("text");
                    System.out.println("查询识别任务成功,结果信息:" + (jsonObject == null ? "null" : jsonObject.getString("left_result")));
                }
            } else {
                System.out.println("查询识别任务失败,错误信息:" + response.body().string());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static String getAccessToken() {
        String accessToken = "";
        OkHttpClient client = new OkHttpClient();
        //request 默认是get请求
        String url = String.format(tokenUrl, clientSecret, clientId);
        Request request = new Request.Builder().url(url).build();
        JSONObject jsonObject;
        try {
            Response response = client.newCall(request).execute();
            if (response.isSuccessful()) {
                //解析
                String resultJson = response.body().string();
                jsonObject = JSON.parseObject(resultJson);
                accessToken = jsonObject.getString("access_token");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return accessToken;
    }

    public enum AudioFileTypeEnum {
        UrlType(1),
        FileType(2);

        private int type;

        AudioFileTypeEnum(int type) {
            this.type = type;
        }
    }
}

      

GO示例代码

package main

import (
	"bytes"
	"encoding/json"
	"errors"
	"flag"
	"fmt"
	"io/ioutil"
	"net/http"
	"net/url"
	"os"
	"strconv"
	"time"
)

type AuthInfo struct {
	AccessToken string `json:"access_token"`
	ExpiresIn   int    `json:"expires_in"`
	Scope       string `json:"scope"`
}
type ReqTtsParams struct {
	AccessToken string
	AudioFormat string
	SampleRate  int
	domain      string
	hotwordId   string
	diylmId     string
	Channel     int
}

type Response struct {
	Code    int    `json:"code"`
	Taskid  string `json:"taskid"`
	TraceId string `json:"trace_id"`
}

type RecognitionText struct {
	LeftResult  string `json:"left_result"`
	RightResult string `json:"right_result"`
}

type RecognitionResult struct {
	Code    int             `json:"code"`
	Taskid  string          `json:"taskid"`
	TraceId string          `json:"trace_id"`
	Info    string          `json:"info"`
	Text    RecognitionText `json:"text"`
}

const grantType string = "client_credentials"

func GetToken(reqUrl, clientId, clientSecret string) (string, error) {
	// 超时时间:60秒
	client := &http.Client{Timeout: 60 * time.Second}
	urlParams := url.Values{}
	urlParams.Add("grant_type", grantType)
	urlParams.Add("client_id", clientId)
	urlParams.Add("client_secret", clientSecret)
	httpUrl := reqUrl
	httpUrl += "?"
	httpUrl += urlParams.Encode()
	fmt.Printf("httpUrl: %s\n\n", httpUrl)
	resp, err := client.Get(httpUrl)
	if err != nil {
		fmt.Printf("send http get token request failed, err: %s\n", err)
		return "", err
	}
	defer resp.Body.Close()
	result, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		fmt.Printf("http get token request, readall body failed, err: %s\n", err)
		return "", err
	}
	authInfo := AuthInfo{}
	err = json.Unmarshal(result, &authInfo)
	if err != nil {
		fmt.Printf("auth info json.Unmarshal err: %s \n", err)
		return "", err
	}
	if len(authInfo.AccessToken) <= 0 {
		return "", errors.New("access token is null")
	}
	fmt.Printf("get token success. info: %#v \n", authInfo)
	return authInfo.AccessToken, nil
}

func CreateTask(reqUrl, file string, reqParam ReqTtsParams) (string, error) {
	// 超时时间:60秒
	client := &http.Client{Timeout: 60 * time.Second}
	fmt.Printf("reqUrl: %s\n\n", reqUrl)
	fileContent, err := ioutil.ReadFile(file)
	if err != nil {
		return "", err
	}
	req, err := http.NewRequest(http.MethodPost, reqUrl, bytes.NewReader(fileContent))
	if err != nil {
		return "", err
	}
	req.Header.Add("access_token", reqParam.AccessToken)
	req.Header.Add("audio_format", reqParam.AudioFormat)
	req.Header.Add("sample_rate", strconv.Itoa(reqParam.SampleRate))
	if len(reqParam.domain) > 0 {
		req.Header.Add("domain", reqParam.domain)
	}
	if len(reqParam.hotwordId) > 0 {
		req.Header.Add("hotwordid", reqParam.hotwordId)
	}
	if len(reqParam.diylmId) > 0 {
		req.Header.Add("diylmid", reqParam.diylmId)
	}
	if reqParam.Channel > 0 {
		req.Header.Add("channel", strconv.Itoa(reqParam.Channel))
	}
	resp, err := client.Do(req)
	if err != nil {
		fmt.Printf("send http request failed, err: %s \n", err)
		return "", err
	}
	defer resp.Body.Close()
	if resp.StatusCode != 200 {
		fmt.Printf("send http request return status code != 200\n")
		return "", errors.New("status code is not 200")
	}
	result, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		fmt.Printf("readall http body failed, err: %s \n", err)
		return "", err
	}
	response := Response{}
	if err = json.Unmarshal(result, &response); err != nil {
		return "", err
	}
	if response.Code != 20000 {
		return string(result), errors.New("request failed code != 20000")
	}

	return response.Taskid, nil
}

func QueryResult(reqUrl, taskId, access_token string) (int, error) {
	client := &http.Client{Timeout: 60 * time.Second}
	req, err := http.NewRequest(http.MethodPost, reqUrl, nil)
	if err != nil {
		return 0, err
	}
	req.Header.Add("access_token", access_token)
	req.Header.Add("taskid", taskId)
	resp, err := client.Do(req)
	if err != nil {
		return 0, err
	}
	defer resp.Body.Close()
	if resp.StatusCode != 200 {
		fmt.Printf("send http request return status code != 200\n")
		return 0, errors.New("status code is not 200")
	}
	resultJson, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		fmt.Printf("readall http body failed, err: %s \n", err)
		return 0, err
	}
	result := RecognitionResult{}
	if err = json.Unmarshal(resultJson, &result); err != nil {
		return 0, err
	}
	if 20000 != result.Code {
		return result.Code, fmt.Errorf("code:%d, traceId:%s info:%s", result.Code, result.TraceId, result.Info)
	}
	fmt.Printf("code:\t\t%d\ntraceId:\t%s\nleft_result:\t%s\nright_result:\t%s\n",
		result.Code, result.TraceId, result.Text.LeftResult, result.Text.RightResult)
	return result.Code, nil
}

func main() {
	var (
		clientId, clientSecret, file, audio_format, domain string
		sample_rate, channel                               int
	)
	flag.StringVar(&clientId, "cid", "", "client id")
	flag.StringVar(&clientSecret, "cs", "", "client secret")
	flag.StringVar(&file, "f", "", "识别文件")
	flag.IntVar(&sample_rate, "sample_rate", 16000, "音频采样率")
	flag.IntVar(&channel, "channel", 1, "录音文件声道数")
	flag.StringVar(&domain, "domain", "", "模型名称")
	flag.StringVar(&audio_format, "audio_format", "wav", "音频格式")
	flag.Parse()
	if len(os.Args) < 2 {
		flag.Usage()
		return
	}
	if len(clientId) <= 0 || len(clientSecret) <= 0 || len(file) <= 0 || len(audio_format) <= 0 {
		fmt.Println("parameter error!!!")
		return
	}
	// 获取令牌
	accessToken, err := GetToken("https://openapi.data-baker.com/oauth/2.0/token",
		clientId,
		clientSecret,
	)
	if err != nil {
		fmt.Println("get access token failed!!!! please check your client_id and client_secret.")
		return
	}
	param := ReqTtsParams{
		AccessToken: accessToken,
		SampleRate:  sample_rate,
		AudioFormat: audio_format,
		Channel:     channel,
		domain:      domain,
	}
	// 创建识别任务
	result, err := CreateTask("https://openapi.data-baker.com/asr/starttask?", file, param)
	if err != nil {
		fmt.Printf("send request failed. result: %s \n", result)
		return
	}
	fmt.Printf("create task success. traceId: %s\n", result)
	for {
		// 查询识别结果
		code, err := QueryResult("https://openapi.data-baker.com/asr/taskresult?", result, accessToken)
		if err == nil {
			break
		}
		if code != 20001 && code != 20005 {
			fmt.Printf("query result failed. error: %s\n", err.Error())
			break
		}
		fmt.Printf("query result failed. %s\n", err.Error())
		time.Sleep(time.Second)
	}
	fmt.Println("request finish...")
}

新建任务响应结果

字段名 描述
trace_id 日志id,如遇到问题,可反馈此id给开发,用于跟踪问题
code 请求结果码,请参考错误码一节
info 任务结果描述,如请求失败请根据该字段内容分析问题
taskid 任务id,后面请求方可携带此taskid去查询是否识别结束
1. 请求成功
{
    "trace_id":" 1571988259683020 ",
    "code":20000,
    "info":"Success",
    "taskid":" f0c58fc9************90e3ebfdb653"
}
2. 请求失败
{
    "trace_id":" 1571988883381595 ",
    "code":40007,
    "info":"Invalid body"
}

查询识别结果

参数名称 类型 是否必填 说明
access_token String Yes 通过client_id,client_secret调用授权服务获得见获取访问令牌
taskid string yes 识别任务的taskid
curl -X POST \
-H "access_token:xxxxxxxxxx" \
-H "taskid:f0c58fc9************90e3ebfdb653" \
"https://openapi.data-baker.com/asr/taskresult" 

响应结果参数

回调通知或主动查询得到识别结果,json格式返回。
字段名 类型 描述
trace_id string 日志id,如遇到问题,可反馈此id给开发,用于跟踪问题
code int 请求结果码,请参考错误码一节
info string 任务结果描述,如请求失败请根据该字段内容分析问题
text jsonObject 识别结果,josn对象,任务失败则为空
taskid string 任务id,后面请求方可携带此taskid去查询是否识别结束
left_duration int 左声道时长,单位:ms
right_duration int 右声道时长,单位:ms

text内部结构:

字段名 类型 描述
left_result_array jsonArray 左声道分段识别结果
right_result_array jsonArray 右声道分段识别结果
left_result string 左声道全部识别结果
right_result string 右声道全部识别结果

left_result_array和right_result_array内部结构:

参数名称 类型 描述
result string 识别结果
text string 语音识别结果,失败时为空
confidence string 整句置信度[0-100],值越大表示置信度越高。
speed int 语速,取值[0-2000]
speakerid int 说话人id,开启后值为1和2,关闭后值为-1
sos string 该句在音频中的绝对开始时间点 单位:秒
eos string 该句在音频中的绝对结束时间点 单位:秒
segment_code int 分段任务code,暂时固定为 20000,忽略该字段
speed_label string 语速标签:
15以下:FAST 快
15-30 : MEDIUM 适中
30-2000:SLOW 慢
volume int 音量,取值[0-100]
volume_label string 音量标签:
SILENT:0-15 静音
XSOFT:15-30 音量很小
SOFT:30-50 音量小
MEDIUM:50-70 音量适中
LOAD:70-85 音量大
XLOUD:85-100 音量很大
words array 词级别识别结果

words内部结构:

字段名 类型 描述
confidence string 词置信度[0-1],值越大表示置信度越高。
sos string 词在音频中的绝对开始时间点 单位:秒
eos string 词在音频中的绝对结束时间点 单位:秒
word string

响应结果示例

{
    "code": 20000,
    "info": "Success",
    "left_duration": 4992,
    "right_duration": 4992,
    "taskid": "1b3eb3b4-9a04-4804-87af-170bffdd21bf",
    "text": {
        "left_result": "欢迎使用标贝科技开放平台。",
        "left_result_array": [
            {
                "confidence": "58.33",
                "eos": "4.42",
                "result": "欢迎使用标贝科技开放平台。",
                "segment_code": 20000,
                "sos": "0.38",
                "speed": 33,
                "speakerid": -1,
                "speedlabel": "SLOW",
                "success": "yes",
                "volume": 43,
                "volume_label": "SOFT",
                "words": [
                    {
                        "confidence": "0.33",
                        "eos": "1.52",
                        "sos": "1.07",
                        "word": "欢迎"
                    },
                    {
                        "confidence": "0.67",
                        "eos": "2.06",
                        "sos": "1.52",
                        "word": "使用"
                    },
                    {
                        "confidence": "0.50",
                        "eos": "2.53",
                        "sos": "2.06",
                        "word": "标贝"
                    },
                    {
                        "confidence": "0.50",
                        "eos": "2.96",
                        "sos": "2.53",
                        "word": "科技"
                    },
                    {
                        "confidence": "0.50",
                        "eos": "3.41",
                        "sos": "2.96",
                        "word": "开放"
                    },
                    {
                        "confidence": "1.00",
                        "eos": "4.38",
                        "sos": "3.41",
                        "word": "平台"
                    }
                ]
            }
        ],
        "right_result": "欢迎使用标贝科技开放平台。",
        "right_result_array": [
            {
                "confidence": "58.33",
                "eos": "4.42",
                "result": "欢迎使用标贝科技开放平台。",
                "segment_code": 20000,
                "sos": "0.38",
                "speed": 33,
                "speakerid": -1,
                "speed_label": "SLOW",
                "success": "yes",
                "volume": 43,
                "volume_label": "SOFT",
                "words": [
                    {
                        "confidence": "0.33",
                        "eos": "1.52",
                        "sos": "1.07",
                        "word": "欢迎"
                    },
                    {
                        "confidence": "0.67",
                        "eos": "2.06",
                        "sos": "1.52",
                        "word": "使用"
                    },
                    {
                        "confidence": "0.50",
                        "eos": "2.53",
                        "sos": "2.06",
                        "word": "标贝"
                    },
                    {
                        "confidence": "0.50",
                        "eos": "2.96",
                        "sos": "2.53",
                        "word": "科技"
                    },
                    {
                        "confidence": "0.50",
                        "eos": "3.41",
                        "sos": "2.96",
                        "word": "开放"
                    },
                    {
                        "confidence": "1.00",
                        "eos": "4.38",
                        "sos": "3.41",
                        "word": "平台"
                    }
                ]
            }
        ]
    },
    "trace_id": "1652152016088962"
}

回调通知

录音文件识别支持回调接口发送识别结果,在调用创建任务接口时,填写callback_url可以将识别结果直接发送到该接口。(如果长时间未收到回调通知,仍可以根据taskid调用识别接口进行查询)

回调通知Python3示例代码

from flask import Flask, request
import json


app = Flask(__name__)


@app.route("/", methods=['GET', 'POST'])
def get_text():
    with open('test.txt', 'w') as f:
        text = json.loads(request.get_data())['text']['left_result']
        f.write(text)
    return "finished"

将上述代码保存为server.py

命令行执行

export FLASK_APP=server
flask run -p 端口号 --host=服务器IP

回调示例

{'left_result': '欢迎使用标贝科技开放平台!', 'left_result_array': [{'eos': '4.97', 'result': '欢迎使用标贝科技开放平台!', 'segment_code': 20000, 'sos': '0.23', 'success': 'yes'}]}

错误码

code 描述 解决方案
20000 请求成功
20001 任务正在处理 等待10分钟再查询
20002 taskid无效 使用新建识别任务时返回的taskid
20005 任务在队列中等待被调度执行 之前任务结束后自动进行
20006 音频分割后,部分识别失败 重新发送识别请求,或联系技术人员
20007 音频分割后,全部识别失败 重新发送识别请求,或联系技术人员
30001 HTTP请求参数错误 服务器内部错误,提交traceid,标贝后台进行排查。
30002 服务内部错误
30003 识别结果解析出错
30004 应用包名未知
30005 语音质量问题
30006 输入语音过长
30007 连接识别引擎失败
30008 会话id不存在
30009 Rpc调用非法
30010 redis rpop操作返回空
30011 redis rpop值不合法
30012 rpc调用识别引擎失败
30013 Redis rpop操作失败
30014 redis lpush操作失败
30015 单个语音分片过长
30016 回调url失败
50002 内部rpc调用失败
50009 其他内部错误