14

Go 1.11 から Amazon の新しいストリーミング文字起こし API を使用しようとしています。現在、Amazon は Java SDK のみを提供しているため、低レベルの方法を試しています。

関連する唯一のドキュメントはここにありますが、エンドポイントは示されていません。私はJavaの例でそれを見つけましhttps://transcribestreaming.<region>.amazonaws.comた.Ireland地域を試していhttps://transcribestreaming.eu-west-1.amazonaws.comます. HTTP/2 双方向ストリームを開くコードは次のとおりです。

import (
    "crypto/tls"
    "github.com/aws/aws-sdk-go-v2/aws"
    "github.com/aws/aws-sdk-go-v2/aws/external"
    "github.com/aws/aws-sdk-go-v2/aws/signer/v4"
    "golang.org/x/net/http2"
    "io"
    "io/ioutil"
    "log"
    "net/http"
    "os"
    "time"
)

const (
    HeaderKeyLanguageCode   = "x-amzn-transcribe-language-code"  // en-US
    HeaderKeyMediaEncoding  = "x-amzn-transcribe-media-encoding" // pcm only
    HeaderKeySampleRate     = "x-amzn-transcribe-sample-rate"    // 8000, 16000 ... 48000
    HeaderKeySessionId      = "x-amzn-transcribe-session-id"     // For retrying a session. Pattern: [a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}
    HeaderKeyVocabularyName = "x-amzn-transcribe-vocabulary-name"
    HeaderKeyRequestId = "x-amzn-request-id"
)

...

region := "eu-west-1"

cfg, err := external.LoadDefaultAWSConfig(aws.Config{
    Region: region,
})
if err != nil {
    log.Printf("could not load default AWS config: %v", err)
    return
}

signer := v4.NewSigner(cfg.Credentials)

transport := &http2.Transport{
    TLSClientConfig: &tls.Config{
        // allow insecure just for debugging
        InsecureSkipVerify: true,
    },
}
client := &http.Client{
    Transport: transport,
}

signTime := time.Now()

header := http.Header{}
header.Set(HeaderKeyLanguageCode, "en-US")
header.Set(HeaderKeyMediaEncoding, "pcm")
header.Set(HeaderKeySampleRate, "16000")
header.Set("Content-type", "application/json")

// Bi-directional streaming via a pipe.
pr, pw := io.Pipe()

req, err := http.NewRequest(http.MethodPost, "https://transcribestreaming.eu-west-1.amazonaws.com/stream-transcription", ioutil.NopCloser(pr))
if err != nil {
    log.Printf("err: %+v", err)
    return
}
req.Header = header

_, err = signer.Sign(req, nil, "transcribe", region, signTime)
if err != nil {
    log.Printf("problem signing headers: %+v", err)
    return
}

// This freezes and ends after 5 minutes with "unexpected EOF".
res, err := client.Do(req)
...

問題は、リクエスト ( client.Do(req)) の実行が 5 分間フリーズした後、「予期しない EOF」エラーで終了することです。

私が間違っていることはありますか?誰かが Java SDK なしで新しいストリーミング文字起こし API を正常に使用しましたか?

編集 (2019 年 3 月 11 日):

これをもう一度テストしたところ、タイムアウトにはなりませんが、すぐに200 OK応答が返されます。ただし、応答本文には「例外」があります。{"Output":{"__type":"com.amazon.coral.service#SerializationException"},"Version":"1.0"}

io.Pipe(上記のコードのように)HTTP2ストリームを開こうとしましたが、ドキュメントに記載されているJSONボディも使用しました:

{
    "AudioStream": { 
        "AudioEvent": { 
            "AudioChunk": ""
        }
    }
}

結果は同じでした。

編集 (2019 年 3 月 13 日):

@gpeng で述べたように、content-typefrom ヘッダーを削除すると、SerializationException. ただし、IAM 例外があり、transcription:StartStreamTranscriptionIAM ユーザーにアクセス許可を追加する必要があります。ただし、これは AWS IAM コンソールのどこにもないため、カスタム JSON アクセス許可として手動で追加する必要があります:/

ここには、正しくないことを示すhost新しい/別のドキュメントドキュメントもありますcontent-type(それを使用しないでくださいcontent-type。リクエストは 404 を返します)。

を削除しcontent-type、新しい権限を追加した後、例外が発生し{"Message":"A complete signal was sent without the preceding empty frame."}ました。また、パイプブロックに永久に書き込むので、再び立ち往生します。新しいドキュメントに記載されているメッセージは古いものとは異なり、最終的にはバイナリですが、私はそれらを理解していません。GoでそのようなHTTP2メッセージを送信する方法はありますか?

編集(2019年15試合):*

transfer-encoding署名の不一致に関する HTTP 403 エラーが発生した場合は、およびx-amz-content-sha256HTTP ヘッダーを設定しないでください。それらを設定したら、AWS SDK の V4 署名者でリクエストに署名すると、HTTP 403 を受け取りますThe request signature we calculated does not match the signature you provided.

4

4 に答える 4

0

私はまだNode.jsでもこのことと戦っています。ドキュメントについて明確でないのは、ある場所では はContent-Typeすべきではないと述べているapplication/json、別の場所では、ペイロードを としてエンコードする必要があるように見えることapplication/vnd.amazon.eventstreamです。次のように、ペイロードは JSON オブジェクトではなくバイナリ形式で慎重にフォーマットする必要があるようです。

Amazon Transcribe は、文字起こしのストリーミングにイベント ストリーム エンコーディングと呼ばれる形式を使用します。この形式は、各イベントの内容を説明するヘッダー情報を含むバイナリ データをエンコードします。この情報は、Amazon Transcribe SDK を使用せずに Amazon Transcribe エンドポイントを呼び出すアプリケーションに使用できます。Amazon Transcribe は、文字起こしのストリーミングに HTTP/2 プロトコルを使用します。ストリーミング リクエストの主要なコンポーネントは次のとおりです。

  • ヘッダー フレーム。これには、リクエストの HTTP ヘッダーと、Amazon Transcribe が次のデータ フレームに署名するためのシード署名として使用する承認ヘッダーの署名が含まれています。

  • イベント ストリーム エンコーディングの 1 つまたはメッセージ フレーム。フレームには、メタデータと生のオーディオ バイトが含まれます。

  • エンドフレームです。これは、本文が空のイベント ストリーム エンコーディングの署名付きメッセージです。

Java を使用してそのすべてを実装する方法を示すサンプル関数があり、このエンコーディングがどのように行われるかを明らかにする可能性があります。

于 2019-04-09T08:11:18.497 に答える