Slide 1

Slide 1 text

+"84%":4 .BTIVQGPSUIF'VUVSF JAWS FESTA 2025でリリースした ほぼリアルタイム文字起こし/翻訳機能の構成について 木村 直紀

Slide 2

Slide 2 text

#jawsug #jawsdays2026 #jawsdays2026_x 自己紹介 名前:木村 直紀 エンジニア歴:営業から転職して5年目 資格:G検定、LPIC1 2024-2025年 All Certification Engineer 2024年 AWS Top Engineer 2026年 AWS Community Builders(Cloud Operations) 好きなAWSサービス:AWSサポート、ECS

Slide 3

Slide 3 text

#jawsug #jawsdays2026 #jawsdays2026_x 音声の入出力について ところで、ご清聴いただいている皆様

Slide 4

Slide 4 text

#jawsug #jawsdays2026 #jawsdays2026_x 音声の入出力について 2025 JAWS FESTA参加しましたか?

Slide 5

Slide 5 text

#jawsug #jawsdays2026 #jawsdays2026_x 音声の入出力について JAWS-UG地域支部が主催するカンファレ ンスイベントです。 毎年開催地が変わり、その土地の文化や雰 囲気を活かしたユニークな企画が展開され るのが特徴です。 また、地域の企業やエンジニアが登壇し、 地方からAWS活用の輪を広げていくことも JAWS FESTAの魅力でもあります。 2025年は石川県金沢市で開催されました。

Slide 6

Slide 6 text

リリースしたアプリの説明

Slide 7

Slide 7 text

#jawsug #jawsdays2026 #jawsdays2026_x リリースしたアプリの説明 JAWS FESTAで左の図のようなアプリケーシ ョンをリリースしました。 対応機能 • 音声のリアルタイム文字起こし • 日→ 英 翻訳 使われる場面 • キーノートセッション なんのために作ったか? より多くの参加者がセッション内容を理解でき るようにするため • 聴覚に障害を持つ方 ⇨リアルタイム字幕で内容を理解 • 英語話者の参加者 ⇨ 日→英の翻訳で内容を理解

Slide 8

Slide 8 text

AWSの構成について

Slide 9

Slide 9 text

#jawsug #jawsdays2026 #jawsdays2026_x • Amazon Chime SDKを使った文字起こし • API Gateway + LambdaでTrancribe API/ Translation APIを呼び出し • Trancribe SDK/ Translation SDK 今回試したAWS構成 AWSの構成について

Slide 10

Slide 10 text

#jawsug #jawsdays2026 #jawsdays2026_x Chime SDKを使った場合 AWSの構成について メリット • リアルタイム音声・ビデオ通信(通話/会 議)を 自前で構築する必要がない • 話者付きテキスト生成が可能 デメリット • ユーザー名、会議室などの情報の入力が必要 →会議が始まる前に入力してもらうののが手間 ボタンを押すだけで、ユーザー名などの情報をダミー値で入力されるようにしたが、その後にtokenの処理も 必要になり、ボタンを押しても「文字起こしが中々始まらない…」となった。 話者分離も必要ないので、今回は別の方法でという形で見送った…

Slide 11

Slide 11 text

#jawsug #jawsdays2026 #jawsdays2026_x LambdaからそれぞれのAPIを呼び出した場合 AWSの構成について メリット • API Gatewayで認証・認可、CORSの設 定ができてセキュリティ的にいい デメリット • API Gateway → Lambda → AWSサービスと段 階が増えて、少し遅い リアルタイム性という観点では少し遅いな…という印象で、他の方法を探しました。

Slide 12

Slide 12 text

#jawsug #jawsdays2026 #jawsdays2026_x SDKを使用して各APIを呼び出す場合 AWSの構成について メリット • フロントエンドから直接呼び出している ので、レイテンシが低い デメリット • IAMアクセスキーの管理が発生し、セキュリテ ィリスクが発生する 「IAMアクセスキーの管理」というところは、一般公開されているサービスでは致命的に感じますが、 今回あくまで、「JAWS Festaで一時的に使われるサービス」というところで、レイテンシーの低さを重視して、 この構成を採用としました。

Slide 13

Slide 13 text

音声の入出力について

Slide 14

Slide 14 text

#jawsug #jawsdays2026 #jawsdays2026_x • Web Speech API • MediaDevices API/ MediaStream APIなど 音声の入力で試したもの 音声の入出力について

Slide 15

Slide 15 text

#jawsug #jawsdays2026 #jawsdays2026_x Web Speech APIとは、ウェブブラウザ上で「音声認識(文字起こし)」と「音声合 成(文字の読み上げ)」を実現するためのAPIです。 Web Speech API 音声の入出力について メリット • このAPI単体で以下のことが可能 • マイクからの音声の読み取り • 文字起こし デメリット • 一定時間無音であると認識が終わったものとみなされ て停止される(数秒〜数分で停止していた…) →このデメリットが致命的だった

Slide 16

Slide 16 text

#jawsug #jawsdays2026 #jawsdays2026_x MediaDevices API/ MediaStreamなど(概要) 音声の入出力について それぞれの機能について • MediaDevices API マイクやカメラなどのメディアデバイスにアクセスするため のブラウザ標準API • MediaStream MediaDevices API でマイクやカメラにアクセスした際に返 されるオブジェクト • Web Audio API ブラウザ上で音声を処理・加工・再生するための標準API • ReadableStream データを少しずつ読み取るためのブラウザ標準オブジェクト

Slide 17

Slide 17 text

#jawsug #jawsdays2026 #jawsdays2026_x 音声の入出力について 何をしているのか少しわかりずらい…

Slide 18

Slide 18 text

#jawsug #jawsdays2026 #jawsdays2026_x 音声の入出力について 可憐なAmazon Transcribeという花への水やりに例えてみた 水源 (マイク) 水道局 (ブラウザ) 配管 (MediaStream) 水道 (Web Audio API) 問い合わせ 許可 契約者 (MediaDevices API) ホース (ReadableStream) 水の届け先 (Amazon Transcribe) ④必要な分だけ出す ②マイクと繋ぐ ③音声を加工して、 出力できる状態にする ①マイクと繋げられるよう リクエストを投げる

Slide 19

Slide 19 text

#jawsug #jawsdays2026 #jawsdays2026_x 音声の入出力について MediaDevices API/ MediaStream 項目 設定値 目的 サンプリングレート 16kHz 音声認識の標準 チャンネル数 1ch 軽量化 エコー除去 ON スピーカー音を除去 ノイズ抑制 ON 環境音を除去 音量自動調整 ON 声の大小を均一化 サンプルサイズ 16 Transcribeの要求するbit 音声設定 説明 MediaDevices API を使用してマイクにアクセスし、音声認識 に最適化された設定で MediaStream を取得 処理フロー ブラウザ → マイクにアクセス許可を要求 → 音声データを取得 参考文献:https://developer.mozilla.org/en-US/docs/Web/API/MediaTrackConstraints

Slide 20

Slide 20 text

#jawsug #jawsdays2026 #jawsdays2026_x 音声の入出力について Web Audio API(概要) 項目 内容 ① AudioNodeに変換 MediaStream を処理可能な AudioNode に変換 ② バッファリング 128サンプルずつ来るデータを2048サンプルに蓄積 ③ PCM変換 Float32(-1.0〜1.0)→ PCM16(整数)に変換 参考文献:https://developer.mozilla.org/ja/docs/Web/API/Web_Audio_API

Slide 21

Slide 21 text

#jawsug #jawsdays2026 #jawsdays2026_x 音声の入出力について Web Audio APIの部分(①AudioNodeに変換) 処理の説明 MediaStreamをAudioNodeに変換 また、AudoWorkletに接続 • MediaStreamは音声処理が行えるように AudioNodeに変換する必要があるため 参考文献: https://developer.mozilla.org/ja/docs/Web/API/AudioNode • AudoWorkletに接続することで、音声処理を別ス レッドを行えるようになり、フロント側の処理と は分けて、音声処理を行えるようになるため 参考文献:https://developer.mozilla.org/ja/docs/Web/API/AudioWorklet この処理を行う理由 別スレッドへ

Slide 22

Slide 22 text

#jawsug #jawsdays2026 #jawsdays2026_x 音声の入出力について Web Audio APIの部分(②バッファリング) 説明 バッファを貯めてメインスレッドに送信 • データを細切れに送ると、送信回数が増え、通信の オーバーヘッドになる 参考文献:https://en.wikipedia.org/wiki/Packet_aggregation • Amazon Transcribeへのデータ送信量のベストプラ クティスに収めるため 参考文献:https://docs.aws.amazon.com/transcribe/latest/dg/streaming.html この処理を行う理由 効率悪い 効率良い

Slide 23

Slide 23 text

#jawsug #jawsdays2026 #jawsdays2026_x 音声の入出力について Web Audio APIの部分(③PCM変換) 説明 Float32(-1.0〜1.0)の値をPCM16(整数)に変換 Amazon Transcribeにデータを送信するために、 Float32(-1.0 〜 1.0)の範囲のデータを、 PCM16(-32768 〜 32767)の範囲に変換する必要があるため ( Amazon TranscribeではPCM16でのデータ送信が推奨されている) 参考文献:https://docs.aws.amazon.com/transcribe/latest/dg/streaming.html この処理を行う理由 ※0x8000, 0x7FFFは16進数の数値。 0x8000 = 32768、0x7FFF = 32767となる。

Slide 24

Slide 24 text

#jawsug #jawsdays2026 #jawsdays2026_x 音声の入出力について MediaDevices API/ MediaStream 処理の説明 これまで作ってきた処理で、下記の順番でパイプに流 す処理を実行している。 ①AudioWorkletからのメッセージを取得 ②メッセージを処理してFloat32からPCM16に変換 ③音声データをPCM16 をバイト配列に変換してパイ プに流し込む 参考文献:https://developer.mozilla.org/ja/docs/Web/API/ReadableStream

Slide 25

Slide 25 text

画面の工夫

Slide 26

Slide 26 text

#jawsug #jawsdays2026 #jawsdays2026_x 画面の工夫 ①色 ①色は色盲の方でも区別がつきやすい色を採用 ②マーク ④AutoScroll ③区切り ②①と同様の理由で、マークをつけることで左右で違うものだと認識しやすいようにした ④自動で一番下のブロックまでスクロールするように設定。それによって、左右のブロックを横並びになるようにした ③会話の区切りをブロックで分けることで、文章を認識しやすくした

Slide 27

Slide 27 text

Translation SDKの部分

Slide 28

Slide 28 text

#jawsug #jawsdays2026 #jawsdays2026_x AWS Transcribeから出力されたtextをキャッシュ機能で既出 のテキストならすぐに出力するように設定しました。 既出のtextはMAPオブジェクトに登録されます。 例えば、「こんにちは」とtextが既に入力されていればMAP 内には下記のように登録されます。 登録されていれば、「MAPより翻訳結果を取り出し」 未登録なら、「AWS Translation APIを呼び出す」とするこ とで少しでも出力の時間を削減するように設定しています。 キャッシュ機能で少しでも早く翻訳結果を返す Translation SDKの部分 Map (translationCache) ├─ キー: “こんにちは_en_auto" │ └─ 値: { originalText: “こんにちは", translatedText: "Hello", ... } └─ キー: "ありがとう_en_auto" └─ 値: { originalText: "ありがとう", translatedText: "Thank you", ... }

Slide 29

Slide 29 text

課題

Slide 30

Slide 30 text

#jawsug #jawsdays2026 #jawsdays2026_x 課題 ① Speakerの喋り方によってはブ ロックが大きくなってしまう ② 文字がもう少し大きくてもよ かった ③ 時々文字を、別の文言に変換 してしまっていたり 例)地震→自身 暖かい拍手→戦い拍手

Slide 31

Slide 31 text

今回紹介したアプリのコード

Slide 32

Slide 32 text

#jawsug #jawsdays2026 #jawsdays2026_x 今回紹介したアプリのコード / 旧Twitter(X) https://github.com/k911672/speech-recognition-app GitHub

Slide 33

Slide 33 text

#jawsug #jawsdays2026 #jawsdays2026_x 今回紹介したアプリのコード / 旧Twitter(X) 旧Twitter(X)

Slide 34

Slide 34 text

まとめ

Slide 35

Slide 35 text

#jawsug #jawsdays2026 #jawsdays2026_x • AWSサービスを使った文字起こしは意外と選択肢が多様 • 音声データをTranscribeに届けるだけで結構大変 • JAWS FESTAの実行委員で毎週進捗MTGをしていただた、加藤さ ん、佐藤さんありがとうございました! まとめ