tokuhirom's Blog

MeetNote2 - Zoom を録音して文字起こしして要約する Mac 用のアプリを作ってみた

Zoom 等の会議があったときに、録音して文字起こしして要約するという一連のタスクがあるわけですが、これをMacのアプリとして実装してみました。

↓このへんからダウンロードできます。 https://github.com/tokuhirom/meetnote2/releases

Zoom 会議の場合には、録画機能などもあるわけだがそういうのを使えないケースもあるのかなと思いますので。。

Technical stack

今回も rust + tauri で作りました。この構成が、ネイティブアプリ作るときには制限が少なくて楽な気がします。Swift で作っても良いんだけど、Swift を覚えるのがめんどくさくて rust で済ませてしまっています。apple-sys を使えば mac の api を呼ぶことにほぼ不自由はないので、swift を覚えるモチベーションが薄いですね。

技術的な難しさ

音声の処理

Mac の場合は screencapturekit という API を利用すると、アプリケーションから発せられる音をキャプチャすることが可能です。screencapturekit-rs というライブラリを使えば、これが簡単にできます。 が、、できます、といいたいところだが、出来なかったので、出来るようにした。パッチを送って取り込んでもらったのであった。wave ファイルとして保存できるので良い。

cpal というライブラリを使うとマイクの音を raw 形式で取得できるので、hound というライブラリで wave 形式で保存していく。

アプリケーションから発せられた音声が入っている音声ファイルとマイクから取得した音声ファイルを sox コマンドでミックスし、ffmpeg で mp3 に変換していく。

音声ファイルは圧縮率高めの mp3 として保存しておいて、後から聞き返せるようにしている。

本当は ffmpeg や sox 使ってるところは、rust のライブラリで処理できるといいのだが、適切なライブラリが見つかっていないのであった。

文字列処理

次に、mp3 ファイルを whisper.cpp を使うと文字起こしが出来るので、文字起こしする。一応、OpenAI の transcription api にも対応しているが、M1 Macbook Pro とかだと whisper.cpp でも十分な速度で文字起こしできるので、whisper.cpp を利用するのがオススメ。

文字起こししたファイルは webvtt 形式で出力される。これを OpenAI の API を使って要約するか、TF-IDF を利用した簡易要約を行う。TF-IDF の場合はローカルで処理が完結するので、重要な情報を扱う場合はこちらのほうがオススメ。本当は、もう少し賢い要約アルゴリズムが rust で利用できると嬉しいので、良い方法を知ってる人がいたら、教えて下さい。お願いします。何卒~~

録音の開始終了処理

録音の開始と終了を制御するのは面倒なので、開始と終了は、Zoom 会議の開始終了とか Teams 会議の開始終了とかのタイミングを自動で検知してやってほしい。

最初は Zoom アプリの CPU 使用率が一定以上高い状態が続いていたら録音するというようなロジックでやっていたのだが、これは誤検知が多いので、window のタイトルを使うことにした。

Window のタイトルが screencapturekit で取れるので、それが対象の window title だったら録音開始するというような感じ。もう少しスマートなやり方もありそうだが、思いついてないです。いい方法知ってる人いたら教えてください。

まとめ

そんな感じで、外部コマンドとかにも依存しまくりであんまり他人に使わせる気があんまない構成にはなっているものの、割りと便利だと思う。