Compose Multiplatform で作成した 音声AiChatアプリ
mimi API と Gemini API を用いて、
デバイスのマイクから録音した音声を音声認識(ASR)し、Geminiにリクエストし、
Geminiからの結果を 音声合成(TTS)し、デバイスのスピーカー等で再生します。
また、mimi APIには、mimi.client.kotlin を利用します。
| Android(SDK 26+) | iOS(15.6+) | |
|---|---|---|
| mimi | ✅️ | ✅️ |
| 通信 | ✅️ | ✅️ |
| マイク | ✅️ | ✅️ |
| カメラ | ✅️ |
Warning
iOSは、カメラの動作確認が十分ではありません。
iPad(MY252J/A) OS:18 では動いています。iPhone6S(A1688) OS:15 では動作不十分です。
sequenceDiagram
actor User
box #76c4ebff Device
participant Speaker
participant Microphone
participant App
end
participant Mimi_ASR as mimi API (ASR)
participant Gemini_API as Gemini API
participant Mimi_TTS as mimi API (TTS)
%% ユーザーからの音声入力
User->>App: 録音開始
activate Microphone
User->>Microphone: 音声入力(質問)
Microphone->>App: PCMデータ
User->>App: 録音停止
deactivate Microphone
%% ASR(音声認識)
App->>Mimi_ASR: ASRリクエスト (PCMデータ)
activate Mimi_ASR
Mimi_ASR-->>App: 認識結果(テキスト)
deactivate Mimi_ASR
%% Geminiへの質問
App->>Gemini_API: テキストをGeminiにリクエスト
activate Gemini_API
Gemini_API-->>App: Geminiからの回答(テキスト)
deactivate Gemini_API
%% TTS(音声合成)
App->>Mimi_TTS: TTSリクエスト(回答テキスト)
activate Mimi_TTS
Mimi_TTS-->>App: 合成音声(PCMデータ)
deactivate Mimi_TTS
%% 音声再生
App->>Speaker: 音声再生
activate Speaker
Speaker-->>User: 音声出力
deactivate Speaker
少し手順が複雑です。ここではAndroid向けのみ記載します。
Git submoduleを使いますので、recursive が必須です。
git clone --recursive <this Repository URL>mimi.client.kotlin は、KMPで構成されていますが、すべてのPlatformをPublishしていません。
そこで、事前にローカルでビルドし、ローカル上にPublishしておきます。
cd <this repository>/library/mimi.kotlin
# ビルドに必要な空ファイルを作成
touch github.properties local.properties
# 以下のスクリプトを実行。Warning
mimi.kotlin.client 直下にある publish.sh とは微妙に異なる点に注意下さい。
#!/bin/bash
list=(
":engine:core"
":engine:ktor"
":engine:okhttp"
":service:token"
":service:asr-core"
":service:asr"
":service:nict-asr"
":service:nict-tts"
":utils"
)
for task in "${list[@]}"; do
./gradlew "$task":publishToMavenLocal
if [ $? -ne 0 ]; then
echo "エラー: $task の実行に失敗しました"
exit 1
fi
echo "完了: $task"
echo "------------------------"
done成功すると、Windowsなら、C:\Users\<UserName>\.m2\repository、Linuxなら、$HOME/.m2/repository にmimi.kotlin.clientが、展開されます。
secrets.properties.sample を参考に、プロジェクトのルートに secrets.properties を作成します。
# mimi api https://mimi.readme.io/docs/firststep-auth/ を読み、発行します。
# スコープは、最低限 音声認識と、音声合成が必要です。
mimiApplicationId=<mimi application Id>
mimiClientId=<mimi client Id>
mimiClientSecret=<mimi client Secret>
# Gemini Developer API https://ai.google.dev/gemini-api/docs?hl=ja を読み、発行します。
geminiApiKey=<gemini api key>
# 自作のダミーサーバーに変える場合に利用します
geminiEndpoint=https://generativelanguage.googleapis.com/
# モデルを変える場合はこちらを更新します
geminiModel=gemini-2.5-flashcd <this repository>
./gradlew :androidApp:installDebugTHINKLET向けに調整したバージョンは、以下でインストール可能です。実行前にPermissionの許可は行ってください。
cd <this repository>
./gradlew :thinkletApp:installDebug第2ボタンを短く押し、効果音が再生されたら、質問をします。
もう一度第2ボタンを短く押し、効果音が再生されたら、質問に使う写真撮影と質問のための録音を停止します。
その後、Geminiからの応答があれば音声で再生されます。
