语音转写

本文主要介绍语音转写的AI能力和实现方式。

语音转写是通义听悟的核心功能, 用以将音视频文件或实时音频流中的语音转写成文字。语音转写是通义听悟API服务链路中的第一个节点,必选其中的一种形式,无法禁用。支持中、英、粤、日等语种,可在转写参数中配置说话人分离功能。

请求参数

参数名

类型

是否必填

说明

Transcription

object

语音识别控制参数对象。

Transcription.DiarizationEnabled

boolean

是否在转写过程中开启发言人区分(说话人分离)功能。

Transcription.Diarization

object

说话人分离功能对象。

Transcription.Diarization.SpeakerCount

int

0:说话人角色区分结果为不定人数。

2:说话人角色区分结果为2人。

Transcription.PhraseId

string

热词词表ID。

Transcription.Model

string

语音转写模型选择,通过该参数可调用领域专属模型,用于提升特定领域的识别准确率,该参数为空时则调用默认模型。目前可选参数如下:

  • "domain-automotive":汽车领域销售对话语音识别模型,仅适用于离线转写任务;

  • "domain-education":教育领域网课场景语音识别模型,仅适用于离线转写任务;

  • 其他领域语音识别模型即将上线,敬请期待。

说明

Transcription.Model参数:通过该参数可调用领域专属模型,可用于提升特定领域的识别准确率。目前可选用的领域专属模型如下表所示:

模型名称

参数值

支持语言

采样率

实时/离线

适用场景

汽车领域销售对话语音识别模型

domain-automotive

中文

16k

离线

适用于汽车行业,包括门店接待、汽车试驾、车型推销等场景下的语音识别

教育领域网课场景语音识别模型

domain-education

中文

16k

离线

适用于教育行业,包括网课等场景下的语音识别

示例设置

// 完全不设置
{
    "Input":{
        ...
    },
    "Parameters":{

    }
}

// 设置开启说话人分离功能
{
    "Input":{
        ...
    },
    "Parameters":{
        "Transcription":{
            "DiarizationEnabled":true,
            "Diarization":{
                "SpeakerCount":2
            }
        }
    }
}

代码示例

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

import os
import json
import datetime
from aliyunsdkcore.client import AcsClient
from aliyunsdkcore.request import CommonRequest
from aliyunsdkcore.auth.credentials import AccessKeyCredential

def create_common_request(domain, version, protocolType, method, uri):
    request = CommonRequest()
    request.set_accept_format('json')
    request.set_domain(domain)
    request.set_version(version)
    request.set_protocol_type(protocolType)
    request.set_method(method)
    request.set_uri_pattern(uri)
    request.add_header('Content-Type', 'application/json')
    return request

def init_parameters():
    root = dict()
    root['AppKey'] = '输入您在听悟管控台创建的Appkey'

    # 基本请求参数
    input = dict()
    input['SourceLanguage'] = 'cn'
    input['TaskKey'] = 'task' + datetime.datetime.now().strftime('%Y%m%d%H%M%S')
    input['FileUrl'] = '输入待测试的音频url链接'
    root['Input'] = input

    # AI相关参数,按需设置即可
    parameters = dict()

    # 语音识别控制相关
    transcription = dict()
    # 角色分离
    transcription['DiarizationEnabled'] = True
    diarization = dict()
    diarization['SpeakerCount'] = 2
    transcription['Diarization'] = diarization
    parameters['Transcription'] = transcription

    root['Parameters'] = parameters
    return root

body = init_parameters()
print(body)

# TODO  请通过环境变量设置您的 AccessKeyId 和 AccessKeySecret
credentials = AccessKeyCredential(os.environ['ALIBABA_CLOUD_ACCESS_KEY_ID'], os.environ['ALIBABA_CLOUD_ACCESS_KEY_SECRET'])
client = AcsClient(region_id='cn-beijing', credential=credentials)

request = create_common_request('tingwu.cn-beijing.aliyuncs.com', '2023-09-30', 'https', 'PUT', '/openapi/tingwu/v2/tasks')
request.add_query_param('type', 'offline')

request.set_content(json.dumps(body).encode('utf-8'))
response = client.do_action_with_exception(request)
print("response: \n" + json.dumps(json.loads(response), indent=4, ensure_ascii=False))
package com.alibaba.tingwu.client.demo.aitest;
import com.alibaba.fastjson.JSONObject;
import com.aliyuncs.CommonRequest;
import com.aliyuncs.CommonResponse;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.http.FormatType;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.http.ProtocolType;
import com.aliyuncs.profile.DefaultProfile;
import org.junit.Test;

/**
 * @author tingwu2023
 */
public class TranscriptionTest {

    @Test
    public void testFiletrans() throws ClientException {
        CommonRequest request = createCommonRequest("tingwu.cn-beijing.aliyuncs.com", "2023-09-30", ProtocolType.HTTPS, MethodType.PUT, "/openapi/tingwu/v2/tasks");
        request.putQueryParameter("type", "offline");

        JSONObject root = new JSONObject();
        root.put("AppKey", "输入您在听悟管控台创建的Appkey");

        JSONObject input = new JSONObject();
        input.fluentPut("FileUrl", "输入待测试的音频url链接")
                .fluentPut("SourceLanguage", "cn")
                .fluentPut("TaskKey", "task" + System.currentTimeMillis());
        root.put("Input", input);

        JSONObject parameters = new JSONObject();
        JSONObject transcription = new JSONObject();
        transcription.put("DiarizationEnabled", true);
        JSONObject speakerCount = new JSONObject();
        speakerCount.put("SpeakerCount", 2);
        transcription.put("Diarization", speakerCount);
        parameters.put("Transcription", transcription);
        root.put("Parameters", parameters);
        System.out.println(root.toJSONString());
        request.setHttpContent(root.toJSONString().getBytes(), "utf-8", FormatType.JSON);

        // TODO 请通过环境变量设置您的AccessKeyId、AccessKeySecret
        DefaultProfile profile = DefaultProfile.getProfile("cn-beijing", System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"), System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"));
        IAcsClient client = new DefaultAcsClient(profile);
        CommonResponse response = client.getCommonResponse(request);
        System.out.println(response.getData());
    }
  
    public static CommonRequest createCommonRequest(String domain, String version, ProtocolType protocolType, MethodType method, String uri) {
        // 创建API请求并设置参数
        CommonRequest request = new CommonRequest();
        request.setSysDomain(domain);
        request.setSysVersion(version);
        request.setSysProtocol(protocolType);
        request.setSysMethod(method);
        request.setSysUriPattern(uri);
        request.setHttpContentType(FormatType.JSON);
        return request;
    }
}

示例输出

{
    "Code":"0",
    "Data":{
        "TaskId":"10683ca4ad3f4f06bdf6e9dd********",
        "TaskStatus":"COMPLETED",
        "Result":{
            "Transcription":"http://speech-swap.oss-cn-zhangjiakou.aliyuncs.com/tingwu_data/output/1738248129743478/10683ca4ad3f4f06bdf6e9dc1f3c1584/10683ca4ad3f4f06bdf6e9dc1f3c1584_Transcription_20231031165005.json?Expires=1698828606&OSSAccessKeLTAI4G4uXHLPwQHj6oX8****nt5S&Signature=GMm%2BdN2tUPx*********ehu74%3D"
        }
    },
    "Message":"success",
    "RequestId":"7a63ee43-8a35-4ef2-8d5c-c76*********"
}

其中Transcription字段对应的即为语音转写结果的http url下载链接。

协议解析

上述输出中的语音转写结果url中的内容为JSON格式的报文,示例如下所示。(实时转写结果中不包含AudioInfo中的Size、SampleRate和Language字段)

{
    "TaskId":"10683ca4ad3f4f06bdf6e9dc*********",
    "Transcription":{
        "AudioInfo": {
            "Size": 670663,
            "Duration": 10394,
            "SampleRate": 48000,
            "Language": "cn"
        },
        "Paragraphs":[
            {
                "ParagraphId":"16987422100275*******",
                "SpeakerId":"1",
                "Words":[
                    {
                        "Id":10,
                        "SentenceId":1,
                        "Start":4970,
                        "End":5560,
                        "Text":"您好,"
                    },
                    {
                        "Id":20,
                        "SentenceId":1,
                        "Start":5730,
                        "End":6176,
                        "Text":"我是"
                    }
                ]
            }
        ]
        "AudioSegments": [
            [12130, 16994],
            [17000, 19720],
            [19940, 28649]
        ]
    }
}

具体字段定义如下。

参数名

类型

说明

TaskId

string

创建任务时生成的TaskId。

Transcription

object

语音转写结果对象。

Transcription.Paragraphs

list[]

语音转写结构以段落形式组织的集合。

Transcription.Paragraphs[i].ParagraphId

string

段落级别id。

Transcription.Paragraphs[i].SpeakerId

string

发言人id。

Transcription.Paragraphs[i].Words

list[]

该段落包含的word信息。

Transcription.Paragraphs[i].Words[i].Id

int

word序号,通常无须关注。

Transcription.Paragraphs[i].Words[i].SentenceId

int

句子id,同属于一个SentenceId的word信息可以组装成一句话。

Transcription.Paragraphs[i].Words[i].Start

long

该word相对于音频起始时间的开始时间,相对时间戳,单位毫秒。

Transcription.Paragraphs[i].Words[i].End

long

该word相对于音频起始时间的结束时间,相对时间戳,单位毫秒。

Transcription.Paragraphs[i].Words[i].Text

string

word文本。

Transcription.AudioInfo

object

音频信息对象。

Transcription.AudioInfo.Size

long

音频大小,单位:字节。

Transcription.AudioInfo.Duration

long

音频时长,单位:毫秒。(实时语音转写时,该字段不表示实际音频时长)

Transcription.AudioInfo.SampleRate

int

音频采样率。

Transcription.AudioInfo.Language

string

音频语种。

Transcription.AudioSegments

list[][]

有效音频片断范围。

Transcription.AudioSegments[i][0]

int

有效音频片段的开始时间,单位为毫秒。

Transcription.AudioSegments[i][1]

int

有效音频片段的结束时间,单位为毫秒。

常见问题

上传一个文件,为什么识别结果为空?

您可以检查原始音视频文件是否存在有效人声、背景噪音过多等问题。