M5Stack CoreS3でWhisperAPIを使う

アイカツ!10th STORY 〜未来へのSTARWAY〜公開 と アイカツ!ミュージックフェスタ FINALなどが重なりブログの存在を忘れていました(いいわけ)

www.aikatsu.net

サボってる間に M5Stackから CORE S3が発売されたので リハビリがてら触ってみます。

Whisper API

言わずと知れたOpenAI の Speech-to-Text APIです。

openai.com

こちらのドキュメントによるとこんな感じのコマンドでいけるっぽいです。簡単っすね。

curl https://api.openai.com/v1/audio/transcriptions \
   -H "Authorization: Bearer $OPENAI_API_KEY" \
   -H "Content-Type: multipart/form-data" \
   -F model="whisper-1" \
   -F file="@/path/to/file/openai.mp3"

上記のコマンドからヘッダにAPI KEYを追加して、modelと変換したいファイルをmultipartで送る感じでしょうか。

multipart/form-data

さてESP32から multipartでPOSTしようか、とHTTPClientのメソッドを見てもやり方がわからない。
どうやら自前で実装する必要がありそう。め、面倒。

愚痴っても仕方ないので実装方法を調べます。結果だけ知りたい方は読み飛ばしてOKです。

multipartでは、Content-Typeで指定したバウンダリ文字列で区切られたデータがボディに並びます。

ヘッダ・・
Content-Type: multipart/form-data; boundary=バウンダリ文字列

--バウンダリ文字列
Content-Disposition:
Content-Type:

(データ1)
--バウンダリ文字列
Content-Disposition:
Content-Type:

(データ2)
--バウンダリ文字列--

完全に理解したけど、不安なのでリクエストヘッダとボディを表示するHTTPサーバを立てて実際に見てみました。*1

先ほどのcurlコマンドのホストをlocalhostに変更して実験します。

ボディ部分がバイナリデータなので見やすいように整形してみます。

Host: localhost
User-Agent: curl/7.87.0
Accept: */*
Authorizeation: Bearer MY_API_KEY
Content-Length: 487811
Content-Type: multipart/form-data; boundary=バウンダリ文字列

--バウンダリ文字列
Content-Disposition: form-data; name="model"

whisper-1
--バウンダリ文字列
Content-Disposition: form-data; name="file"; filename="kiriya.wav"
Content-Type: application/octet-stream

(wavのバイナリデータ)
--バウンダリ文字列--

ばっちり理解できたぞ!

WiFiClient(Secure) を用いた実装

HTTPClientが利用できないので WiFiClientSecureを用いて直接データを作って送受信します。

WiFiClientSecureは

  1. connect()で接続(その前にルート証明書をセットしておく)
  2. print()とflush()でリクエストを送信
  3. available()の間データを read***() で読み込み
  4. stop()で終了

という流れで行います。

レスポンスはJSONで返ってくるのがわかっているので、空行以降のデータをボディとして保持しておき、deserializeJson()でデシリアライズするキメ打ち実装で良いでしょう。

上記の処理を transcriptions() という関数に実装したサンプルコードを載せておきます。 (M5Unified、ArduinoJson、gob_unifiedButton を利用しています)

SDカードから'sample.wav'という音声ファイルを読み込むため、あらかじめ準備しておいてください。
実験では488KのWAVEオーディオを使用しました。ファイルサイズが大きいとおかしな動きをするかもしれませんので注意してください。

参考資料

こちらの資料で勉強させていただきました。

ESP32でバイナリファイルのダウンロード・アップロード - Qiita

Arduino – ESP32 WiFiClientSecure ライブラリで、安定して https ( SSL )記事をGETする方法 | mgo-tec電子工作

WebAPI でファイルをアップロードする方法アレコレ - Qiita