设置流式转录 - Amazon Transcribe

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

设置流式转录

本节展开讲了主要的流式转录部分。它旨在为想要使用 HTTP /2 或 WebSockets 直接设置直播而不是使用 /2 设置直播的用户提供信息 AWS SDK。本节中的信息也可以用来自己构建SDK。

重要

我们强烈建议 WebSockets 直接使用SDKs而不是使用 HTTP /2。SDKs是转录数据流的最简单、最可靠的方法。要开始流式传输,请使用 AWS SDK,请参阅使用 SDK 进行转录 AWS

用于流式传输转录请求的 HTTP/2 协议的关键组件 Amazon Transcribe 是:

  • 标头帧。它包含您的请求的 HTTP /2 标头,以及授权标头中的签名 Amazon Transcribe 用作对数据帧进行签名的种子签名。

  • 一个或多个消息帧采用事件流编码,其中包含元数据和原始音频字节。

  • 结束帧。这是事件流编码中正文为空的已签名消息。

注意

Amazon Transcribe 每个 HTTP /2 会话仅支持一个直播。如果您尝试使用多个音频流,则转录请求将失败。

  1. 将以下政策附加到 IAM 发出请求的角色。参见添加 IAM 有关更多信息,请查看政策。

    { "Version": "2012-10-17", "Statement": [ { "Sid": "my-transcribe-http2-policy", "Effect": "Allow", "Action": "transcribe:StartStreamTranscription", "Resource": "*" } ] }
  2. 要启动会话,请将 HTTP /2 请求发送到 Amazon Transcribe.

    POST /stream-transcription HTTP/2 host: transcribestreaming.us-west-2.amazonaws.com X-Amz-Target: com.amazonaws.transcribe.Transcribe.StartStreamTranscription Content-Type: application/vnd.amazon.eventstream X-Amz-Content-Sha256: string X-Amz-Date: YYYYMMDDTHHMMSSZ Authorization: AWS4-HMAC-SHA256 Credential=access-key/YYYYMMDD/us-west-2/transcribe/aws4_request, SignedHeaders=content-type;host;x-amz-content-sha256;x-amz-date;x-amz-target;x-amz-security-token, Signature=string x-amzn-transcribe-language-code: en-US x-amzn-transcribe-media-encoding: flac x-amzn-transcribe-sample-rate: 16000 transfer-encoding: chunked

    API参考资料中列出了其他操作和参数;所有操作和参数通用 AWS API操作列在 “常用参数” 部分。

    Amazon Transcribe 发送以下响应:

    HTTP/2.0 200 x-amzn-transcribe-language-code: en-US x-amzn-transcribe-media-encoding: flac x-amzn-transcribe-sample-rate: 16000 x-amzn-request-id: 8a08df7d-5998-48bf-a303-484355b4ab4e x-amzn-transcribe-session-id: b4526fcf-5eee-4361-8192-d1cb9e9d6887 content-type: application/json
  3. 创建包含您音频数据的音频事件。将下表中描述的标头与音频字节组块一起组合到事件编码消息中。要创建事件消息负载,请按照原始字节格式使用缓冲区。

    标头名称字节长度 标头名称(字符串) 标头值类型 值字符串字节长度 值字符串 (UTF-8)
    13 :content-type 7 24 application/octet-stream
    11 :event-type 7 10 AudioEvent
    13 :message-type 7 5 事件

    此示例请求中的二进制数据是经过 base64 编码的。在实际请求中,数据为原始字节。

    :content-type: "application/vnd.amazon.eventstream" :event-type: "AudioEvent" :message-type: "event" UklGRjzxPQBXQVZFZm10IBAAAAABAAEAgD4AAAB9AAACABAAZGF0YVTwPQAAAAAAAAAAAAAAAAD//wIA/f8EAA==
  4. 创建一个音频消息,其中包含音频数据。

    1. 音频消息数据帧包含事件编码标头,这些标头包含音频组块和音频事件的当前日期和签名。

      标头名称字节长度 标头名称(字符串) 标头值类型 值字符串字节长度
      16 :chunk-signature 6 变化 生成的签名
      5 :date 8 8 时间戳

      此请求中的二进制数据是经过 base64 编码的。在实际请求中,数据为原始字节。

      :date: 2019-01-29T01:56:17.291Z :chunk-signature: signature AAAA0gAAAIKVoRFcTTcjb250ZW50LXR5cGUHABhhcHBsaWNhdGlvbi9vY3RldC1zdHJlYW0LOmV2ZW50LXR5 cGUHAApBdWRpb0V2ZW50DTptZXNzYWdlLXR5cGUHAAVldmVudAxDb256ZW50LVR5cGUHABphcHBsaWNhdGlv bi94LWFtei1qc29uLTEuMVJJRkY88T0AV0FWRWZtdCAQAAAAAQABAIA+AAAAfQAAAgAQAGRhdGFU8D0AAAAA AAAAAAAAAAAA//8CAP3/BAC7QLFf
    2. 构造待签字符串,如为签名版本 4 创建待签字符串。您的字符串遵循以下格式:

      String stringToSign = "AWS4-HMAC-SHA256" + "\n" + DateTime + "\n" + Keypath + "\n" + Hex(priorSignature) + "\n" + HexHash(nonSignatureHeaders) + "\n" + HexHash(payload);
      • DateTime:签名的创建日期和时间。格式为YYYYMMDDTHHMMSSZ,其中 YYYY =year、mm=month、dd=day、hh=Hour、mm=minute、ss=Seconds 以及 'T' 和 'Z' 是固定字符。有关更多信息,请参阅处理签名版本 4 中的日期

      • Keypath:采用 date/region/service/aws4_request 格式的签名范围。例如,20220127/us-west-2/transcribe/aws4_request

      • Hex:一个将输入编码为十六进制表示形式的函数。

      • priorSignature:上一帧的签名。对于第一个数据帧,请使用标头帧的签名。

      • HexHash: 一个函数,它首先创建其输入的 SHA -256 哈希值,然后使用十六进制函数对哈希进行编码。

      • nonSignatureHeaders: 编码为字符串的 DateTime 标头。

      • payload:包含音频事件数据的字节缓冲区。

    3. 从您的签名密钥中获取签名密钥 AWS 私有访问密钥并用它来签署stringToSign。为了获得更高程度的保护,派生密钥特定于日期、服务和 AWS 区域。 有关更多信息,请参阅计算签名 AWS签名版本 4.

      请务必实施用于派生签名密钥的 GetSignatureKey 函数。如果您尚未派生签名密钥,请参阅关于如何为签名版本 4 派生签名密钥的示例

      String signature = HMACSHA256(derivedSigningKey, stringToSign);
      • HMACSHA256: 使用 SHA -256 哈希函数创建签名的函数。

      • derivedSigningKey:签名版本 4 签名密钥。

      • stringToSign:您为数据框计算的字符串。

      在计算数据帧的签名后,构造一个包含日期、签名和音频事件负载的字节缓冲区。将字节数组发送到 Amazon Transcribe 用于转录。

  5. 要向指示音频流已完成,请发送仅包含日期和签名的结束帧(空数据帧)。构造此结束帧的方式与构造数据帧的方式相同。

    Amazon Transcribe 使用发送到您的应用程序的一系列转录事件进行响应。此响应是经过事件流编码的。它包含标准前导信息和以下标头。

    标头名称字节长度 标头名称(字符串) 标头值类型 值字符串字节长度 值字符串 (UTF-8)
    13 :content-type 7 16 application/json
    11 :event-type 7 15 TranscriptEvent
    13 :message-type 7 5 事件

    这些事件采用原始字节格式发送。在该示例中,字节是经过 base64 编码的。

    AAAAUwAAAEP1RHpYBTpkYXRlCAAAAWiXUkMLEDpjaHVuay1zaWduYXR1cmUGACCt6Zy+uymwEK2SrLp/zVBI 5eGn83jdBwCaRUBJA+eaDafqjqI=

    要查看转录结果,请使用事件流编码对原始字节进行解码。

    :content-type: "application/vnd.amazon.eventstream" :event-type: "TranscriptEvent" :message-type: "event" { "Transcript": { "Results": [ results ] } }
  6. 要结束直播,请将一个空的音频事件发送到 Amazon Transcribe。 创建音频事件的方法与其他事件完全相同,但有效载荷为空。为事件签名并将此签名包括在 :chunk-signature 标头中,如下所示:

    :date: 2019-01-29T01:56:17.291Z :chunk-signature: signature

处理 HTTP /2 直播错误

如果在处理您的媒体流时出现错误, Amazon Transcribe 发送异常响应。响应是经过事件流编码的。

此响应包含标准前导信息和以下标头:

标头名称字节长度 标头名称(字符串) 标头值类型 值字符串字节长度 值字符串 (UTF-8)
13 :content-type 7 16 application/json
11 :event-type 7 19 BadRequestException
13 :message-type 7 9 exception

异常响应解码后将包含以下信息:

:content-type: "application/vnd.amazon.eventstream" :event-type: "BadRequestException" :message-type: "exception" Exception message

用于流式传输转录请求的WebSocket协议的关键组件 Amazon Transcribe 是:

  • 升级请求。它包含您的请求的查询参数和一个签名 Amazon Transcribe 用作对数据帧进行签名的种子签名。

  • 一个或多个消息帧采用事件流编码,其中包含元数据和原始音频字节。

  • 结束帧。这是事件流编码中正文为空的已签名消息。

注意

Amazon Transcribe 每个 WebSocket 会话仅支持一个直播。如果您尝试使用多个音频流,则转录请求将失败。

  1. 将以下政策附加到 IAM 发出请求的角色。参见添加 IAM 有关更多信息,请查看政策。

    { "Version": "2012-10-17", "Statement": [ { "Sid": "my-transcribe-websocket-policy", "Effect": "Allow", "Action": "transcribe:StartStreamTranscriptionWebSocket", "Resource": "*" } ] }
  2. 要启动会话,请按以下格式创建预签名URL。为了便于阅读,已增加了换行符。

    GET wss://transcribestreaming.us-west-2.amazonaws.com:8443/stream-transcription-websocket? &X-Amz-Algorithm=AWS4-HMAC-SHA256 &X-Amz-Credential=access-key%2FYYYYMMDD%2Fus-west-2%2Ftranscribe%2Faws4_request &X-Amz-Date=YYYYMMDDTHHMMSSZ &X-Amz-Expires=300 &X-Amz-Security-Token=security-token &X-Amz-Signature=string &X-Amz-SignedHeaders=content-type%3Bhost%3Bx-amz-date &language-code=en-US &media-encoding=flac &sample-rate=16000
    注意

    X-Amz-Expires 的最大值为 300(5 分钟)。

    API参考资料中列出了其他操作和参数;所有操作和参数通用 AWS API操作列在 “常用参数” 部分。

    要URL为您的请求构造签名并创建签名版本 4 签名,请参阅以下步骤。这些示例是伪代码。

    1. 创建规范请求。一个规范请求,其中包含来自标准格式的请求的信息。这样可以确保当 AWS 收到请求,它可以计算出您为自己创建的相同签名URL。有关更多信息,请参阅为签名版本 4 创建规范请求

      # HTTP verb method = "GET" # Service name service = "transcribe" # Region region = "us-west-2" # Amazon Transcribe streaming endpoint endpoint = "wss://transcribestreaming.us-west-2.amazonaws.com:8443" # Host host = "transcribestreaming.us-west-2.amazonaws.com:8443" # Date and time of request amz-date = YYYYMMDDTHHMMSSZ # Date without time for credential scope datestamp = YYYYMMDD
    2. 创建一个 canonicalURI,它是域名和查询字符串URI之间的部分。

      canonical_uri = "/stream-transcription-websocket"
    3. 创建规范标头和签名标头。请注意规范标头尾部的 \n

      • 追加小写标头名称,后跟冒号 (:)。

      • 追加该标头的值的逗号分隔列表。请勿对有多个值的标头进行值排序。

      • 追加一个新行(\n)。

      canonical_headers = "host:" + host + "\n" signed_headers = "host"
    4. 将算法与哈希算法匹配。使用 SHA-256

      algorithm = "AWS4-HMAC-SHA256"
    5. 创建凭证范围,将派生密钥的范围限定为日期, AWS 区域和服务。例如,20220127/us-west-2/transcribe/aws4_request

      credential_scope = datestamp + "/" + region + "/" + service + "/" + "aws4_request"
    6. 创建规范查询字符串。查询字符串值必须URI经过编码并按名称排序。

      • 按字符代码点以升序顺序对参数名称进行排序。具有重复名称的参数应按值进行排序。例如,以大写字母 F 开头的参数名称排在以小写字母 b 开头的参数名称之前。

      • 不要对 RFC 3986 定义的任何非保留字符进行URI编码:A-Z、a-z、0-9、连字符 (-)、下划线 (_)、句点 (.) 和波浪号 (~)。

      • 使用 %XY 对所有其他字符进行百分比编码,其中“X”和“Y”为十六进制字符(0-9 和大写字母 A-F)。例如,空格字符必须编码为 %20(不要像某些编码方案那样包含 '+');扩展后的 UTF -8 个字符必须采用 %XY%ZA%BC 的格式。

      • 对参数值中的任何等于 (=) 字符进行双重编码。

      canonical_querystring = "X-Amz-Algorithm=" + algorithm canonical_querystring += "&X-Amz-Credential="+ URI-encode(access key + "/" + credential_scope) canonical_querystring += "&X-Amz-Date=" + amz_date canonical_querystring += "&X-Amz-Expires=300" canonical_querystring += "&X-Amz-Security-Token=" + token canonical_querystring += "&X-Amz-SignedHeaders=" + signed_headers canonical_querystring += "&language-code=en-US&media-encoding=flac&sample-rate=16000"
    7. 创建负载的哈希。对于 GET 请求,负载为空字符串。

      payload_hash = HashSHA256(("").Encode("utf-8")).HexDigest()
    8. 组合以下元素以创建规范请求。

      canonical_request = method + '\n' + canonical_uri + '\n' + canonical_querystring + '\n' + canonical_headers + '\n' + signed_headers + '\n' + payload_hash
  3. 创建待签字符串,其中包含您的请求的元信息。在计算请求签名时,您可以使用该字符串登录下一步。有关更多信息,请参阅为签名版本 4 创建待签字符串

    string_to_sign=algorithm + "\n" + amz_date + "\n" + credential_scope + "\n" + HashSHA256(canonical_request.Encode("utf-8")).HexDigest()
  4. 计算签名。为此,请从您的签名密钥中获取签名密钥 AWS 秘密访问密钥。为了获得更高程度的保护,派生密钥特定于日期、服务和 AWS 区域。 使用此派生密钥对请求进行签名。有关更多信息,请参阅计算签名 AWS 签名版本 4.

    请务必实施用于派生签名密钥的 GetSignatureKey 函数。如果您尚未派生签名密钥,请参阅关于如何为签名版本 4 派生签名密钥的示例

    #Create the signing key signing_key = GetSignatureKey(secret_key, datestamp, region, service) # Sign the string_to_sign using the signing key signature = HMAC.new(signing_key, (string_to_sign).Encode("utf-8"), Sha256()).HexDigest

    该函数HMAC(key, data)代表一个 HMAC-SHA256 函数,它以二进制格式返回结果。

  5. 向请求中添加签名信息并创建请求URL。

    在计算签名之后,将它添加到查询字符串。有关更多信息,请参阅将签名添加到请求中

    首先,将身份验证信息添加到查询字符串。

    canonical_querystring += "&X-Amz-Signature=" + signature

    其次,URL为请求创建。

    request_url = endpoint + canonical_uri + "?" + canonical_querystring

    使用您的 WebSocket 图书馆URL的请求向以下地址提出请求 Amazon Transcribe.

  6. 的请求 Amazon Transcribe 必须包含以下标题。通常,这些标头由您的 WebSocket 客户端库管理。

    Host: transcribestreaming.us-west-2.amazonaws.com:8443 Connection: Upgrade Upgrade: websocket Origin: URI-of-WebSocket-client Sec-WebSocket-Version: 13 Sec-WebSocket-Key: randomly-generated-string
  7. 时间 Amazon Transcribe 收到您的 WebSocket 请求,它会以 WebSocket 升级响应进行响应。通常,你的 WebSocket 库会管理这个响应,并设置一个用于与之通信的套接字 Amazon Transcribe.

    以下是来自的回复 Amazon Transcribe。 为了便于阅读,添加了换行符。

    HTTP/1.1 101 WebSocket Protocol Handshake Connection: upgrade Upgrade: websocket websocket-origin: wss://transcribestreaming.us-west-2.amazonaws.com:8443 websocket-location: transcribestreaming.us-west-2.amazonaws.com:8443/stream-transcription-websocket? &X-Amz-Algorithm=AWS4-HMAC-SHA256 &X-Amz-Credential=AKIAIOSFODNN7EXAMPLE%2F20220208%2Fus-west-2%2Ftranscribe%2Faws4_request &X-Amz-Date=20220208T235959Z &X-Amz-Expires=300 &X-Amz-Signature=Signature Version 4 signature &X-Amz-SignedHeaders=host &language-code=en-US &session-id=String &media-encoding=flac &sample-rate=16000 x-amzn-RequestId: RequestId Strict-Transport-Security: max-age=31536000 sec-websocket-accept: hash-of-the-Sec-WebSocket-Key-header
  8. 提出 WebSocket 直播请求。

    建立 WebSocket 连接后,客户端可以开始发送一系列音频帧,每个帧都使用事件流编码进行编码

    每个数据帧包含三个标头以及原始音频字节组块,后跟描述这些标头的表。

    标头名称字节长度 标头名称(字符串) 标头值类型 值字符串字节长度 值字符串 (UTF-8)
    13 :content-type 7 24 application/octet-stream
    11 :event-type 7 10 AudioEvent
    13 :message-type 7 5 事件
  9. 要结束数据流,请在事件流编码消息中发送空音频组块。

    响应包含负载中的事件流编码的原始字节。它包含标准前导信息和以下标头。

    标头名称字节长度 标头名称(字符串) 标头值类型 值字符串字节长度 值字符串 (UTF-8)
    13 :content-type 7 16 application/json
    11 :event-type 7 15 TranscriptEvent
    13 :message-type 7 5 事件

    当你解码二进制响应时,你最终会得到一个包含转录结果的JSON结构。

处理 WebSocket 直播错误

如果在处理您的请求时出现异常, Amazon Transcribe 使用包含事件流编码响应的终端 WebSocket 帧进行响应。该响应包含下表中描述的标头,以及包含描述性错误消息的响应的正文。发送异常响应后, Amazon Transcribe 发送一帧近距离画面。

标头名称字节长度 标头名称(字符串) 标头值类型 值字符串字节长度 值字符串 (UTF-8)
13 :content-type 7 16 application/json
15 :exception-type 7 变化 各种编号,请参阅下文
13 :message-type 7 9 exception

exception-type 标头包含以下值之一:

  • BadRequestException:创建流时发生客户端错误,或者流式处理数据中发生错误。确保您的客户端已准备好接受数据,然后重试请求。

  • InternalFailureException: Amazon Transcribe 在与客户握手时遇到了问题。请再次尝试您的请求。

  • LimitExceededException:客户端超出了并发流限制。有关更多信息,请参阅 Amazon Transcribe 极限。减少要转录的流的数量。

  • UnrecognizedClientException:使用错误的访问密钥或私有密钥签署了 WebSocket 升级请求。请确保您正确创建了访问密钥,然后重试请求。

Amazon Transcribe 也可以返回任何常见的服务错误。有关错误列表,请参阅常见错误

事件流编码

Amazon Transcribe 使用一种名为事件流编码的格式来传输转录。

事件流编码在客户端和服务器之间提供双向通信。数据帧发送到 Amazon Transcribe 流媒体服务以这种格式编码。来自的回应 Amazon Transcribe 也使用这种编码。

每个消息都包含两部分:前导信息和数据。前导信息包括:

  1. 消息的总字节长度

  2. 所有标头的组合字节长度

数据部分包含:

  1. 标头

  2. 有效负载

每个部分都以 4 字节的大端整数循环冗余校验 () 校验和结尾。CRC消息CRC校验和适用于前奏部分和数据部分。 Amazon Transcribe 使用CRC32(通常称为 GZIPCRC32)来计算两者CRCs。有关的更多信息CRC32,请参阅GZIP文件格式规范版本 4.3

总消息开销(包括前导信息和两个校验和)为 16 个字节。

下图显示了构成消息和标头的组件。每个消息有多个标头。

消息组成部分的示意图和流式转录的标头。

每个消息都包含以下组件:

  • 前导消息:包含两个 4 字节的字段,固定总长度为 8 个字节。

    • 第一个 4 字节:这是整个消息的 big-endian 整数字节长度,包括这个 4 字节长度字段本身。

    • 第二个 4 字节:这是消息的“标头”部分的 big-endian 整数字节长度,不包括“标头”长度字段本身。

  • PreludeCRC:消息前奏部分的 4 字节CRC校验和,不包括消息本身。CRC前奏与信息CRC是分CRC开的。这样可以确保 Amazon Transcribe 可以立即检测损坏的字节长度信息,而不会导致错误,例如缓冲区溢出。

  • 标头:用于批注消息元数据;例如,消息类型和内容类型。消息有多个标头,它们是 key: value 对,其中键是 UTF -8 字符串。标头可按任何顺序出现在消息的“标头”部分中,并且每个标头只能出现一次。

  • 负载:要转录的音频内容。

  • 消息 CRC:从消息开头到CRC校验和开头的 4 字节校验和。也就是说,消息中除其CRC本身之外的所有内容。

标题帧是直播转录的授权框架。 Amazon Transcribe 使用授权标头的值作为种子,为请求中的数据帧生成授权标头链。

每个标头包含以下组成部分;每帧有多个标头。

  • 标头名称字节长度:标头名称的字节长度。

  • 标头名称:指示标头类型的标头名称。有关有效值,请参阅下面的帧描述。

  • 标头值类型:指示标头值的数字。以下列表显示了标头的可能值及其表示的内容。

    • 0 – TRUE

    • 1 – FALSE

    • 2 – BYTE

    • 3 – SHORT

    • 4 – INTEGER

    • 5 – LONG

    • 6 – BYTE ARRAY

    • 7 – STRING

    • 8 – TIMESTAMP

    • 9 – UUID

  • 值字符串字节长度:标头值字符串的字节长度。

  • 标头值:标头字符串的值。此字段的有效值取决于标头的类型。有关更多信息,请参阅设置 HTTP /2 直播设置直 WebSocket 播

数据帧

每个流式请求都包含一个或多个数据帧。创建数据帧有两个步骤:

  1. 将原始音频数据与元数据组合以创建请求负载。

  2. 将有效负载与签名组合起来,形成发送到的事件消息 Amazon Transcribe.

下图演示了工作原理。

用于流式转录的数据帧的组成部分。