長い音声ファイルをテキストに変換する

このページでは、Speech-to-Text API と非同期音声認識を使用して、長い音声ファイル(1 分を超える)をテキストに変換する方法について説明します。

非同期音声認識について

非同期音声認識は、音声処理オペレーションの長時間実行を開始します。60 秒を超える音声を文字に変換するには、非同期音声認識を使用します。短い音声の場合は、同期音声認識を使用したほうが早くて簡単です。非同期音声認識の上限は 480 分です。

Speech-to-Text と非同期処理

音声コンテンツをローカル ファイルから Speech-to-Text に直接送信し、非同期処理を行うことができます。ただし、ローカル ファイルの音声時間の上限は 60 秒です。60 秒を超えるローカル音声ファイルを文字変換しようとすると、エラーが発生します。非同期音声認識を使用して 60 秒を超える音声を文字変換するには、Google Cloud Storage バケットにデータを保存する必要があります。

オペレーションの結果は、google.longrunning.Operations メソッドを使用して取得できます。結果は 5 日後(120 時間)まで取得できます。Google Cloud Storage バケットに結果を直接アップロードすることもできます。

Google Cloud Storage ファイルを使用して長い音声ファイルを文字変換する

次のサンプルでは、長時間の音声文字変換処理用の生の音声入力データを格納するために、Cloud Storage バケットを使用しています。一般的な longrunningrecognize オペレーションのレスポンスの例については、リファレンス ドキュメントをご覧ください。

プロトコル

詳細については、speech:longrunningrecognize API エンドポイントをご覧ください。

同期音声認識を実行するには、POST リクエストを作成し、適切なリクエスト本文を指定します。次は、curl を使用した POST リクエストの例です。この例では、Google Cloud CLI を使用してアクセス トークンを生成します。gcloud CLI のインストール手順については、クイックスタートをご覧ください。

curl -X POST \
     -H "Authorization: Bearer "$(gcloud auth application-default print-access-token) \
     -H "Content-Type: application/json; charset=utf-8" \
     --data "{
  'config': {
    'language_code': 'en-US'
  },
  'audio':{
    'uri':'gs://cloud-samples-tests/speech/brooklyn.flac'
  }
}" "https://speech.googleapis.com/v1/speech:longrunningrecognize"

リクエスト本文の構成について詳しくは、RecognitionConfigRecognitionAudio のリファレンス ドキュメントをご覧ください。

リクエストが成功すると、サーバーは 200 OK HTTP ステータス コードと JSON 形式のレスポンスを返します。

{
  "name": "7612202767953098924"
}

ここで、name はリクエストに対して作成された長時間実行オペレーションの名前です。

処理が完了するまで待ちます。処理時間はソース音声によって異なります。ほとんどの場合、ソース音声の半分の長さの結果が得られます。長時間実行オペレーションのステータスは、GET リクエストを https://speech.googleapis.com/v1/operations/ エンドポイントにすることによって取得できます。your-operation-namelongrunningrecognize リクエストから返された name に置き換えます。

curl -H "Authorization: Bearer "$(gcloud auth application-default print-access-token) \
     -H "Content-Type: application/json; charset=utf-8" \
     "https://speech.googleapis.com/v1/operations/your-operation-name"

リクエストが成功すると、サーバーは 200 OK HTTP ステータス コードと JSON 形式のレスポンスを返します。

{
  "name": "7612202767953098924",
  "metadata": {
    "@type": "type.googleapis.com/google.cloud.speech.v1.LongRunningRecognizeMetadata",
    "progressPercent": 100,
    "startTime": "2017-07-20T16:36:55.033650Z",
    "lastUpdateTime": "2017-07-20T16:37:17.158630Z"
  },
  "done": true,
  "response": {
    "@type": "type.googleapis.com/google.cloud.speech.v1.LongRunningRecognizeResponse",
    "results": [
      {
        "alternatives": [
          {
            "transcript": "how old is the Brooklyn Bridge",
            "confidence": 0.96096134,
          }
        ]
      },
      {
        "alternatives": [
          {
            ...
          }
        ]
      }
    ]
  }
}

オペレーションが完了していない場合は、レスポンスの done プロパティが true になるまで GET リクエストを繰り返し行って、エンドポイントをポーリングできます。

gcloud

詳しくは、recognize-long-running コマンドをご覧ください。

非同期音声認識を行うには、Google Cloud CLI を使用して、ローカル ファイルまたは Google Cloud Storage URL のパスを指定します。

gcloud ml speech recognize-long-running \
    'gs://cloud-samples-tests/speech/brooklyn.flac' \
     --language-code='en-US' --async

リクエストが成功すると、サーバーは長時間実行オペレーションの ID を JSON 形式で返します。

{
  "name": OPERATION_ID
}

次のコマンドを実行すると、オペレーションに関する情報を取得できます。

gcloud ml speech operations describe OPERATION_ID

また、次のコマンドを実行して、オペレーションが完了するまでオペレーションをポーリングすることもできます。

gcloud ml speech operations wait OPERATION_ID

オペレーションが完了すると、音声文字変換の結果が JSON 形式で返されます。

{
  "@type": "type.googleapis.com/google.cloud.speech.v1.LongRunningRecognizeResponse",
  "results": [
    {
      "alternatives": [
        {
          "confidence": 0.9840146,
          "transcript": "how old is the Brooklyn Bridge"
        }
      ]
    }
  ]
}

Go

Speech-to-Text 用のクライアント ライブラリをインストールして使用する方法については、Speech-to-Text クライアント ライブラリをご覧ください。詳細については、Speech-to-Text の Go API リファレンス ドキュメントをご覧ください。

Speech-to-Text に対する認証を行うには、アプリケーションのデフォルト認証情報を設定します。詳細については、ローカル開発環境の認証を設定するをご覧ください。


func sendGCS(w io.Writer, client *speech.Client, gcsURI string) error {
	ctx := context.Background()

	// Send the contents of the audio file with the encoding and
	// and sample rate information to be transcripted.
	req := &speechpb.LongRunningRecognizeRequest{
		Config: &speechpb.RecognitionConfig{
			Encoding:        speechpb.RecognitionConfig_LINEAR16,
			SampleRateHertz: 16000,
			LanguageCode:    "en-US",
		},
		Audio: &speechpb.RecognitionAudio{
			AudioSource: &speechpb.RecognitionAudio_Uri{Uri: gcsURI},
		},
	}

	op, err := client.LongRunningRecognize(ctx, req)
	if err != nil {
		return err
	}
	resp, err := op.Wait(ctx)
	if err != nil {
		return err
	}

	// Print the results.
	for _, result := range resp.Results {
		for _, alt := range result.Alternatives {
			fmt.Fprintf(w, "\"%v\" (confidence=%3f)\n", alt.Transcript, alt.Confidence)
		}
	}
	return nil
}

Java

Speech-to-Text 用のクライアント ライブラリをインストールして使用する方法については、Speech-to-Text クライアント ライブラリをご覧ください。詳細については、Speech-to-Text の Java API リファレンス ドキュメントをご覧ください。

Speech-to-Text に対する認証を行うには、アプリケーションのデフォルト認証情報を設定します。詳細については、ローカル開発環境の認証を設定するをご覧ください。

/**
 * Performs non-blocking speech recognition on remote FLAC file and prints the transcription.
 *
 * @param gcsUri the path to the remote LINEAR16 audio file to transcribe.
 */
public static void asyncRecognizeGcs(String gcsUri) throws Exception {
  // Configure polling algorithm
  SpeechSettings.Builder speechSettings = SpeechSettings.newBuilder();
  TimedRetryAlgorithm timedRetryAlgorithm =
      OperationTimedPollAlgorithm.create(
          RetrySettings.newBuilder()
              .setInitialRetryDelay(Duration.ofMillis(500L))
              .setRetryDelayMultiplier(1.5)
              .setMaxRetryDelay(Duration.ofMillis(5000L))
              .setInitialRpcTimeout(Duration.ZERO) // ignored
              .setRpcTimeoutMultiplier(1.0) // ignored
              .setMaxRpcTimeout(Duration.ZERO) // ignored
              .setTotalTimeout(Duration.ofHours(24L)) // set polling timeout to 24 hours
              .build());
  speechSettings.longRunningRecognizeOperationSettings().setPollingAlgorithm(timedRetryAlgorithm);

  // Instantiates a client with GOOGLE_APPLICATION_CREDENTIALS
  try (SpeechClient speech = SpeechClient.create(speechSettings.build())) {

    // Configure remote file request for FLAC
    RecognitionConfig config =
        RecognitionConfig.newBuilder()
            .setEncoding(AudioEncoding.FLAC)
            .setLanguageCode("en-US")
            .setSampleRateHertz(16000)
            .build();
    RecognitionAudio audio = RecognitionAudio.newBuilder().setUri(gcsUri).build();

    // Use non-blocking call for getting file transcription
    OperationFuture<LongRunningRecognizeResponse, LongRunningRecognizeMetadata> response =
        speech.longRunningRecognizeAsync(config, audio);
    while (!response.isDone()) {
      System.out.println("Waiting for response...");
      Thread.sleep(10000);
    }

    List<SpeechRecognitionResult> results = response.get().getResultsList();

    for (SpeechRecognitionResult result : results) {
      // There can be several alternative transcripts for a given chunk of speech. Just use the
      // first (most likely) one here.
      SpeechRecognitionAlternative alternative = result.getAlternativesList().get(0);
      System.out.printf("Transcription: %s\n", alternative.getTranscript());
    }
  }
}

Node.js

Speech-to-Text 用のクライアント ライブラリをインストールして使用する方法については、Speech-to-Text クライアント ライブラリをご覧ください。詳細については、Speech-to-Text の Node.js API リファレンス ドキュメントをご覧ください。

Speech-to-Text に対する認証を行うには、アプリケーションのデフォルト認証情報を設定します。詳細については、ローカル開発環境の認証を設定するをご覧ください。

// Imports the Google Cloud client library
const speech = require('@google-cloud/speech');

// Creates a client
const client = new speech.SpeechClient();

/**
 * TODO(developer): Uncomment the following lines before running the sample.
 */
// const gcsUri = 'gs://my-bucket/audio.raw';
// const encoding = 'Encoding of the audio file, e.g. LINEAR16';
// const sampleRateHertz = 16000;
// const languageCode = 'BCP-47 language code, e.g. en-US';

const config = {
  encoding: encoding,
  sampleRateHertz: sampleRateHertz,
  languageCode: languageCode,
};

const audio = {
  uri: gcsUri,
};

const request = {
  config: config,
  audio: audio,
};

// Detects speech in the audio file. This creates a recognition job that you
// can wait for now, or get its result later.
const [operation] = await client.longRunningRecognize(request);
// Get a Promise representation of the final result of the job
const [response] = await operation.promise();
const transcription = response.results
  .map(result => result.alternatives[0].transcript)
  .join('\n');
console.log(`Transcription: ${transcription}`);

Python

Speech-to-Text 用のクライアント ライブラリをインストールして使用する方法については、Speech-to-Text クライアント ライブラリをご覧ください。詳細については、Speech-to-Text の Python API リファレンス ドキュメントをご覧ください。

Speech-to-Text に対する認証を行うには、アプリケーションのデフォルト認証情報を設定します。詳細については、ローカル開発環境の認証を設定するをご覧ください。

def transcribe_gcs(gcs_uri: str) -> str:
    """Asynchronously transcribes the audio file specified by the gcs_uri.

    Args:
        gcs_uri: The Google Cloud Storage path to an audio file.

    Returns:
        The generated transcript from the audio file provided.
    """
    from google.cloud import speech

    client = speech.SpeechClient()

    audio = speech.RecognitionAudio(uri=gcs_uri)
    config = speech.RecognitionConfig(
        encoding=speech.RecognitionConfig.AudioEncoding.FLAC,
        sample_rate_hertz=44100,
        language_code="en-US",
    )

    operation = client.long_running_recognize(config=config, audio=audio)

    print("Waiting for operation to complete...")
    response = operation.result(timeout=90)

    transcript_builder = []
    # Each result is for a consecutive portion of the audio. Iterate through
    # them to get the transcripts for the entire audio file.
    for result in response.results:
        # The first alternative is the most likely one for this portion.
        transcript_builder.append(f"\nTranscript: {result.alternatives[0].transcript}")
        transcript_builder.append(f"\nConfidence: {result.alternatives[0].confidence}")

    transcript = "".join(transcript_builder)
    print(transcript)

    return transcript

その他の言語

C#: クライアント ライブラリ ページの C# の設定手順を行ってから、.NET の Speech-to-Text のリファレンス ドキュメントをご覧ください。

PHP: クライアント ライブラリ ページの PHP の設定手順を行ってから、PHP の Speech-to-Text のリファレンス ドキュメントをご覧ください。

Ruby: クライアント ライブラリ ページの Ruby の設定手順を行ってから、Ruby の Speech-to-Text のリファレンス ドキュメントをご覧ください。

音声文字変換の結果を Cloud Storage バケットにアップロードする

Speech-to-Text では、長時間にわたる認識結果を Cloud Storage バケットに直接アップロードできます。この機能を Cloud Storage トリガーで実装すると、Cloud Storage アップロードで Cloud Functions を呼び出す通知がトリガーされ、Speech-to-Text にポーリングして認識結果を返す必要がなくなります。

結果を Cloud Storage バケットにアップロードするには、長時間実行の認識リクエストでオプションの TranscriptOutputConfig 出力構成を指定します。

  message TranscriptOutputConfig {

    oneof output_type {
      // Specifies a Cloud Storage URI for the recognition results. Must be
      // specified in the format: `gs://bucket_name/object_name`
      string gcs_uri = 1;
    }
  }

プロトコル

詳細については、longrunningrecognize API エンドポイントをご覧ください。

次の例は、curl を使用して POST リクエストを送信する方法を示しています。ここでは、リクエストの本文で Cloud Storage バケットへのパスを指定しています。結果は、SpeechRecognitionResult を格納する JSON ファイルとしてこの場所にアップロードされます。

curl -X POST \
     -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
     -H "Content-Type: application/json; charset=utf-8" \
     --data "{
  'config': {...},
  'output_config': {
     'gcs_uri':'gs://bucket/result-output-path.json'
  },
  'audio': {
    'uri': 'gs://bucket/audio-path'
  }
}" "https://speech.googleapis.com/v1p1beta1/speech:longrunningrecognize"

LongRunningRecognizeResponse には、アップロードが試みられた Cloud Storage バケットのパスが含まれています。アップロードが失敗した場合、出力エラーが返されます。同じ名前のファイルがすでに存在する場合、アップロードは、タイムスタンプを接尾辞として付加した新しいファイルに結果を書き込みます。

{
  ...
  "metadata": {
    ...
    "outputConfig": {...}
  },
  ...
  "response": {
    ...
    "results": [...],
    "outputConfig": {
      "gcs_uri":"gs://bucket/result-output-path"
    },
    "outputError": {...}
  }
}

使ってみる

Google Cloud を初めて使用する場合は、アカウントを作成して、実際のシナリオでの Speech-to-Text のパフォーマンスを評価してください。新規のお客様には、ワークロードの実行、テスト、デプロイができる無料クレジット $300 分を差し上げます。

Speech-to-Text の無料トライアル