[Google Cloud Speech-to-Text API(V2)] Javaで音声をテキストに変換する

Cloud Speech-to-Text API V2(Java)を使用して、
音声をテキストに変換する方法についてご紹介します。

:::note info
APIを利用する環境の準備から始める場合や、コードを実行する際は、
[⧉[Google Cloud Speech-to-Text API(V2)] JavaでSpeech-to-Text APIを使ってみる](https://qiita.com/doran/items/8e4ef896588229c4fed3)
を参照ください。
:::

|No||目次|
|---|---|---|
|1||[音声を変換(同期)](#1-音声を変換同期)|
||1|[スコープ](#11-スコープ)|
||2|[実行](#12-実行)|
||3|[レスポンスの内容](#13-レスポンスの内容)|
|2||[長い音声を変換(非同期)](#2-長い音声を変換非同期)|
||1|[スコープ](#21-スコープ)|
||2|[実行](#22-実行)|
||3|[レスポンスの内容](#23-レスポンスの内容)|

## 1. 音声を変換(同期)
音声をテキストに変換します。
変換したテキストはすぐ(同期的)に取得できます。
変換に時間がかかるような長い音声は、[2. 音声を変換(非同期)](#2-長い音声を変換非同期)の方を利用ください。

音声入力はローカルファイルからと、GoogleCloudStorage上のファイルからの入力があります。

### 1.1. スコープ
OAuth2.0でこのAPIを実行するには、以下のスコープを指定してください。
サービスアカウントで実行する場合はスコープの指定は不要です。
```
https://www.googleapis.com/auth/cloud-platform
```

### 1.2. 実行
認識ツールIDでは、"_"(デフォルト(未使用))を指定しています。
サンプルではローカルにある音声ファイルを変換しています。

```java
public static void main(String[] args) throws Exception{
    try(SpeechClient client = getSpeechClient()){
        byte[] data = Files.readAllBytes(Paths.get("音声ファイルのパス"));
        ByteString audioBytes = ByteString.copyFrom(data);
        
        RecognitionConfig.Builder config = RecognitionConfig.newBuilder();
        config.addLanguageCodes("ja-JP");
        config.setModel("short");
        AutoDetectDecodingConfig.Builder decoding = AutoDetectDecodingConfig.newBuilder();
        config.setAutoDecodingConfig(decoding.build());
        
        RecognizeRequest.Builder builder = RecognizeRequest.newBuilder();
        builder.setConfig(config.build());
        builder.setContent(audioBytes);
        builder.setRecognizer(String.format("projects/%s/locations/%s/recognizers/%s", 
                    "プロジェクトID","ロケーションID","_"));
        
        RecognizeResponse response = client.recognize(builder.build());
        List<SpeechRecognitionResult> results = response.getResultsList();
        for (SpeechRecognitionResult result : results) {
            if (result.getAlternativesCount() > 0) {
                SpeechRecognitionAlternative alternative = result.getAlternativesList().get(0);
                System.out.printf("Transcription: %s%n", alternative.getTranscript());
            }
        }
    }
}
```
#### 1.2.1. HTTPリクエスト
POST:　https:\//speech.googleapis.com/v2/projects/{プロジェクトID}/locations/{ロケーションID}/recognizers/{認識ツールID}:recognize
が実行されます。

#### 1.2.2. クエリパラメータ
クエリパラメータはありません。

#### 1.2.3. リクエストボディ
RecognizeRequest.Builderのsetメソッドにより、リクエストボディを追加できます。
build()メソッドでRecognizeRequestインスタンスを取得し、
recognize()に渡します。

|メソッド|引数|説明|
|---|---|---|
|setRecognizer|String|【必須】リソース名<br>形式："projects/{プロジェクトID}/locations/{ロケーションID}/recognizers/{認識ツールID}|
|setConfig|[⧉ RecognitionConfig](https://qiita.com/doran/items/c952b2f5ea58e8911337#recognitionconfig)|リクエストに使用するデフォルトの構成|
|setConfigMask|FieldMask|この認識要求中に認識エンジンのconfig値をオーバーライドするフィールドのリスト|
|setContent|ByteString|オーディオデータ(バイト)|
|setUri|String|Google Cloud Storage上のオーディオデータのURI<br>形式："gs://{bucket_name}/{object_name}"|

### 1.3. レスポンスの内容
#### RecognizeResponse
|メソッド|戻り値|説明|
|---|---|---|
|getResultsList|List\<[SpeechRecognitionResult](#speechrecognitionresult)\>|音声の連続部分に対応する文字起こし結果の連続リスト|
|getMetadata|[RecognitionResponseMetadata](#recognitionresponsemetadata)|認識に関するメタデータ|

#### SpeechRecognitionResult
|メソッド|戻り値|説明|
|---|---|---|
|getAlternativesList|List\<[SpeechRecognitionAlternative](#speechrecognitionalternative)|認識仮説|
|getChannelTag|int|マルチチャネルオーディオの認識結果に対応するチャネル番号|
|getResultEndOffset|Duration|オーディオの開始に対する終了時間オフセット|
|getLanguageCode|String|BCP-47言語タグ|

#### SpeechRecognitionAlternative
|メソッド|戻り値|説明|
|---|---|---|
|getTranscript|String|ユーザーが話した単語を表すトランスクリプトテキスト|
|getConfidence|float|信頼度推定値(0.0～1.0)|
|getWordsList|[WordInfo](#wordinfo)|認識された各単語の単語固有の情報のリスト|

#### WordInfo
|メソッド|戻り値|説明|
|---|---|---|
|getStartOffset|Duration|音声の先頭を基準とした話し言葉の先頭に対応する時間オフセット|
|getEndOffset|Duration|音声の先頭からの相対的な時間オフセット|
|getWord|String|情報セットに対応する単語|
|getConfidence|float|信頼度推定値(0.0～1.0)|
|getSpeakerLabel|String|スピーカーのラベル|

#### RecognitionResponseMetadata
|メソッド|戻り値|説明|
|---|---|---|
|getTotalBilledDuration|Duration|音声秒数の課金|

## 2. 長い音声を変換(非同期)
非同期で長い音声をテキストに変換します。

変換されたテキストファイルはCloud Storageに出力されます。
変換される[音声ファイルの形式は、LINEAR16のみ](#audioencoding)対応されています。

出力するGoogle Cloud Storageは、APIからアクセスできるように
保存先のプロジェクトにIAM権限の設定を忘れないでください。

### 2.1. スコープ
OAuth2.0でこのAPIを実行するには、以下のスコープを指定してください。
サービスアカウントで実行する場合はスコープの指定は不要です。
```
https://www.googleapis.com/auth/cloud-platform
```

### 2.2. 実行
認識ツールIDでは、"_"(デフォルト(未使用))を指定しています。

```java
public static void main(String[] args) throws Exception{
    try(SpeechClient client = getSpeechClient()){
        RecognitionConfig.Builder config = RecognitionConfig.newBuilder();
        config.addLanguageCodes("ja-JP");
        config.setModel("short");

        AutoDetectDecodingConfig.Builder decoding = AutoDetectDecodingConfig.newBuilder();
        config.setAutoDecodingConfig(decoding.build());

        BatchRecognizeFileMetadata.Builder file = BatchRecognizeFileMetadata.newBuilder();
        file.setUri("gs://{bucket_name}/{object_name}");

        BatchRecognizeRequest.Builder builder = BatchRecognizeRequest.newBuilder();
        builder.setConfig(config.build());
        builder.addFiles(file.build());
        builder.setRecognizer(String.format(
                    "projects/%s/locations/%s/recognizers/%s", 
                    "プロジェクトID","ロケーションID","_"));
        
        OperationFuture<BatchRecognizeResponse,OperationMetadata> response = client.batchRecognizeAsync(builder.build());
        
        //非同期なので終了するまで待ち
        while (!response.isDone()) {
            System.out.println("Waiting for response...");
            Thread.sleep(10000);
        }

        for(Map.Entry<String, BatchRecognizeFileResult> entry : response.get().getResultsMap().entrySet()) {
            System.out.println(entry.getKey()+" : "+entry.getValue());
        }
    }
}
```
#### 2.2.1. HTTPリクエスト
POST:　https:\//speech.googleapis.com/v2/projects/{プロジェクトID}/locations/{ロケーションID}/recognizers/{認証ツールID}:batchRecognize
が実行されます。

#### 2.2.2. クエリパラメータ
クエリパラメータはありません。

#### 2.2.3. リクエストボディ
BatchRecognizeRequest.Builderのsetメソッドにより、リクエストボディを追加できます。
build()メソッドでBatchRecognizeRequestインスタンスを取得し、
batchRecognizeAsync()に渡します。

|メソッド|引数|説明|
|---|---|---|
|setRecognizer|String|【必須】リソース名<br>形式："projects/{プロジェクトID}/locations/{ロケーションID}/recognizers/{認識ツールID}|
|setConfig|[⧉ RecognitionConfig](https://qiita.com/doran/items/c952b2f5ea58e8911337#recognitionconfig)|自動音声認識に使用する機能とオーディオメタデータ|
|setConfigMask|FieldMask|この認識要求中に認識エンジンのconfig値をオーバーライドするフィールドのリスト|
|addAllFiles|Iterable\<[BatchRecognizeFileMetadata](#batchrecognizefilemetadata)\>|ASRのファイルメタデータを含むオーディオファイル(最大5)|
|setRecognitionOutputConfig|[RecognitionOutputConfig](#recognitionoutputconfig)|各ファイルのトランスクリプトを出力する場所の構成オプション|
|setProcessingStrategy|[ProcessingStrategy(enum)](#processingstrategy)|このリクエストに使用する処理戦略|

#### BatchRecognizeFileMetadata
|メソッド|引数|説明|
|---|---|---|
|setConfig|[⧉ RecognitionConfig](https://qiita.com/doran/items/c952b2f5ea58e8911337#recognitionconfig)|自動音声認識に使用する機能とオーディオメタデータ|
|setConfigMask|FieldMask|この認識要求中に認識エンジンのconfig値をオーバーライドするフィールドのリスト|
|setUri|string|音声ファイルのクラウドストレージURI<br>形式："gs://{bucket_name}/{object_name}"|

#### RecognitionOutputConfig
|メソッド|引数|説明|
|---|---|---|
|setOutputFormatConfig|[OutputFormatConfig](#outputformatconfig)|結果の形式の構成|
|setGcsOutputConfig|[GcsOutputConfig](#gcsoutputconfig)|結果の出力先(Google Cloud Storage URI)|
|setInlineResponseConfig|[InlineOutputConfig](#inlineoutputconfig)|処理完了時の認識結果の出力有無|

#### OutputFormatConfig
|メソッド|引数|説明|
|---|---|---|
|setNative|[NativeOutputFileFormatConfig](#nativeoutputfileformatconfig)|ネイティブ出力形式の構成|
|setVtt|[VttOutputFileFormatConfig](#vttoutputfileformatconfig)|VTT出力フォーマットの設定|
|setSrt|[SrtOutputFileFormatConfig](#srtoutputfileformatconfig)|SRT出力フォーマットの設定|

#### GcsOutputConfig
|メソッド|引数|説明|
|---|---|---|
|setUri|String|認識結果が書き込まれるCloudStorageURI|

#### NativeOutputFileFormatConfig
フィールドはありません。

#### VttOutputFileFormatConfig
フィールドはありません。

#### SrtOutputFileFormatConfig
フィールドはありません。

#### InlineOutputConfig
フィールドはありません。

#### ProcessingStrategy
|定義値|内容|
|---|---|
|PROCESSING_STRATEGY_UNSPECIFIED|処理戦略のデフォルト値|
|DYNAMIC_BATCHING|使用率が低い期間にリクエストが処理され、価格が割引される|

### 2.3. レスポンスの内容
#### OperationFuture\<BatchRecognizeResponse,OperationMetadata\>
|メソッド|戻り値|説明|
|---|---|---|
|getName|String|サーバーによって割り当てられた名前<br>形式："projects/{プロジェクトID}/locations/{ロケーションID}/recognizers/{認証ツールID}"|
|isDone|boolean|操作がまだ進行中であるか|
|getPollingFuture|RetryingFuture\<[OperationSnapshot](#operationsnapshot)\>|失敗またはキャンセルされた場合の操作のエラー結果|
|get|[BatchRecognizeResponse](#batchrecognizeresponse)|認識ツールの情報|

#### OperationSnapshot
|メソッド|戻り値|説明|
|---|---|---|
|getErrorCode|StatusCode|エラーコード|
|getErrorMessage|String|開発者向けのエラーメッセージ|

#### BatchRecognizeResponse
|メソッド|戻り値|説明|
|---|---|---|
|getResultsMap|Map\<String,[BatchRecognizeFileResult](#batchrecognizefileresult)\>|ファイル名からそのファイルの最終結果マップ|
|getTotalBilledDuration|Duration|対応するリクエストの音声秒数の課金|

#### BatchRecognizeFileResult
|メソッド|戻り値|説明|
|---|---|---|
|getError|[Status](#status)|エラー情報|
|getMetadata|[RecognitionResponseMetadata](#recognitionresponsemetadata)|認識リクエストと応答に関するメタデータ|
|getCloudStorageResult|[CloudStorageResult](#cloudstorageresult)|認識結果の出力(Cloud Storage)|
|getInlineResult|[InlineResult](#inlineresult)|認識結果|

#### Status
|メソッド|戻り値|説明|
|---|---|---|
|getCode|int|ステータスコード|
|getMessage|String|開発者向けのエラーメッセージ|
|getDetailsList|List\<Any\>|エラーの詳細を伝えるメッセージのリスト|

#### CloudStorageResult
|メソッド|戻り値|説明|
|---|---|---|
|getUri|String|認識結果が書き込まれるCloudStorageURI|
|getVttFormatUri|String|認識結果がVTT形式のキャプションとして書き込まれるCloudStorageURI|
|getSrtFormatUri|String|認識結果がSRT形式のキャプションとして書き込まれるCloudStorageURI|

#### InlineResult
|メソッド|戻り値|説明|
|---|---|---|
|getTranscript|[BatchRecognizeResults](#batchrecognizeresults)|音声ファイルのトランスクリプト|
|getVttCaptions|String|VTT形式のキャプションとしての音声ファイルのトランスクリプト|
|getSrtCaptions|String|SRT形式のキャプションとしての音声ファイルのトランスクリプト|

#### BatchRecognizeResults
|メソッド|戻り値|説明|
|---|---|---|
|getResultsList|List\<[SpeechRecognitionResult](#speechrecognitionresult)\>|音声の連続部分に対応する文字起こし結果の連続リスト|
|getMetadata|[RecognitionResponseMetadata](#recognitionresponsemetadata)|認識に関するメタデータ|

#### AudioEncoding
|定義値|内容|
|---|---|
|AUDIO_ENCODING_UNSPECIFIED|デフォルト値|
|LINEAR16|ヘッダーなしの16ビット符号付きリトルエンディアンPCMサンプル|
|MULAW|ヘッダーなしの8ビット圧縮されたmulawサンプル|
|ALAW|ヘッダーなしの8ビット圧縮されたalawサンプル|

<br>
<br>
おしまい。。