适用于短音频的语音转文本 REST API

适用于短音频的语音转文本 REST API 的适用场景有限。 仅在无法使用语音 SDK 的情况下使用它。

在使用适用于短音频的语音转文本 REST API 之前,请考虑以下限制:

在使用适用于短音频的语音转文本 REST API 之前,你需要在身份验证过程中完成令牌交换才能访问该服务,请悉知。 有关详细信息,请参阅身份验证

区域和终结点

适用于短音频的 REST API 的终结点具有以下格式:

https://<REGION_IDENTIFIER>.stt.speech.azure.cn/speech/recognition/conversation/cognitiveservices/v1

<REGION_IDENTIFIER> 替换为与语音资源所在区域匹配的标识符。

注意

对于由世纪互联运营的 Microsoft Azure 终结点,请参阅这篇关于主权云的文章

音频格式

在 HTTP POST 请求的正文中发送音频。 它必须采用下表中的格式之一:

格式 编解码器 比特率 采样速率
WAV PCM 256 kbps 16 kHz,单声道
OGG OPUS 256 kbps 16 kHz,单声道

注意

语音服务中适用于短音频的 REST API 和 WebSocket 支持上述格式。 语音 SDK 支持使用 PCM 编解码器的 WAV 格式以及其他格式

请求标头

下表列出了语音转文本请求的必需和可选标头:

标头 说明 必需还是可选
Ocp-Apim-Subscription-Key 语音服务的资源密钥。 此标头或 Authorization 是必需的。
Authorization 前面带有单词 Bearer 的授权令牌。 有关详细信息,请参阅身份验证 此标头或 Ocp-Apim-Subscription-Key 是必需的。
Pronunciation-Assessment 指定用于在识别结果中显示发音分数的参数。 这些分数评估语音输入的发音质量,并具有准确性、流畅性、完整性等指标。

此参数是 Base64 编码的 JSON,其中包含多个详细的参数。 若要了解如何生成此标头,请参阅发音评估参数
可选
Content-type 描述所提供音频数据的格式和编解码器。 接受的值为 audio/wav; codecs=audio/pcm; samplerate=16000audio/ogg; codecs=opus 必需
Transfer-Encoding 指定要发送分块的音频数据,而不是单个文件。 仅当要对音频数据进行分块时才使用此标头。 可选
Expect 如果使用分块传输,则发送 Expect: 100-continue。 语音服务将确认初始请求并等待更多数据。 如果发送分块的音频数据,则是必需的。
Accept 如果提供此标头,则值必须是 application/json。 语音服务以 JSON 格式提供结果。 某些请求框架提供不兼容的默认值。 最好始终包含 Accept 可选,但建议提供。

查询参数

可将以下参数包含在 REST 请求的查询字符串中。

注意

必须将语言参数追加到 URL 以避免收到 4xx HTTP 错误。 例如,通过“中国北部 2”终结点设置为美国英语的语言为:https://chinanorth2.stt.speech.azure.cn/speech/recognition/conversation/cognitiveservices/v1?language=en-US

参数 说明 必需还是可选
language 标识所要识别的口语。 请参阅支持的语言 必需
format 指定结果格式。 接受的值为 simpledetailed。 简单结果包括 RecognitionStatusDisplayTextOffsetDuration。 Detailed 响应包括显示文本的四种不同的表示形式。 默认设置为 simple 可选
profanity 指定如何处理识别结果中的不雅内容。 接受的值包括:

masked,以星号替代不雅内容。
removed,从结果中删除所有不雅内容。
raw,包含结果中的不雅内容。

默认设置为 masked
可选
cid 使用 Speech Studio 创建自定义模型时,可以利用“部署”页上的"终结点 ID" 值。 使用"终结点 ID" 值作为 cid 查询字符串形式参数的实际参数。 可选

发音评估参数

下表列出了发音评估的必需参数和可选参数:

参数 说明 必需还是可选
ReferenceText 用来对发音进行评估的文本。 必须
GradingSystem 用于分数校准的分数系统。 FivePoint 系统给出 0-5 的浮点分数,而 HundredMark 系统给出 0-100 的浮点分数。 默认值:FivePoint 可选
Granularity 评估粒度。 接受的值为:

Phoneme,它显示全文、单词和音素级别的分数。
Word,它显示全文和单词级别的分数。
FullText,它仅显示全文级别的分数。

默认设置为 Phoneme
可选
Dimension 定义输出条件。 接受的值为:

Basic,它只显示准确度分数。
Comprehensive,它显示更多维度的分数(例如,全文级别的流畅度分数和完整性分数、单词级别的错误类型)。

若要了解不同分数维度和单词错误类型的定义,请参阅响应属性。 默认设置为 Basic
可选
EnableMiscue 启用误读计算。 启用此参数后,会将发音的词与参考文本进行比较。 根据比较结果,将这些词标记为省略或插入。 接受的值为 FalseTrue。 默认设置为 False 可选
ScenarioId 一个 GUID,表示自定义分数系统。 可选

下面是一个示例 JSON,其中包含发音评估参数:

{
  "ReferenceText": "Good morning.",
  "GradingSystem": "HundredMark",
  "Granularity": "FullText",
  "Dimension": "Comprehensive"
}

下面的示例代码演示如何将发音评估参数构建到 Pronunciation-Assessment 标头中:

var pronAssessmentParamsJson = $"{{\"ReferenceText\":\"Good morning.\",\"GradingSystem\":\"HundredMark\",\"Granularity\":\"FullText\",\"Dimension\":\"Comprehensive\"}}";
var pronAssessmentParamsBytes = Encoding.UTF8.GetBytes(pronAssessmentParamsJson);
var pronAssessmentHeader = Convert.ToBase64String(pronAssessmentParamsBytes);

我们强烈建议在发布音频数据时进行流式(分块传输)上传,这可以显著减少延迟。 若要了解如何启用流式处理,请参阅不同编程语言的示例代码

备注

有关详细信息,请参阅发音评估

示例请求

以下示例包括主机名和必需的标头。 必须注意,服务同时预期提供音频数据,但此示例未包括这些数据。 如前所述,建议进行分块,但不是非要这样做。

POST speech/recognition/conversation/cognitiveservices/v1?language=en-US&format=detailed HTTP/1.1
Accept: application/json;text/xml
Content-Type: audio/wav; codecs=audio/pcm; samplerate=16000
Ocp-Apim-Subscription-Key: YOUR_RESOURCE_KEY
Host: chinanorth2.stt.speech.azure.cn
Transfer-Encoding: chunked
Expect: 100-continue

若要启用发音评估,可以添加以下标头。 若要了解如何生成此标头,请参阅发音评估参数

Pronunciation-Assessment: eyJSZWZlcm...

HTTP 状态代码

每个响应的 HTTP 状态代码指示成功或一般错误。

HTTP 状态代码 说明 可能的原因
100 继续 已接受初始请求。 继续发送剩余的数据。 (此代码与分块传输配合使用。)
200 OK 请求已成功。 响应正文为 JSON 对象。
400 错误的请求 未提供语言代码,语言不受支持,或音频文件无效(例如)。
401 未授权 指定区域中的资源密钥或授权令牌无效,或终结点无效。
403 禁止 缺少资源密钥或授权令牌。

示例响应

这是 simple 识别的典型响应:

{
  "RecognitionStatus": "Success",
  "DisplayText": "Remind me to buy 5 pencils.",
  "Offset": "1236645672289",
  "Duration": "1236645672289"
}

这是 detailed 识别的典型响应:

{
  "RecognitionStatus": "Success",
  "Offset": "1236645672289",
  "Duration": "1236645672289",
  "NBest": [
    {
      "Confidence": 0.9052885,
      "Display": "What's the weather like?",
      "ITN": "what's the weather like",
      "Lexical": "what's the weather like",
      "MaskedITN": "what's the weather like"
    },
    {
      "Confidence": 0.92459863,
      "Display": "what is the weather like",
      "ITN": "what is the weather like",
      "Lexical": "what is the weather like",
      "MaskedITN": "what is the weather like"
    }
  ]
}

这是使用发音评估进行识别的典型响应:

{
  "RecognitionStatus": "Success",
  "Offset": "400000",
  "Duration": "11000000",
  "NBest": [
      {
        "Confidence" : "0.87",
        "Lexical" : "good morning",
        "ITN" : "good morning",
        "MaskedITN" : "good morning",
        "Display" : "Good morning.",
        "PronScore" : 84.4,
        "AccuracyScore" : 100.0,
        "FluencyScore" : 74.0,
        "CompletenessScore" : 100.0,
        "Words": [
            {
              "Word" : "Good",
              "AccuracyScore" : 100.0,
              "ErrorType" : "None",
              "Offset" : 500000,
              "Duration" : 2700000
            },
            {
              "Word" : "morning",
              "AccuracyScore" : 100.0,
              "ErrorType" : "None",
              "Offset" : 5300000,
              "Duration" : 900000
            }
        ]
      }
  ]
}

响应属性

结果以 JSON 格式提供。 此 simple 格式包括以下顶级字段:

属性 说明
RecognitionStatus 状态,例如 Success 表示成功识别。 请参阅下表。
DisplayText 大写、标点符号、反向文本规范化和不雅内容屏蔽之后的已识别文本。 仅在成功时提供。 反向文本规范化是指将口述文本转换为较短的形式,例如 200 表示“two hundred”或 Dr. Smith 表示“doctor smith”。
Offset 在音频流中开始识别语音的时间(以 100 纳秒为单位)。
Duration 在音频流中识别语音的持续时间(以 100 纳秒为单位)。

RecognitionStatus 字段可能包含以下值:

状态 说明
Success 识别成功并且存在 DisplayText 字段。
NoMatch 在音频流中检测到语音,但没有匹配目标语言的字词。 此状态通常意味着识别语言与用户正在使用的语言不同。
InitialSilenceTimeout 音频流的开始仅包含静音,并且服务在等待语音时超时。
BabbleTimeout 音频流的开始仅包含噪音,并且服务在等待语音时超时。
Error 识别服务遇到内部错误,无法继续。 如果可能,请重试。

注意

如果音频仅包含亵渎内容,并且 profanity 查询参数设置为 remove,则服务不会返回语音结果。

detailed 格式包括更多形式的已识别结果。 使用 detailed 格式时,将以 Display 形式为 NBest 列表中的每条结果提供 DisplayText

NBest 列表中的对象可以包括:

属性 说明
Confidence 条目的置信度评分,从 0.0(完全不可信)到 1.0(完全可信)。
Lexical 已识别文本的词法形式:识别的实际单词。
ITN 已识别文本的反向文本规范化 (ITN) 或规范格式,已应用电话号码、数字、缩写(“doctor smith”缩写为“dr smith”)和其他转换。
MaskedITN 可根据请求提供应用了亵渎内容屏蔽的 ITN 形式。
Display 已识别文本的显示形式,其中添加了标点符号和大小写形式。 此参数与将格式设置为 simpleDisplayText 提供的内容相同。
AccuracyScore 语音的发音准确度。 准确度表示音素与母语人士发音的接近程度。 单词和全文级别的准确性分数是从音素级别的准确性分数聚合而来的。
FluencyScore 给定语音的流畅度。 流畅度表示语音与母语人士在单词之间使用无声停顿的接近程度。
CompletenessScore 语音的完整性,通过计算发音单词与参考文本输入的比率来确定。
PronScore 总分,表示给定语音的发音质量。 此分数按权重从 AccuracyScoreFluencyScoreCompletenessScore 聚合而成。
ErrorType 该值指示与 ReferenceText 相比,是省略、插入还是错误读出字词。 可能的值为 None(表示此词没有错误)、OmissionInsertionMispronunciation

分块传输

分块传输 (Transfer-Encoding: chunked) 有助于降低识别延迟。 它允许语音服务在传输音频文件时开始处理该文件。 适用于短音频的 REST API 不提供部分结果或临时结果。

以下代码示例演示如何以块的形式发送音频。 只有第一个区块应该包含音频文件的标头。 request 是连接到相应 REST 终结点的 HttpWebRequest 对象。 audioFile 是音频文件在磁盘上的路径。

var request = (HttpWebRequest)HttpWebRequest.Create(requestUri);
request.SendChunked = true;
request.Accept = @"application/json;text/xml";
request.Method = "POST";
request.ProtocolVersion = HttpVersion.Version11;
request.Host = host;
request.ContentType = @"audio/wav; codecs=audio/pcm; samplerate=16000";
request.Headers["Ocp-Apim-Subscription-Key"] = "YOUR_RESOURCE_KEY";
request.AllowWriteStreamBuffering = false;

using (var fs = new FileStream(audioFile, FileMode.Open, FileAccess.Read))
{
    // Open a request stream and write 1,024-byte chunks in the stream one at a time.
    byte[] buffer = null;
    int bytesRead = 0;
    using (var requestStream = request.GetRequestStream())
    {
        // Read 1,024 raw bytes from the input audio file.
        buffer = new Byte[checked((uint)Math.Min(1024, (int)fs.Length))];
        while ((bytesRead = fs.Read(buffer, 0, buffer.Length)) != 0)
        {
            requestStream.Write(buffer, 0, bytesRead);
        }

        requestStream.Flush();
    }
}

身份验证

每个请求都需要一个授权标头。 下表说明了每个功能支持的标头:

受支持的授权标头 语音转文本 文本到语音转换
Ocp-Apim-Subscription-Key
Authorization: Bearer

使用 Ocp-Apim-Subscription-Key 标头时,只需要提供你的资源密钥。 例如:

'Ocp-Apim-Subscription-Key': 'YOUR_SUBSCRIPTION_KEY'

在使用 Authorization: Bearer 标头时,需要向 issueToken 终结点发出请求。 在此请求中,用资源密钥交换一个有效期为 10 分钟的访问令牌。

如何获取访问令牌

若要获取访问令牌,需要通过使用 Ocp-Apim-Subscription-Key 和你的资源密钥来向 issueToken 终结点发出请求。

issueToken 终结点具有以下格式:

https://<REGION_IDENTIFIER>.api.cognitive.azure.cn/sts/v1.0/issueToken

<REGION_IDENTIFIER> 替换为与订阅所在区域匹配的标识符。

使用以下示例来创建访问令牌请求。

HTTP 示例

此示例是获取令牌的简单 HTTP 请求。 将 YOUR_SUBSCRIPTION_KEY 替换为你的语音服务的资源密钥。 如果订阅不在“中国东部 2”区域,请将 Host 标头替换为你的区域的主机名。

POST /sts/v1.0/issueToken HTTP/1.1
Ocp-Apim-Subscription-Key: YOUR_SUBSCRIPTION_KEY
Host: chinaeast2.api.cognitive.azure.cn
Content-type: application/x-www-form-urlencoded
Content-Length: 0

响应正文包含 JSON Web 令牌 (JWT) 格式的访问令牌。

PowerShell 示例

此示例是获取访问令牌的简单 PowerShell 脚本。 将 YOUR_SUBSCRIPTION_KEY 替换为你的语音服务的资源密钥。 请务必使用与订阅匹配的正确区域终结点。 此示例目前设置为“中国东部 2”。

$FetchTokenHeader = @{
  'Content-type'='application/x-www-form-urlencoded';
  'Content-Length'= '0';
  'Ocp-Apim-Subscription-Key' = 'YOUR_SUBSCRIPTION_KEY'
}

$OAuthToken = Invoke-RestMethod -Method POST -Uri https://chinaeast2.api.cognitive.azure.cn/sts/v1.0/issueToken
 -Headers $FetchTokenHeader

# show the token received
$OAuthToken

cURL 示例

cURL 是 Linux(及面向 Linux 的 Windows 子系统)中提供的一种命令行工具。 此 cURL 命令演示如何获取访问令牌。 将 YOUR_SUBSCRIPTION_KEY 替换为你的语音服务的资源密钥。 请务必使用与订阅匹配的正确区域终结点。 此示例目前设置为“中国东部 2”。

curl -v -X POST \
 "https://chinaeast2.api.cognitive.azure.cn/sts/v1.0/issueToken" \
 -H "Content-type: application/x-www-form-urlencoded" \
 -H "Content-Length: 0" \
 -H "Ocp-Apim-Subscription-Key: YOUR_SUBSCRIPTION_KEY"

C# 示例

此 C# 类演示如何获取访问令牌。 在实例化该类时,传递你的语音服务的资源密钥。 如果订阅不在“中国东部 2”区域,请更改 FetchTokenUri 的值,使之与订阅的区域匹配。

public class Authentication
{
    public static readonly string FetchTokenUri =
        "https://chinaeast2.api.cognitive.azure.cn/sts/v1.0/issueToken";
    private string subscriptionKey;
    private string token;

    public Authentication(string subscriptionKey)
    {
        this.subscriptionKey = subscriptionKey;
        this.token = FetchTokenAsync(FetchTokenUri, subscriptionKey).Result;
    }

    public string GetAccessToken()
    {
        return this.token;
    }

    private async Task<string> FetchTokenAsync(string fetchUri, string subscriptionKey)
    {
        using (var client = new HttpClient())
        {
            client.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", subscriptionKey);
            UriBuilder uriBuilder = new UriBuilder(fetchUri);

            var result = await client.PostAsync(uriBuilder.Uri.AbsoluteUri, null);
            Console.WriteLine("Token Uri: {0}", uriBuilder.Uri.AbsoluteUri);
            return await result.Content.ReadAsStringAsync();
        }
    }
}

Python 示例

# Request module must be installed.
# Run pip install requests if necessary.
import requests

subscription_key = 'REPLACE_WITH_YOUR_KEY'


def get_token(subscription_key):
    fetch_token_url = 'https://chinaeast2.api.cognitive.azure.cn/sts/v1.0/issueToken'
    headers = {
        'Ocp-Apim-Subscription-Key': subscription_key
    }
    response = requests.post(fetch_token_url, headers=headers)
    access_token = str(response.text)
    print(access_token)

如何使用访问令牌

应将访问令牌作为 Authorization: Bearer <TOKEN> 标头发送到服务。 每个访问令牌的有效期为 10 分钟。 你随时可以获取新令牌,但为了最大限度地减少网络流量和延迟,建议同一令牌使用 9 分钟。

下面是向适用于短音频的语音转文本 REST API 发出的示例 HTTP 请求:

POST /cognitiveservices/v1 HTTP/1.1
Authorization: Bearer YOUR_ACCESS_TOKEN
Host: chinaeast2.stt.speech.azure.cn
Content-type: application/ssml+xml
Content-Length: 199
Connection: Keep-Alive

// Message body here...

后续步骤