バッチ文字起こしの使用方法

バッチ文字起こしは、ストレージ内の大量のオーディオを文字起こしできる一連の REST API 操作です。 一般的な URI または Shared Access Signatures (SAS) URI を使用してオーディオ ファイルを示し、非同期に文字起こしの結果を受け取ることができます。 v3.0 API では、1 つ以上のオーディオ ファイルを文字起こしするか、またはストレージ コンテナー全体を処理することがきます。

バッチ文字起こし REST API を使用すると、次のメソッドを呼び出すことができます。

バッチ文字起こし操作 Method REST API の呼び出し
新しい文字起こしを作成する。 POST speechtotext/v3.0/transcriptions
認証されたサブスクリプションに対する文字起こしのリストを取得する。 GET speechtotext/v3.0/transcriptions
オフライン文字起こしでサポートされているロケールの一覧を取得する。 GET speechtotext/v3.0/transcriptions/locales
ID によって示された文字起こしの変更可能な詳細を更新する。 PATCH speechtotext/v3.0/transcriptions/{id}
指定した文字起こしタスクを削除する。 DELETE speechtotext/v3.0/transcriptions/{id}
指定した ID によって示される文字起こしを取得する。 GET speechtotext/v3.0/transcriptions/{id}
指定された ID で識別された文字起こしの結果ファイルを取得します。 GET speechtotext/v3.0/transcriptions/{id}/files

詳細な API を確認してテストできます。これは、Swagger ドキュメントで入手できます。

バッチ文字起こしジョブは、ベスト エフォート ベースでスケジュールされます。 ジョブが実行状態になるタイミングを見積もることはできませんが、通常のシステム負荷では数分以内に発生します。 いったん実行状態になると、文字起こしはオーディオのランタイム再生速度よりも速く発生します。

前提条件

Speech Service の他の機能と同様に、使用開始ガイドに従って Azure portal でサブスクリプション キーを作成します。

注意

バッチ文字起こしを使用するには、音声サービスの Standard サブスクリプション (S0) が必要です。 Free サブスクリプション キー (F0) は機能しません。 詳細については、価格と制限に関するページを参照してください。

モデルをカスタマイズする予定がある場合は、音響のカスタマイズ言語のカスタマイズの手順に従ってください。 作成されたモデルをバッチ文字起こしで使用するには、モデルの場所が必要です。 モデルの詳細 (self プロパティ) を調べると、モデルの場所を取得できます。 デプロイされたカスタム エンドポイントは、バッチ文字起こしサービスには "必要ありません"。

注意

REST API の一部として、バッチ文字起こしにはクォータと制限のセットがあり、これらはレビューすることをお勧めします。 大量のオーディオ ファイルを効率的に文字起こしするためのバッチ文字起こし機能を最大限に活用するには、要求ごとに常に複数のファイルを送信するか、または文字起こしするオーディオ ファイルを含む Blob Storage コンテナーを指定することをお勧めします。 このサービスにより、ターンアラウンド時間を短縮しながらファイルの文字起こしが同時に行われます。 1 つの要求での複数ファイルの使用は非常に単純で簡単です。「構成」セクションを参照してください。

バッチ文字起こし API

バッチ文字起こし API では、次の形式がサポートされています。

Format コーデック サンプルごとのビット数 サンプル レート
WAV PCM 0 16 ビット 8 kHz または 16 kHz、モノラルまたはステレオ
MP3 PCM 0 16 ビット 8 kHz または 16 kHz、モノラルまたはステレオ
OGG OPUS 16 ビット 8 kHz または 16 kHz、モノラルまたはステレオ

ステレオ オーディオ ストリームの場合、文字起こし中に左チャンネルと右チャンネルが分離されます。 JSON 結果ファイルが各チャネルに対して作成されます。 時間順の最終的なトランスクリプトを作成するには、発話ごとに生成されたタイムスタンプを使用します。

構成

構成パラメーターは JSON として提供されます。

1 つ以上の個別のファイルを文字起こししています。 複数のファイルを文字起こしする場合は、1 つの要求で複数のファイルを送信することをお勧めします。 次の例では、3 つのファイルを使用しています。

{
  "contentUrls": [
    "<URL to an audio file 1 to transcribe>",
    "<URL to an audio file 2 to transcribe>",
    "<URL to an audio file 3 to transcribe>"
  ],
  "properties": {
    "wordLevelTimestampsEnabled": true
  },
  "locale": "en-US",
  "displayName": "Transcription of file using default model for en-US"
}

ストレージ コンテナー全体の処理。 コンテナー SAS には、r (読み取り) と l (一覧) のアクセス許可が含まれている必要があります。

{
  "contentContainerUrl": "<SAS URL to the Azure blob container to transcribe>",
  "properties": {
    "wordLevelTimestampsEnabled": true
  },
  "locale": "en-US",
  "displayName": "Transcription of container using default model for en-US"
}

バッチ文字起こしでカスタム トレーニング済みのモデルを使用します。 この例では、3 つのファイルを使用しています。

{
  "contentUrls": [
    "<URL to an audio file 1 to transcribe>",
    "<URL to an audio file 2 to transcribe>",
    "<URL to an audio file 3 to transcribe>"
  ],
  "properties": {
    "wordLevelTimestampsEnabled": true
  },
  "locale": "en-US",
  "model": {
    "self": "https://westus.api.cognitive.microsoft.com/speechtotext/v3.0/models/{id}"
  },
  "displayName": "Transcription of file using default model for en-US"
}

構成プロパティ

次の省略可能なプロパティを使用して、文字起こしを構成します。

パラメーター

説明

profanityFilterMode

省略可能、既定値は Masked です。 認識結果内の不適切な表現をどう扱うかを指定します。 指定できる値は、None (不適切な表現のフィルターを無効にする)、Masked (不適切な表現をアスタリスクに置き換える)、Removed (すべての不適切な表現を結果から除去する)、または Tags ("profanity" (不適切な表現) のタグを追加する) です。

punctuationMode

省略可能、既定値は DictatedAndAutomatic です。 認識結果内の句読点をどう扱うかを指定します。 指定できる値は、None (句読点を無効にする)、Dictated (明示的な (音声指示の) 句読点を暗黙指定する)、Automatic (デコーダーで句読点を処理する)、または DictatedAndAutomatic (口述指示および自動の句読点を使用する) です。

wordLevelTimestampsEnabled

省略可能、既定値は false です。 単語レベルのタイムスタンプを出力に追加するかどうかを指定します。

diarizationEnabled

省略可能、既定値は false です。 2 つの音声を含むモノラル チャネルであることが予測される入力に対してダイアライゼーション分析を実行する必要があることを指定します。 注:wordLevelTimestampsEnabledtrue に設定する必要があります。

channels

省略可能、既定では 01 が文字起こしされます。 処理するチャネル番号の配列。 ここでは、オーディオ ファイルで使用できるチャネルのサブセットを処理するように指定できます (例: 0 のみ)。

timeToLive

省略可能、既定では削除は行われません。 文字起こしの完了後に、文字起こしを自動的に削除する期間。 timeToLive は、大量の文字起こしを最終的に確実に削除されるように処理するのに役立ちます (例: 12 時間の場合は PT12H)。

destinationContainerUrl

Azure の書き込み可能なコンテナーに対するアドホック SAS のオプションの URL。 結果はこのコンテナーに格納されます。 保存されているアクセス ポリシーによる SAS は サポートされていません。 指定しない場合、Microsoft では、Microsoft が管理するストレージ コンテナーに結果を格納します。 文字起こしの削除を呼び出して文字起こしを削除すると、結果データも削除されます。

ストレージ

バッチ文字起こしでは、公開されているインターネット URI からオーディオを読み取ることができます、また、Azure Blob Storage で SAS URI を使用してオーディオを読み取ったり、文字起こしを書き込んだりできます。

バッチ文字起こしの結果

オーディオ入力ごとに、1 つの文字起こし結果ファイルが作成されます。 文字起こしファイルの取得操作から、この文字起こしの結果ファイルの一覧が返されます。 特定の入力ファイルの文字起こしファイルを見つけるには、kind == Transcription および name == {originalInputName.suffix}.json を使用して、返されたすべてのファイルをフィルター処理します。

各文字起こし結果ファイルの形式は次のとおりです。

{
  "source": "...",                      // sas url of a given contentUrl or the path relative to the root of a given container
  "timestamp": "2020-06-16T09:30:21Z",  // creation time of the transcription, ISO 8601 encoded timestamp, combined date and time
  "durationInTicks": 41200000,          // total audio duration in ticks (1 tick is 100 nanoseconds)
  "duration": "PT4.12S",                // total audio duration, ISO 8601 encoded duration
  "combinedRecognizedPhrases": [        // concatenated results for simple access in single string for each channel
    {
      "channel": 0,                     // channel number of the concatenated results
      "lexical": "hello world",
      "itn": "hello world",
      "maskedITN": "hello world",
      "display": "Hello world."
    }
  ],
  "recognizedPhrases": [                // results for each phrase and each channel individually
    {
      "recognitionStatus": "Success",   // recognition state, e.g. "Success", "Failure"
      "speaker": 1,                     // if `diarizationEnabled` is `true`, this is the identified speaker (1 or 2), otherwise this property is not present
      "channel": 0,                     // channel number of the result
      "offset": "PT0.07S",              // offset in audio of this phrase, ISO 8601 encoded duration
      "duration": "PT1.59S",            // audio duration of this phrase, ISO 8601 encoded duration
      "offsetInTicks": 700000.0,        // offset in audio of this phrase in ticks (1 tick is 100 nanoseconds)
      "durationInTicks": 15900000.0,    // audio duration of this phrase in ticks (1 tick is 100 nanoseconds)

      // possible transcriptions of the current phrase with confidences
      "nBest": [
        {
          "confidence": 0.898652852,    // confidence value for the recognition of the whole phrase
          "lexical": "hello world",
          "itn": "hello world",
          "maskedITN": "hello world",
          "display": "Hello world.",

          // if wordLevelTimestampsEnabled is `true`, there will be a result for each word of the phrase, otherwise this property is not present
          "words": [
            {
              "word": "hello",
              "offset": "PT0.09S",
              "duration": "PT0.48S",
              "offsetInTicks": 900000.0,
              "durationInTicks": 4800000.0,
              "confidence": 0.987572
            },
            {
              "word": "world",
              "offset": "PT0.59S",
              "duration": "PT0.16S",
              "offsetInTicks": 5900000.0,
              "durationInTicks": 1600000.0,
              "confidence": 0.906032
            }
          ]
        }
      ]
    }
  ]
}

結果には次のフィールドが含まれます。

フィールド

コンテンツ

lexical

実際に認識された単語。

itn

認識されたテキストの逆テキスト正規化形式。 略語 ("doctor smith" から "dr smith")、電話番号、およびその他の変換が適用されます。

maskedITN

不適切表現のマスキングを適用した ITN 形式。

display

認識されたテキストの表示形式。 追加された句読点と大文字化が含まれます。

話者の分離 (ダイアライゼーション)

ダイアライゼーションは、音声に含まれる話者を分離するプロセスです。 ダイアライゼーションはバッチ パイプラインによってサポートされ、モノラル チャンネル レコーディングの 2 人の話者を認識できます。 この機能は、ステレオ録音では使用できません。

ダイアライゼーションを有効にした文字起こしの出力には、文字起こしされたフレーズごとに Speaker エントリが含まれます。 ダイアライゼーションが使用されない場合、Speaker プロパティは JSON 出力に存在しません。 ダイアライゼーションでは 2 つの音声がサポートされるため、話者は 1 または 2 として識別されます。

ダイアライゼーションを要求するには、次に示す HTTP 要求のように、diarizationEnabled プロパティを追加して true に設定します。

{
 "contentUrls": [
   "<URL to an audio file to transcribe>",
 ],
 "properties": {
   "diarizationEnabled": true,
   "wordLevelTimestampsEnabled": true,
   "punctuationMode": "DictatedAndAutomatic",
   "profanityFilterMode": "Masked"
 },
 "locale": "en-US",
 "displayName": "Transcription of file using default model for en-US"
}

上記の要求のパラメーターが示すように、ワードレベルのタイムスタンプを有効にする必要があります。

ベスト プラクティス

バッチ文字起こしサービスは、送信された多数の文字起こしを処理できます。 文字起こしの取得を実行して、文字起こしの状態を照会できます。 結果を取得した後は、サービスから定期的に文字起こしの削除を呼び出します。 または、timeToLive プロパティを設定して、確実に結果が最終的に削除されるようにします。

ヒント

インジェスト クライアント ツールおよび結果として得られるソリューションを使用して、大量のオーディオを処理することができます。

サンプル コード

完全なサンプルは、GitHub サンプル リポジトリsamples/batch サブディレクトリにあります。

カスタム モデルを使用している場合は、サブスクリプション情報、サービス リージョン、文字起こしするオーディオ ファイルを指す URI、モデルの場所を使用してサンプル コードを更新します。

var newTranscription = new Transcription
{
    DisplayName = DisplayName, 
    Locale = Locale, 
    ContentUrls = new[] { RecordingsBlobUri },
    //ContentContainerUrl = ContentAzureBlobContainer,
    Model = CustomModel,
    Properties = new TranscriptionProperties
    {
        IsWordLevelTimestampsEnabled = true,
        TimeToLive = TimeSpan.FromDays(1)
    }
};

newTranscription = await client.CreateTranscriptionAsync(newTranscription).ConfigureAwait(false);
Console.WriteLine($"Created transcription {newTranscription.Self}");

サンプル コードでは、クライアントが設定されて、文字起こし要求が送信されます。 その後、状態情報がポーリングされて、文字起こしの進行状況に関する詳細が表示されます。

// get the status of our transcriptions periodically and log results
int completed = 0, running = 0, notStarted = 0;
while (completed < 1)
{
    completed = 0; running = 0; notStarted = 0;

    // get all transcriptions for the user
    paginatedTranscriptions = null;
    do
    {
        // <transcriptionstatus>
        if (paginatedTranscriptions == null)
        {
            paginatedTranscriptions = await client.GetTranscriptionsAsync().ConfigureAwait(false);
        }
        else
        {
            paginatedTranscriptions = await client.GetTranscriptionsAsync(paginatedTranscriptions.NextLink).ConfigureAwait(false);
        }

        // delete all pre-existing completed transcriptions. If transcriptions are still running or not started, they will not be deleted
        foreach (var transcription in paginatedTranscriptions.Values)
        {
            switch (transcription.Status)
            {
                case "Failed":
                case "Succeeded":
                    // we check to see if it was one of the transcriptions we created from this client.
                    if (!createdTranscriptions.Contains(transcription.Self))
                    {
                        // not created form here, continue
                        continue;
                    }

                    completed++;

                    // if the transcription was successful, check the results
                    if (transcription.Status == "Succeeded")
                    {
                        var paginatedfiles = await client.GetTranscriptionFilesAsync(transcription.Links.Files).ConfigureAwait(false);

                        var resultFile = paginatedfiles.Values.FirstOrDefault(f => f.Kind == ArtifactKind.Transcription);
                        var result = await client.GetTranscriptionResultAsync(new Uri(resultFile.Links.ContentUrl)).ConfigureAwait(false);
                        Console.WriteLine("Transcription succeeded. Results: ");
                        Console.WriteLine(JsonConvert.SerializeObject(result, SpeechJsonContractResolver.WriterSettings));
                    }
                    else
                    {
                        Console.WriteLine("Transcription failed. Status: {0}", transcription.Properties.Error.Message);
                    }

                    break;

                case "Running":
                    running++;
                    break;

                case "NotStarted":
                    notStarted++;
                    break;
            }
        }

        // for each transcription in the list we check the status
        Console.WriteLine(string.Format("Transcriptions status: {0} completed, {1} running, {2} not started yet", completed, running, notStarted));
    }
    while (paginatedTranscriptions.NextLink != null);

    // </transcriptionstatus>
    // check again after 1 minute
    await Task.Delay(TimeSpan.FromMinutes(1)).ConfigureAwait(false);
}

前の呼び出しに関する詳細については、Swagger ドキュメントを参照してください。 ここに示すすべてのサンプルについては、GitHubsamples/batch サブディレクトリにアクセスしてください。

このサンプルでは、非同期セットアップの使用により、オーディオをポストして文字起こしの状態を受け取っています。 PostTranscriptions メソッドによってオーディオ ファイルの詳細を送信し、GetTranscriptions メソッドによって状態を受け取ります。 PostTranscriptions はハンドルを返し、GetTranscriptions はそのハンドルを使用して文字起こしの状態を取得するためのハンドルを作成します。

このサンプル コードでは、カスタム モデルは指定されていません。 このサービスでは、ファイルの文字起こしにベースライン モデルを使用します。 モデルを指定するには、同じメソッドにカスタム モデルのモデル参照を渡すことができます。

注意

ベースライン文字起こしの場合、ベースライン モデルの ID を宣言する必要はありません。

次のステップ