CLOVA Speech長文認識の API
    • PDF

    CLOVA Speech長文認識の API

    • PDF

    Article Summary

    Classic/VPC環境で利用できます。

    version

    VersionDateChanges
    v1.0.02020.9.17.初回作成
    V1.1.02020.11.18.強調(Boosting)、禁則文字(Forbidden)を追加
    V1.2.02021.4.8.話者認識機能を追加
    V1.3.02021.5.27.英語認識機能を追加
    V1.4.02021.7.22.韓国語/英語の同時認識機能を追加
    V1.5.02021.11.25.非同期モードに対応
    V1.6.02022.2.17.日本語認識機能を追加
    V1.7.02022.6.8.domain boosting support
    V1.8.02022.10.20.中文繁体、簡体認識機能を追加
    V1.9.02022.12.15.ノイズフィルタ機能を追加
    V2.0.02023.12.21.イベント検知機能を追加
    V2.1.02024.03.21.字幕の抽出機能を追加

    リクエスト

    MethodRequest URI
    POSTCLOVA Speechドメインで作成された API Gatewayの InvokeURLで呼び出します。
    ドメインごとに固有の呼び出し URLが作成されます。

    CLOVA Speech APIの使用方法

    CLOVA Speech APIは3つの方法から選択できます。

    • object storageファイル urlで認識をリクエスト: object storageに保存されているファイルの固有 urlを利用します(認識したいファイルは、まず object storageにアップロードされている必要があります)。
    • 外部 urlで認識をリクエスト: 外部からアクセス可能なファイルの固有 urlを利用します。
    • ローカルのファイルをアップロードしてリクエスト: ファイルシステムのパスを利用します。

    認識リクエスト後のレスポンスは2つの方法で行えます。

    • sync: syncでリクエスト時、認識が完了すると response結果(json)を受け取り、
    • async: asyncでリクエスト時、リクエスト時に入力した Callback urlアドレスまたは ResultToObs(ObjectStorage)へ認識結果を返します。
    Callback urlresultToObs(ObjectStorage)result
    URLアドレスあり(O)TrueCallback urlと ObjectStorageのすべての結果を返す
    URLアドレスあり(O)FalseCallback urlへのみ結果を返す
    URLアドレスなし(X)TrueObjectStorageにのみ結果を返す
    URLアドレスなし(X)Falseエラーを返す

    1. Object Storageファイル urlで認識をリクエスト

    object storageに保存されているファイルの固有 urlを利用します。認識したいファイルは、まず object storageにアップロードされている必要があります。

    POST /recognizer/object-storage

    • recognize media from object storage
    MethodRequest URI
    POST${Invoke URL}/recognizer/object-storage

    リクエストヘッダ

    ヘッダ名説明
    Content-Typeapplication/json

    リクエストボディ

    namedesctyperequirementvaluedefault
    dataKey認識するファイルの ObjectStorageパスへアクセスするための Keystringrequired
    languagelanguagestringrequiredko-KR, en-US, enko, ja, zh-cn, zh-twko-KR
    completionsync, async方式の中から選択stringoptionalasync
    callbackCallback部分を参照stringoptional
    userdatajson objectobjectoptional
    wordAlignment認識結果に word alignmentを出力booleanoptionaltrue
    fullText全体認識結果のテキストを出力booleanoptionaltrue
    resultToObsドメインの作成時に選択した保存場所(Object Storage)に結果を保存booleanoptionalfalse
    noiseFilteringノイズフィルタリングの有無booleanoptionaltrue
    boostingsboosting object arrayarrayoptional
    boostings.wordscomma separated wordsstringoptional
    useDomainBoostingsuse domain boostingsbooleanoptionalfalse
    forbiddenscomma separated wordsstringoptional
    diarization話者認識(diarization)の設定objectoptional
    diarization.enable話者認識の有無booleanoptionaltrue
    sedevent detectobjectoptional
    sed.enableevent detectbooleanoptionalfalse
    formatresponse formatstringoptionalJSON, SRT, SMIJSON

    Example (cURL shell)

    curl --location --request POST '${Invoke URL}/recognizer/object-storage' \  
    --header 'X-CLOVASPEECH-API-KEY: ${Secret Key}' \  
    --header 'Content-Type: application/json' \  
    --data-raw '{  
      "language": "ko-KR",  
      "callback": "http://example/callback",  
      "userdata": {  
        "dataId": "1"  
      },  
      "boostings": [  
      	{  
      		"words": "comma separated words"  
      	}  
      ],  
      "forbiddens": "comma separated words",  
      "completion":"async",  
      "dataKey": "data/sample.wav"  
    }'  
    
    • Response: refer to Common Response

    2. 外部 urlへ認識をリクエスト

    外部からアクセス可能なファイルの固有 urlを利用します。

    POST /recognizer/url

    • recognize media from URL
    MethodRequest URI
    POST${Invoke URL}/recognizer/url

    リクエストヘッダ

    ヘッダ名説明
    Content-Typeapplication/json

    リクエストボディ

    namedesctyperequirementvaluedefault
    urlthe media URLstringrequired
    languagelanguagestringrequiredko-KR, en-US, enko, ja, zh-cn, zh-twko-KR
    completionsync方式と async方式の中で選択stringoptionalasync
    callbackCallback部分を参照stringoptional
    userdatajson objectobjectoptional
    wordAlignment認識結果に word alignmentを出力booleanoptionaltrue
    fullText全体認識結果のテキストを出力booleanoptionaltrue
    resultToObsドメインの作成時に選択した保存場所(Object Storage)に結果を保存booleanoptionalfalse
    noiseFilteringノイズフィルタリングの有無booleanoptionaltrue
    boostingsboosting object arrayarrayoptional
    boostings.wordscomma separated wordsstringoptional
    useDomainBoostingsuse domain boostingsbooleanoptionalfalse
    forbiddenscomma separated wordsstringoptional
    diarization話者認識(diarization)の設定objectoptional
    diarization.enable話者認識の有無booleanoptionaltrue
    sedevent detectobjectoptional
    sed.enableevent detectbooleanoptionalfalse
    formatresponse formatstringoptionalJSON, SRT, SMIJSON
    • キーワードブースト
      • 認識率を高めたいキーワードリストを APIリクエストボディに含めることができます。
      • リクエストボディの params.boostingsparams.boostings.words フィールドを参照します。
      • 対応するブースト可能なキーワード数は最大1000件までです。
      • ブースト可能な文字はハングル、英語のみ対応します。
      • noのように1音節の単語は間違って認識するおそれがあるため、ブーストは対応しません。
      • 英語の認識結果は基本的に小文字に変換されますが、大文字キーワードをブーストリクエストすると、大文字に置き換えられます。
      • 分かち書きの有無と関係なくブースト処理します。
        例えば、「CLOVASpeech」と「CLOVA Speech」の場合、そのうち1つのキーワードのみブーストリクエストされます。
      • キーワードの長さに制限はありませんが、ブーストする対象が複数の単語の組み合わせによる構文の場合は、その構文でないとブーストの影響を受けにくいです。例えば、「CLOVA Speech」というキーワードをブーストすると、「CLOVA Speech」が含まれているすべての文章がブーストの影響を受けます。一方、「CLOVA Speechのメディア音声認識技術」というような複数の単語の組み合わせによる長いキーワードをブーストすると、「CLOVA Speech」だけが入った文章はブーストの影響を受けにくくなります。
    • 除外キーワード検出
      • 認識結果に表示させたくないキーワードリストを APIリクエストボディに含めることができます。
      • リクエストボディの params.forbiddensフィールドを参照します。
      • 除外キーワードには個数や長さに制限はありません。
      • 分かち書き、英字の大小文字がすべて 完全一致 した場合のみ検出処理が可能です。

    Example (cURL shell)

    curl --location --request POST '${Invoke URL}/recognizer/url' \  
    --header 'X-CLOVASPEECH-API-KEY: ${Secret Key}' \  
    --header 'Content-Type: application/json' \  
    --data-raw '{  
      "language": "ko-KR",  
      "callback": "http://example/callback",  
      "userdata": {  
        "dataId": "1"  
      },  
      "boostings": [  
      {  
        "words": "comma separated words"  
      }],  
      "forbiddens": "comma separated words",  
      "completion":"async",  
      "url": "https://kr.object.ncloudstorage.com/nest/data/IMG_3866.mp4"  
    }'  
    
    • Response: refer to Common Response

    3. ローカルのファイルアップロードをしてリクエスト

    ローカルファイルシステムのパスを利用します。

    POST /recognizer/upload

    • upload a media for recognize
    MethodRequest URI
    POST${Invoke URL}/recognizer/upload

    リクエストヘッダ

    ヘッダ名説明
    Content-Typemultipart/form-data

    リクエストボディ

    namedesctyperequirementvaluedefault
    mediathe media filefilerequired
    paramsobjectrequired
    params.languagelanguagestringrequiredko-KR, en-US, enko, ja, zh-cn, zh-twko-KR
    params.completionsync, asyncstringoptionalasync
    params.callbackrefer to Callbackstringoptional
    params.userdatajson objectobjectoptional
    params.wordAlignment認識結果に word alignmentを出力booleanoptionaltrue
    params.fullText全体認識結果のテキストを出力booleanoptionaltrue
    params.resultToObsドメインの作成時に選択した保存場所(Object Storage)に結果を保存booleanoptionalfalse
    params.noiseFilteringノイズフィルタリングの有無booleanoptionaltrue
    params.boostingsboosting object arrayarrayoptional
    params.boostings.wordscomma separated wordsstringoptional
    params.useDomainBoostingsuse domain boostingsbooleanoptionalfalse
    params.forbiddenscomma separated wordsstringoptional
    params.diarization話者認識(diarization)の設定objectoptional
    params.diarization.enable話者認識の有無booleanoptionaltrue
    sedイベント検知objectoptional
    sed.enableイベント検知の使用有無booleanoptionalfalse
    formatresponse formatstringoptionalJSON, SRT, SMIJSON
    • キーワードブースト
      • 認識率を高めたいキーワードリストを APIリクエストボディに含めることができます。
      • リクエストボディの params.boostingsparams.boostings.words フィールドを参照します。
      • 対応するブースト可能なキーワード数は最大1000件までです。
      • ブースト可能なキーワードは韓国語、英語、日本語、数字のみです。
      • 英語の認識結果は基本的に小文字に変換されますが、大文字キーワードをブーストリクエストすると、大文字に置き換えられます。
      • 分かち書きの有無と関係なくブースト処理します。
        例えば、「CLOVASpeech」と「CLOVA Speech」の場合、そのうち1つのキーワードのみブーストリクエストされます。
      • キーワードの長さに制限はありませんが、ブーストする対象が複数の単語の組み合わせによる構文の場合は、その構文でないとブーストの影響を受けにくいです。例えば、「CLOVA Speech」というキーワードをブーストすると、「CLOVA Speech」が含まれているすべての文章がブーストの影響を受けます。一方、「CLOVA Speechのメディア音声認識技術」というような複数の単語の組み合わせによる長いキーワードをブーストすると、「CLOVA Speech」だけが入った文章はブーストの影響を受けにくくなります。
    • 除外キーワード検出
      • 認識結果に表示させたくないキーワードリストを APIリクエストボディに含めることができます。
      • リクエストボディの params.forbiddensフィールドを参照します。
      • 除外キーワード検出には個数や長さに制限はありません。
      • 分かち書き、英字の大小文字がすべて完全一致した場合のみ検出処理が可能です。

    Example (cURL shell)

    curl --location --request POST '${Invoke URL}/recognizer/upload' \
    --header 'X-CLOVASPEECH-API-KEY: ${Secret Key}' \
    --form 'media=@/video/sample.wav' \
    --form 'params={"language":"ko-KR","completion":"sync","callback":"http://localhost:9010","forbiddens":"comma separated words","boostings":[{"words": "comma separated words"}]};type=application/json'
    
    • Response: refer to Common Response

    レスポンス

    認識リクエスト後のレスポンスは2つの方法で行えます。

    1. sync

      syncでリクエスト時、認識が完了すると response結果(json)を受け取り

    2. async

      asyncでリクエスト時、リクエスト時に入力し Callback urlアドレスまたは ResultToObs(ObjectStorage)へ認識結果を返します。

    Callback urlresultToObs(ObjectStorage)result
    URLアドレスあり(O)TrueCallback urlと ObjectStorageのすべての結果を返す
    URLアドレスあり(O)FalseCallback urlへのみ結果を返す
    URLアドレスなし(X)TrueObjectStorageにのみ結果を返す
    URLアドレスなし(X)Falseエラーを返す

    Callback

    リクエストヘッダ

    ヘッダ名説明
    Content-Typeapplication/application-json; charset=utf-8
    • Method

      Method
      POST
    • Body

      • Same as Common Response(sync)

    4. Get job status

    GET /recognizer/{token}

    • Get the status of async request
    MethodRequest URI
    GET${Invoke URL}/recognizer/{token}

    リクエストヘッダ

    ヘッダ名説明
    Content-Typeapplication/json

    リクエストボディ

    namedesctyperequirementvaluedefault
    tokentokenstringrequired

    Example (cURL shell)

    curl --location --request GET '${Invoke URL}/recognizer/ceb77af3dae44a6c8c4de3dce519140a' \
    --header 'X-CLOVASPEECH-API-KEY: ${Secret Key}'
    
    • Response
    {
        "token": "ceb77af3dae44a6c8c4de3dce519140a",
        "result": "PROCESSING"
    }
    

    result:

    • WAITING
    • PROCESSING
    • FAILED
    • COMPLETED
    • TIMEOUT

    Common Response

    • Response(async)

      {
          "token": "a951af6a1015466bae2c926177f26310",
          "result": "SUCCEEDED",
          "message": "Succeeded"
      }
      
    • Response(sync)

      {
          "result": "COMPLETED",
          "message": "Succeeded",
          "token": "d3bea166039e486abbb90e4a84c3b3a5",
          "version": "ncp_v2_v2.3.0-aa6cd8d-20231205_231211-3cf30bfc_v0.0.0_",
          "params": {
              "service": "ncp",
              "domain": "general",
              "lang": "enko",
              "completion": "sync",
              "callback": "",
              "diarization": {
                  "enable": true,
                  "speakerCountMin": -1,
                  "speakerCountMax": -1
              },
              "sed": {
                  "enable": true
              },
              "boostings": [
                  {
                      "words": "こんにちは。テスト"
                  }
              ],
              "forbiddens": "",
              "wordAlignment": true,
              "fullText": true,
              "noiseFiltering": true,
              "resultToObs": false,
              "priority": 0,
              "userdata": {
                  "_ncp_DomainCode": "NEST",
                  "_ncp_DomainId": 1,
                  "_ncp_TaskId": 55442,
                  "_ncp_TraceId": "36a75ce98ec342d8a8c8fe9191cec343",
                  "id": 1
              }
          },
          "progress": 100,
          "keywords": {},
          "segments": [
              {
                  "start": 5870,
                  "end": 8160,
                  "text": "ソウルプールです。",
                  "confidence": 0.9626975,
                  "diarization": {
                      "label": "2"
                  },
                  "speaker": {
                      "label": "2",
                      "name": "B",
                      "edited": false
                  },
                  "words": [
                      [
                          5871,
                          6730,
                          "ソウル"
                      ],
                      [
                          6860,
                          7530,
                          "プールです。"
                      ]
                  ],
                  "textEdited": "ソウルプールです。"
              },
              {
                  "start": 8160,
                  "end": 12950,
                  "text": "入場料はいくらですか? 5千ウォンです。ありがとうございました。",
                  "confidence": 0.8835926,
                  "diarization": {
                      "label": "1"
                  },
                  "speaker": {
                      "label": "1",
                      "name": "A",
                      "edited": false
                  },
                  "words": [
                      [
                          8161,
                          9220,
                          "入場料は"
                      ],
                      [
                          9390,
                          10020,
                          "いくらですか?"
                      ],
                      [
                          10410,
                          10640,
                          "5千"
                      ],
                      [
                          10710,
                          11140,
                          "ウォンです。"
                      ],
                      [
                          11910,
                          12500,
                          "ありがとうございました。"
                      ]
                  ],
                  "textEdited": "入場料はいくらですか? 5千ウォンです。ありがとうございました。"
              }
          ],
          "text": "ソウルプールです。入場料はいくらですか? 5千ウォンです。ありがとうございました。",
          "confidence": 0.9071357,
          "speakers": [
              {
                  "label": "1",
                  "name": "A",
                  "edited": false
              },
              {
                  "label": "2",
                  "name": "B",
                  "edited": false
              }
          ],
          "events": [
              {
                  "type": "music",
                  "label": "music",
                  "labelEdited": "music",
                  "start": 1400,
                  "end": 5000
              }
          ],
          "eventTypes": [
              "music"
          ]
      }
      
      • Body

        fielddesctype
        result結果コードstring
        message結果メッセージstring
        token結果トークンstring
        versionエンジンバージョンstring
        paramsパラメータobject
        params: serviceサービスコードstring
        params: domainドメインstring
        params: lang認識言語string
        params: completionリクエスト方式string
        params: diarization話者分離情報object
        params: diarization.enable話者分離使用可否boolean
        params: diarization.speakerCountMin最小話者数number
        params: diarization.speakerCountMax最大話者数number
        params: boostingsブースト情報array
        params: boostings: wordsブーストキーワードstring
        params: forbiddens除外キーワードstring
        params: fullText全体認識結果のテキスト出力の有無boolean
        params: noiseFilteringノイズフィルタリングの有無boolean
        params: resultToObsObject Storage保存の有無boolean
        params: segmentセグメントstring
        params: morpheme形態素string
        params: completion同期 非同期string
        params: userdataユーザーデータobject
        segmentsセグメント情報array
        segments: startセグメント開始時刻(ms)number
        segments: endセグメント終了時刻(ms)number
        segments: textセグメントテキストstring
        segments: textEdited変更内容string
        segments: diarization認識された話者object
        segments: diarization.label認識話者 Numberstring
        segments: speaker変更された話者object
        segments: speaker.label変更話者 Numberstring
        segments: speaker.name変更話者名string
        segments: confidenceセグメントの信頼性(0.0~1.0)number
        segments: wordsセグメント節array
        segments: words: [0]セグメント節開始時刻(ms)number
        segments: words: [1]セグメント節終了時刻(ms)number
        segments: words: [2]セグメント節テキストstring
        text全体テキストstring
        confidence全体の信頼性number
        eventsイベントarray
        events.typeイベントタイプstring
        events.labelイベント名string
        events.labelEditedイベント変更名string
        events.startイベント開始時間number
        events.endイベント終了時間number
    • SRT format

    1
    00:00:00,000 --> 00:00:01,425 
    A: あの、この前
    
    2
    00:00:02,533 --> 00:00:11,550 
    A: トウモロコシを食べたんですよ。本当に甘くて美味しかったんですけど、私ってそれが町の名前かと思ってたの。
    
    3
    00:00:11,550 --> 00:00:19,025 
    A: チョダンってあの超と甘いの糖って知りませんでしたよ。知らなかった。私って草堂が超糖豆腐みたいなものだと思ってたの。
    
    4
    00:00:19,025 --> 00:00:26,317 
    C: サッカリンと思ったんですよ。ちょっと。作者さん超糖で召し上がってましたけど。
    
    5
    00:00:26,317 --> 00:00:28,240 
    A: トウモロコシですか?
    
    6
    00:00:28,240 --> 00:00:35,318 
    B: いや、豆腐って甘い味の豆腐ってありえるかよ。今この道は理解できないね。上道って草堂の地域じゃなかったっけ?
    
    7
    00:00:35,318 --> 00:00:42,800 
    A: いや。超糖トウモロコシはスーパースイートという意味だったの。超甘いって誰も理解していませんね。今。
    
    • SMI format
    <SAMI>
    <Body>
      <SYNC Start=0>
        <P>A: あの、この前
      <SYNC Start=2533>
        <P>A: トウモロコシを食べたんですよ。本当に甘くて美味しかったんですけど、私ってそれが町の名前かと思ってたの。
      <SYNC Start=11550>
        <P>A: チョダンってあの超と甘いの糖って知りませんでしたよ。知らなかった。私って草堂が超糖豆腐みたいなものだと思ってたの。
      <SYNC Start=19025>
        <P>C: サッカリンと思ったんですよ。ちょっと。作者さん超糖で召し上がってましたけど。
      <SYNC Start=26317>
        <P>A: トウモロコシですか?
      <SYNC Start=28240>
        <P>B: いや、豆腐って甘い味の豆腐ってありえるかよ。今この道は理解できないね。上道って草堂の地域じゃなかったっけ?
      <SYNC Start=35318>
        <P>A: いや。超糖トウモロコシはスーパースイートという意味だったの。超甘いって誰も理解していませんね。今。
    </Body>
    </SAMI>
    

    Examples

    Java

    dependency

    <dependency>
        <groupId>org.apache.httpcomponents</groupId>
        <artifactId>httpclient</artifactId>
        <version>4.5.12</version>
    </dependency>
    <dependency>
        <groupId>org.apache.httpcomponents</groupId>
        <artifactId>httpmime</artifactId>
        <version>4.3.1</version>
    </dependency>
    <dependency>
        <groupId>com.google.code.gson</groupId>
        <artifactId>gson</artifactId>
        <version>2.8.5</version>
    </dependency>
    

    ClovaSpeechClient

    package org.example.clovaspeech.client;
    
    import java.io.File;
    import java.nio.charset.StandardCharsets;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    
    import org.apache.http.Header;
    import org.apache.http.HttpEntity;
    import org.apache.http.client.methods.CloseableHttpResponse;
    import org.apache.http.client.methods.HttpPost;
    import org.apache.http.entity.ContentType;
    import org.apache.http.entity.StringEntity;
    import org.apache.http.entity.mime.MultipartEntityBuilder;
    import org.apache.http.impl.client.CloseableHttpClient;
    import org.apache.http.impl.client.HttpClients;
    import org.apache.http.message.BasicHeader;
    import org.apache.http.util.EntityUtils;
    
    import com.google.gson.Gson;
    
    public class ClovaSpeechClient {
    
        // Clova Speech secret key
    	private static final String SECRET = "";
        // Clova Speech invoke URL
    	private static final String INVOKE_URL = "";
    
    	private CloseableHttpClient httpClient = HttpClients.createDefault();
    	private Gson gson = new Gson();
    
    	private static final Header[] HEADERS = new Header[] {
    		new BasicHeader("Accept", "application/json"),
    		new BasicHeader("X-CLOVASPEECH-API-KEY", SECRET),
    	};
    
        	public static class Boosting {
    		private String words;
    
    		public String getWords() {
    			return words;
    		}
    
    		public void setWords(String words) {
    			this.words = words;
    		}
    	}
    
    	public static class Diarization {
    		private Boolean enable = Boolean.FALSE;
    		private Integer speakerCountMin;
    		private Integer speakerCountMax;
    
    		public Boolean getEnable() {
    			return enable;
    		}
    
    		public void setEnable(Boolean enable) {
    			this.enable = enable;
    		}
    
    		public Integer getSpeakerCountMin() {
    			return speakerCountMin;
    		}
    
    		public void setSpeakerCountMin(Integer speakerCountMin) {
    			this.speakerCountMin = speakerCountMin;
    		}
    
    		public Integer getSpeakerCountMax() {
    			return speakerCountMax;
    		}
    
    		public void setSpeakerCountMax(Integer speakerCountMax) {
    			this.speakerCountMax = speakerCountMax;
    		}
    	}
    
        public static class Sed {
    		private Boolean enable = Boolean.FALSE;
    
    		public Boolean getEnable() {
    			return enable;
    		}
    
    		public void setEnable(Boolean enable) {
    			this.enable = enable;
    		}
    	}
    
    	public static class NestRequestEntity {
    		private String language = "ko-KR";
    		//completion optional, sync/async
    		private String completion = "sync";
    		//optional, used to receive the analyzed results
    		private String callback;
    		//optional, any data
    		private Map<String, Object> userdata;
    		private Boolean wordAlignment = Boolean.TRUE;
    		private Boolean fullText = Boolean.TRUE;
    		//boosting object array
    		private List<Boosting> boostings;
    		//comma separated words
    		private String forbiddens;
    		private Diarization diarization;
            private Sed sed;
    
            public Sed getSed() {
    			return sed;
    		}
    
    		public void setSed(Sed sed) {
    			this.sed = sed;
    		}
            
    		public String getLanguage() {
    			return language;
    		}
    
    		public void setLanguage(String language) {
    			this.language = language;
    		}
    
    		public String getCompletion() {
    			return completion;
    		}
    
    		public void setCompletion(String completion) {
    			this.completion = completion;
    		}
    
    		public String getCallback() {
    			return callback;
    		}
    
    		public Boolean getWordAlignment() {
    			return wordAlignment;
    		}
    
    		public void setWordAlignment(Boolean wordAlignment) {
    			this.wordAlignment = wordAlignment;
    		}
    
    		public Boolean getFullText() {
    			return fullText;
    		}
    
    		public void setFullText(Boolean fullText) {
    			this.fullText = fullText;
    		}
    
    		public void setCallback(String callback) {
    			this.callback = callback;
    		}
    
    		public Map<String, Object> getUserdata() {
    			return userdata;
    		}
    
    		public void setUserdata(Map<String, Object> userdata) {
    			this.userdata = userdata;
    		}
    
    		public String getForbiddens() {
    			return forbiddens;
    		}
    
    		public void setForbiddens(String forbiddens) {
    			this.forbiddens = forbiddens;
    		}
    
    		public List<Boosting> getBoostings() {
    			return boostings;
    		}
    
    		public void setBoostings(List<Boosting> boostings) {
    			this.boostings = boostings;
    		}
    
    		public Diarization getDiarization() {
    			return diarization;
    		}
    
    		public void setDiarization(Diarization diarization) {
    			this.diarization = diarization;
    		}
    	}
    
    	/**
    	 * recognize media using URL
    	 * @param url required, the media URL
    	 * @param nestRequestEntity optional
    	 * @return string
    	 */
    	public String url(String url, NestRequestEntity nestRequestEntity) {
    		HttpPost httpPost = new HttpPost(INVOKE_URL + "/recognizer/url");
    		httpPost.setHeaders(HEADERS);
    		Map<String, Object> body = new HashMap<>();
    		body.put("url", url);
    		body.put("language", nestRequestEntity.getLanguage());
    		body.put("completion", nestRequestEntity.getCompletion());
    		body.put("callback", nestRequestEntity.getCallback());
    		body.put("userdata", nestRequestEntity.getCallback());
    		body.put("wordAlignment", nestRequestEntity.getWordAlignment());
    		body.put("fullText", nestRequestEntity.getFullText());
    		body.put("forbiddens", nestRequestEntity.getForbiddens());
    		body.put("boostings", nestRequestEntity.getBoostings());
    		body.put("diarization", nestRequestEntity.getDiarization());
            body.put("sed", nestRequestEntity.getSed());
    		HttpEntity httpEntity = new StringEntity(gson.toJson(body), ContentType.APPLICATION_JSON);
    		httpPost.setEntity(httpEntity);
    		return execute(httpPost);
    	}
    
    	/**
    	 * recognize media using Object Storage
    	 * @param dataKey required, the Object Storage key
    	 * @param nestRequestEntity optional
    	 * @return string
    	 */
    	public String objectStorage(String dataKey, NestRequestEntity nestRequestEntity) {
    		HttpPost httpPost = new HttpPost(INVOKE_URL + "/recognizer/object-storage");
    		httpPost.setHeaders(HEADERS);
    		Map<String, Object> body = new HashMap<>();
    		body.put("dataKey", dataKey);
    		body.put("language", nestRequestEntity.getLanguage());
    		body.put("completion", nestRequestEntity.getCompletion());
    		body.put("callback", nestRequestEntity.getCallback());
    		body.put("userdata", nestRequestEntity.getCallback());
    		body.put("wordAlignment", nestRequestEntity.getWordAlignment());
    		body.put("fullText", nestRequestEntity.getFullText());
    		body.put("forbiddens", nestRequestEntity.getForbiddens());
    		body.put("boostings", nestRequestEntity.getBoostings());
    		body.put("diarization", nestRequestEntity.getDiarization());
            body.put("sed", nestRequestEntity.getSed());
    		StringEntity httpEntity = new StringEntity(gson.toJson(body), ContentType.APPLICATION_JSON);
    		httpPost.setEntity(httpEntity);
    		return execute(httpPost);
    	}
    
    	/**
    	 *
    	 * recognize media using a file
    	 * @param file required, the media file
    	 * @param nestRequestEntity optional
    	 * @return string
    	 */
    	public String upload(File file, NestRequestEntity nestRequestEntity) {
    		HttpPost httpPost = new HttpPost(INVOKE_URL + "/recognizer/upload");
    		httpPost.setHeaders(HEADERS);
    		HttpEntity httpEntity = MultipartEntityBuilder.create()
    			.addTextBody("params", gson.toJson(nestRequestEntity), ContentType.APPLICATION_JSON)
    			.addBinaryBody("media", file, ContentType.MULTIPART_FORM_DATA, file.getName())
    			.build();
    		httpPost.setEntity(httpEntity);
    		return execute(httpPost);
    	}
    
    	private String execute(HttpPost httpPost) {
    		try (final CloseableHttpResponse httpResponse = httpClient.execute(httpPost)) {
    			final HttpEntity entity = httpResponse.getEntity();
    			return EntityUtils.toString(entity, StandardCharsets.UTF_8);
    		} catch (Exception e) {
    			throw new RuntimeException(e);
    		}
    	}
    
    	public static void main(String[] args) {
    		final ClovaSpeechClient clovaSpeechClient = new ClovaSpeechClient();
    		NestRequestEntity requestEntity = new NestRequestEntity();
    		final String result =
    			clovaSpeechClient.upload(new File("/data/sample.mp4"), requestEntity);
    		//final String result = clovaSpeechClient.url("file URL", requestEntity);
    		//final String result = clovaSpeechClient.objectStorage("Object Storage key", requestEntity);
    		System.out.println(result);
    	}
    }
    

    Python

    import requests
    import json
    
    
    class ClovaSpeechClient:
        # Clova Speech invoke URL
        invoke_url = ''
        # Clova Speech secret key
        secret = ''
    
        def req_url(self, url, completion, callback=None, userdata=None, forbiddens=None, boostings=None, wordAlignment=True, fullText=True, diarization=None, sed=None):
            request_body = {
                'url': url,
                'language': 'ko-KR',
                'completion': completion,
                'callback': callback,
                'userdata': userdata,
                'wordAlignment': wordAlignment,
                'fullText': fullText,
                'forbiddens': forbiddens,
                'boostings': boostings,
                'diarization': diarization,
                'sed': sed,
            }
            headers = {
                'Accept': 'application/json;UTF-8',
                'Content-Type': 'application/json;UTF-8',
                'X-CLOVASPEECH-API-KEY': self.secret
            }
            return requests.post(headers=headers,
                                 url=self.invoke_url + '/recognizer/url',
                                 data=json.dumps(request_body).encode('UTF-8'))
    
        def req_object_storage(self, data_key, completion, callback=None, userdata=None, forbiddens=None, boostings=None,
                               wordAlignment=True, fullText=True, diarization=None, sed=None):
            request_body = {
                'dataKey': data_key,
                'language': 'ko-KR',
                'completion': completion,
                'callback': callback,
                'userdata': userdata,
                'wordAlignment': wordAlignment,
                'fullText': fullText,
                'forbiddens': forbiddens,
                'boostings': boostings,
                'diarization': diarization,
                'sed': sed,
            }
            headers = {
                'Accept': 'application/json;UTF-8',
                'Content-Type': 'application/json;UTF-8',
                'X-CLOVASPEECH-API-KEY': self.secret
            }
            return requests.post(headers=headers,
                                 url=self.invoke_url + '/recognizer/object-storage',
                                 data=json.dumps(request_body).encode('UTF-8'))
    
        def req_upload(self, file, completion, callback=None, userdata=None, forbiddens=None, boostings=None,
                       wordAlignment=True, fullText=True, diarization=None, sed=None):
            request_body = {
                'language': 'ko-KR',
                'completion': completion,
                'callback': callback,
                'userdata': userdata,
                'wordAlignment': wordAlignment,
                'fullText': fullText,
                'forbiddens': forbiddens,
                'boostings': boostings,
                'diarization': diarization,
                'sed': sed,
            }
            headers = {
                'Accept': 'application/json;UTF-8',
                'X-CLOVASPEECH-API-KEY': self.secret
            }
            print(json.dumps(request_body, ensure_ascii=False).encode('UTF-8'))
            files = {
                'media': open(file, 'rb'),
                'params': (None, json.dumps(request_body, ensure_ascii=False).encode('UTF-8'), 'application/json')
            }
            response = requests.post(headers=headers, url=self.invoke_url + '/recognizer/upload', files=files)
            return response
    
    if __name__ == '__main__':
        # res = ClovaSpeechClient().req_url(url='http://example.com/media.mp3', completion='sync')
        # res = ClovaSpeechClient().req_object_storage(data_key='data/media.mp3', completion='sync')
        res = ClovaSpeechClient().req_upload(file='/data/media.mp3', completion='sync')
        print(res.text)
    

    PHP

    <?php
    
    $secret = '';
    $invoke_url = '';
    
    function req_url($url, $completion, $callback, $userdata, $forbiddens, $boostings,
                     $wordAlignment, $fullText, $diarization, $sed)
    {
        $object = (object)[
            'language' => 'ko-KR',
            'completion' => $completion,
            'callback' => $callback,
            'url' => $url,
            'userdata' => $userdata,
            'forbiddens' => $forbiddens,
            'boostings' => $boostings,
            'wordAlignment' => $wordAlignment,
            'fullText' => $fullText,
            'diarization' => $diarization,
            'sed' => $sed,
        ];
        return execute('/recognizer/url', json_encode($object), array('Content-Type: application/json'));
    }
    
    function req_object_storage($dataKey, $completion, $callback, $userdata, $forbiddens, $boostings,
                                $wordAlignment, $fullText, $diarization, $sed)
    {
        $object = (object)[
            'language' => 'ko-KR',
            'completion' => $completion,
            'callback' => $callback,
            'dataKey' => $dataKey,
            'userdata' => $userdata,
            'forbiddens' => $forbiddens,
            'boostings' => $boostings,
            'wordAlignment' => $wordAlignment,
            'fullText' => $fullText,
            'diarization' => $diarization,
            'sed' => $sed,
        ];
        return execute('/recognizer/object-storage', json_encode($object), array('Content-Type: application/json'));
    }
    
    function req_upload($filePath, $completion, $callback, $userdata, $forbiddens, $boostings,
                        $wordAlignment, $fullText, $diarization, $sed)
    {
        $object = (object)[
            'language' => 'ko-KR',
            'completion' => $completion,
            'callback' => $callback,
            'userdata' => $userdata,
            'forbiddens' => $forbiddens,
            'boostings' => $boostings,
            'wordAlignment' => $wordAlignment,
            'fullText' => $fullText,
            'diarization' => $diarization,
            'sed' => $sed,
        ];
        $fields = array(
            'media' => new CURLFile($filePath),
            'params' => json_encode($object),
        );
        return execute('/recognizer/upload', $fields, null);
    }
    
    function execute($uri, $postFields, $customHeaders)
    {
        try {
            $ch = curl_init($GLOBALS['invoke_url'] . $uri);
            curl_setopt($ch, CURLOPT_POST, true);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
            curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
            curl_setopt($ch, CURLOPT_POSTFIELDS, $postFields);
            curl_setopt($ch, CURLOPT_VERBOSE, true);
            curl_setopt($ch, CURLOPT_TIMEOUT, 600);
            $headers = array();
            $headers[] = 'X-CLOVASPEECH-API-KEY: ' . $GLOBALS['secret'];
            if (!is_null($customHeaders)) {
                $headers = array_merge($headers, $customHeaders);
            }
            curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
            $response = curl_exec($ch);
            $err = curl_error($ch);
            curl_close($ch);
            if ($err) {
                echo 'cURL Error #:' . $err;
                return $err;
            }
            return $response;
        } catch (Exception $E) {
            echo 'Response: ' . $E . '\n';
            return $E->lastResponse;
        }
    }
    
    //$response = req_url('https://example.com/sample.mp4', 'sync', null, null, null, null, null, null, null);
    //$response = req_object_storage('data/sample.mp4', 'sync', null, null, null, null, null, null, null);
    $response = req_upload('/data/sample.mp4', 'sync', null, null, null, null, null, null, null);
    echo $response;
    ?>
    

    C#

    using System;
    using System.Globalization;
    using System.Net.Http;
    using System.Net.Http.Headers;
    using System.Text.RegularExpressions;
    using System.Threading.Channels;
    using System.Threading.Tasks;
    using System.Text.Json;
    using System.Text.Json.Serialization;
    using System.Text;
    using System.Diagnostics;
    
    namespace HttpClientStatus
    {
        public class ClovaSpeechRequest
        {
            public string language { get; set; }
            public string completion { get; set; }
            // Other fields are omitted, please refer to: https://api.ncloud-docs.com/release-20230525/docs/ja/ai-application-service-clovaspeech-clovaspeech for available fields
        }
        public class Program
        {
            private static readonly string secretKey = "";
            private static readonly string invokeUrl = "";
            public static async Task<string> Upload(ClovaSpeechRequest clovaSpeechRequest, string path)
            {
    
                using (var client = new HttpClient())
                {
                    var multiForm = new MultipartFormDataContent();
                    multiForm.Headers.Add("X-CLOVASPEECH-API-KEY", secretKey);
                    multiForm.Add(new StringContent(JsonSerializer.Serialize(clovaSpeechRequest)), "params");
                    FileStream fs = File.OpenRead(path);
                    Console.WriteLine(Path.GetFileName(path));
                    multiForm.Add(new StreamContent(fs), "media", Path.GetFileName(path));
                    var message = await client.PostAsync(invokeUrl+ "/recognizer/upload", multiForm);
                    return await message.Content.ReadAsStringAsync();
                }
            }
    
            static async Task Main(string[] args)
            {
                var clovaSpeechRequest = new ClovaSpeechRequest
                {
                    language = "ko-KR",
                    completion = "sync"
                };
    
                var result = await Upload(clovaSpeechRequest, @"D:\media\video\\sample.mp3");
                Console.WriteLine(result);
            }
        }
    }
    

    エラーコード

    Error Response Body:

    {
      "result": "FAILED",
      "message": "サポートしていないファイルフォーマットです。",
      "token": ''
    }
    
    ResultMessage
    SUCCEEDEDSucceeded
    PROCESSINGProcessing
    ERROR_SERVER_BUSYServer too busy
    ERROR_TOKEN_INVALIDToken does not exist
    ERROR_AUDIO_EMPTYAudio is empty
    ERROR_AUDIO_CONVERSIONAudio conversion has been failed
    ERROR_PARAMS_FORMAT_INVALIDParams must be JSON format
    ERROR_REQUEST_PARAMETERInvalid request parameters
    ERROR_REQUEST_PARAMETERSpeaker detect is off
    ERROR_INVALID_SECRETInvalid secret
    ERROR_DATA_NOT_FOUNDNot found
    ERROR_DATA_CONFLICTData conflict
    ERROR_INTERNAL_ERRORInternal Server Error
    ERROR_EXTERNAL_ERRORService Unavailable
    ERROR_TOO_MANY_JOBSToo many jobs
    ERROR_GATEWAY_TIMEOUTGateway timeout
    FAILEDOther errors

    この記事は役に立ちましたか?

    Changing your password will log you out immediately. Use the new password to log back in.
    First name must have atleast 2 characters. Numbers and special characters are not allowed.
    Last name must have atleast 1 characters. Numbers and special characters are not allowed.
    Enter a valid email
    Enter a valid password
    Your profile has been successfully updated.