プログラマってこんなかんじ??

アプリ作ったり歌ったりしてます

賃貸に防音室を導入した話

長いので、先にまとめると

  • 趣味でボーカルをしている
  • 練習できない環境が続いていた
  • 防音室を実際に見て、その場で購入を決めた
  • 毎日声を出すのが当たり前になった
  • かかった費用は、約15万円

そもそもの話

自分は趣味でボーカルをしています。

住居は賃貸で壁が薄く、時間やまわりを気にしながら声を出す必要があって。「練習しよう」と思ってもなかなか腰が重い、そんな状態がしばらく続いていました。

防音室があれば便利だろうな、とは思っていましたが、「もっと本気で活動している人のもの」というイメージがありました。

ただ、音楽の大先輩(せいさん)が運営している「防音室オープンソースプロジェクト」のことは前から知っていて、なんとなく気になっていました。

そんなこともあって、「一度実物を見てみたいな」と思い、見学に行くことにしました。

www.bouonshitsu.info

防音室ラボを見学

せいさんに連絡し、防音室を見せていただきました。まずは実物を見てみたいだけで、まだ買うつもりはありませんでした。

実際に防音室の中に入って、声を出して最初に感じたのは、音のことよりも先に、「あーーー遠慮しなくていいんだ」という感覚でした。

大きな声を出しても、

  • 周りを気にしなくていい
  • 時間や隣人のことを考えなくていい
  • これがあれば、いつでも声を出していい

防音室から出てすぐ、「買わせてください」とお願いしました。

設置の流れ

  • 設置は3回に分けて実施(各2時間ほど)
  • 平日夜、仕事終わりに来てもらった
  • 搬入は一緒に手伝い、作業は見ているだけ

設置の様子はこんな感じです。

防音室完成 (2025/2/21)

設置完了後、この日は夜中までずっと防音室の中で余韻に浸っていたのを覚えています。

何が変わったか

とにかく、毎日声を出せるようになりました。

  • 起きて、仕事の前に声を出す
  • 休憩のついでに声を出す
  • 思いついたときに声を出す

声を出すことが日常になった気がします。長時間こもって練習する日もありますが、それよりもこの変化のほうが大きい。うまくなったかどうかは正直わかりませんが、自分の声に対する解像度は確実に上がったと思います。

よかったところ

一番よかったのは、いつでも声を出せる環境ができたことかな、と思います。

  • 時間を気にしなくていい
  • 周りを気にしなくていい
  • 思いついたときに声を出せる

あとは、

  • リモートワークの作業部屋として使える
  • YouTube や音源を、遠慮なく聴ける
  • 気兼ねなく音を出せるオーディオスペースになる

「防音室」というより、音に関して気を遣わなくていい場所、という感覚に近いかも。

気になるところ

強いて言うのであれば、それなりに大きいです。自分の場合は「2x3 (約1畳)」+ ドア開閉スペースが必要でした。

  • それなりのスペースは、確実に必要
  • 誰にでもおすすめできるものではない

必要な人が、理解したうえで買えばいいと思います。

あとは、一緒に住んでいる人がいる場合は「理解を得られるかどうか」。ここはもう頑張ってください、という話になります。

かかった費用

こちらが実際の見積書 (2024/11/29 時点) です。

今回の防音室設置にかかった費用は 147,912 円 (税込) でした。金額は状況によって変わるみたいなので (材料費の高騰など) 、気になる人は直接聞いたほうが早いと思います。

また、別途「簡易クーラー」が必要でしたが、アドバイスをいただいて、自分でメルカリで格安購入しました。

少し個人的な話

ちょっと前の話ですが、バンドをひとつ離れました。誰かが悪かったという話ではなく、今思えば単純に自分が未熟だっただけかなと思います。バンドを離れたあと、人前で歌うことに対しても少し距離ができていました。

そんなとき、友人の結婚式で、サックスプレイヤーの大先輩と話す機会がありました。バンドを離れた話をすると、「もったいない。また歌の場に引っ張り出すからな」とうれしい声をかけてもらいました。さらに、「自分のタイミングで来ていいよ」と、そんな距離感でバンドに誘っていただいて。本当にありがたくて、「またちゃんと練習しようかな」と久しぶりに思えました。

このときのやり取りが、防音室を買おうと思った大きなきっかけでした。

その頃の自分を振り返ると、

  • 月2回ボイトレには通っている
  • でも練習するのは、その直前くらい
  • 普段から声を出す習慣はほとんどなかった
  • 賃貸で壁が薄く、隣人を常に気にしていた
  • 小声なら出せるけど、気を遣うことに集中してしまう
  • カラオケに行こうと思って、行かない日が続いた

やる気がないというより、声を出すハードルが高い状態が続いていたのかな、と思います。ただの言い訳かも。

まとめ

何かが劇的に変わった、という感じではないのですが、声を出すことが日常になっただけで自分にとっては十分でした。

防音室は、正直、全員に必要なものではないと思います。それなりのスペースも必要ですし、金額も安くはない。

でも「声を出したいのに出せない」「練習したいのに環境がない」状態に悩んでいる人は、考えてみる価値はあるかなぁと思います。

少なくとも自分にとっては、「声を自由に出していい場所」ができただけで十分な買い物でした。すでにもっと広くしたい願望が出てきています。

そして環境面の言い訳ができなくなったので、いろんな意味で逃げ場もなくなりました笑

追加カスタマイズ(後日)

使っているうちに、ピアノ台と棚が欲しくなりました。最初はスノボのワックス台にピアノを載せて使ってたのですけど、せっかくなら・・・という欲望。

再びせいさんに相談して付けてもらいました。

自分好みにカスタマイズできるのと、困ったら相談できる人がいる、というのは大きい。

クラス全員で使うと落ちる英語採点システムを直した話 (Cloud Run)

最近、学校向けに小規模な英語学習支援システムをほぼ1人で作っています。生徒が Speaking (発話) の練習を行い、AI が自動で採点するシステムです。

開発中、「複数人で同時に採点を行うと 500 エラーが発生する」という問題に直面しました。

本記事では、問題の調査から解決までの過程を共有します。似たようなシステムを作っている方がいれば、ぜひアドバイスやご意見をいただけると嬉しいです。

要件

  • ブラウザで動作する Web アプリ(PC / タブレット / スマホ対応)
  • 生徒が録音した音声ファイルを AI がリアルタイム採点
  • クラス単位(約50人)で同時に利用する想定
  • なるべく低コストで運用したい

採点の流れ

音声ファイルを受け取ってから採点結果を返すまでの流れ:

順序 処理 技術
1 音声変換 ffmpeg(WAV 形式に変換)
2 無音検出 VAD(音声区間を検出)
3 文字起こし Whisper
4 AI 評価 ChatGPT(発音・文法・総合評価)

VAD(Voice Activity Detection)とは

VAD は音声区間検出の技術です。「事前に無音解析を行いたい」という要件があり導入しました。VAD ライブラリは WAV 形式の音声を必要とするため、事前に ffmpeg で変換しています。

(もし VAD が不要であれば、そもそも ffmpeg 不要 → CPU Throttling は発生しなかったと思います)

システム構成

カテゴリ 技術
ホスティング Firebase Hosting
ストレージ Firebase Storage
データベース Firestore
バックエンド Cloud Run

アーキテクチャ

Before(同期処理)

シンプルな同期処理方式。リクエストを受けて、採点処理を行い、結果を返す。

After(非同期 + Cloud Run Job)

非同期処理方式。採点処理を Cloud Run Job に分離し、結果は Firestore 経由で通知。

問題の発端

導入した学校から「複数人で試験の採点を行うと 500 エラーが発生する」という報告を受けました。

1人で採点する分には問題なく動作するのに、複数人が同時に採点を実行すると失敗するケースがある。典型的な負荷問題かと思いましたが、想定外の原因が次々と見つかりました。

原因1: Firebase Hosting の 60 秒タイムアウト制限

発見の経緯

採点処理自体は正常に完了しているケースでも、フロントエンドには 502 エラーが返っていることがわかりました。

処理時間を計測すると、60 秒を超えた時点でエラーが発生していました。

原因

Cloud Run 側のタイムアウトは 300 秒 (default) なので正直問題ないと思っていましたが、Firebase Hosting に 60 秒のタイムアウト制限があり。これが起因となっていました。この値は変更できないようです。

Speaking 採点は音声ファイルの処理(ffmpeg)、文字起こし(Whisper)、評価(ChatGPT)と複数の処理を直列で行うため、60 秒を超えることがありました。

解決策

REST の同期応答を待つ方式から、Firestore の onSnapshot による非同期監視に変更しました。

これで 60 秒制限を回避できました。しかし、ここで新たな問題が発生しました。

原因2: Cloud Run の CPU Throttling

発見の経緯

Firestore 監視方式に変更後、採点処理が極端に遅くなりました。同じ処理なのに、遅いときは 100 秒以上かかる。これは明らかに異常でした。

原因

Cloud Run のデフォルト設定では、「CPU はリクエスト処理中のみ割り当てられる」という仕様があります。つまり、HTTP レスポンスを返却した時点で CPU の割り当てが停止 します。

原因1 の対応で「先にレスポンスを返して、処理はバックグラウンドで」という方式に変更したことが、この問題を引き起こしていました。

解決策

Cloud Tasks を使って処理を別の Cloud Run Service に移動しました。

Cloud Tasks 経由で呼び出された処理は「新しい HTTP リクエスト」として扱われるため、CPU 制限を受けません。これで処理速度は大幅に改善しました。

しかし、大量同時実行時にはまだ不安定さが残っていました。

原因3: ffmpeg の競合

発見の経緯

50 人同時実行のベンチマークを行うと、処理時間にばらつきが大きく、一部で 100 秒を超えるケースがありました。

原因

Cloud Run Service は、複数のリクエストを 1 つのコンテナ内で並列処理します。ffmpeg は CPU とメモリを大量に消費するため、同一コンテナ内で複数の ffmpeg が同時実行されると競合が発生していました。

解決策

Cloud Tasks + Cloud Run Service から Cloud Run Job に移行しました。Cloud Run Job は 1 タスク = 1 コンテナで実行されるため、リソース競合が発生しません。

これでさらなる高速化と安定性向上を実現しました。

検討したが採用しなかった対策

Cloud Run Service の「最小インスタンス数を 1 に設定」する方法も検討しました。これによりコールドスタートを回避し、常にウォーム状態を維持できます。

しかし、この方法は常時インスタンスが起動している = 常時課金が発生するため、「なるべく低コストで運用したい」という要件に合わず採用しませんでした。

Cloud Run Job 方式であれば、処理がないときは課金が発生しないため、コスト面でも要件を満たせました。

まとめ

今回の問題は、1つの原因ではなく 3つの異なる原因が複合的に絡んでおり、1つの問題を解決すると別の問題が発生するという連鎖的な状況でした。なんだかんだ解決してよかったです。

原因 詳細 解決策
Firebase Hosting 60秒制限 変更不可のタイムアウト Firestore 非同期監視
Cloud Run CPU Throttling レスポンス後の CPU 制限 Cloud Tasks で処理分離
ffmpeg 競合 1コンテナ内での並列実行 Cloud Run Job に移行

ひとこと

検証に利用したベンチマークツールなどは Claude Code との協業で短時間で作成しました。1人開発で技術相談できる相手がいない中、AI と設計から実装まで進められたのは助かりました。

似たようなサービスを作る方にとって、なにかしら参考になれば幸いです。

システム構成(詳細)

カテゴリ 技術
言語 TypeScript
フレームワーク Nuxt 4, Hono, TailwindCSS
ホスティング Firebase Hosting (CDN)
認証 Firebase Authentication
ストレージ Firebase Storage
データベース Firestore
コンテナ Cloud Run (service/job)
音声処理 ffmpeg, VAD
AI OpenAI Whisper, ChatGPT

LINE ミニアプリを利用したテイクアウトシステムを作りました

弊社初の自社サービスとして「LINE ミニアプリを利用したテイクアウトシステム」を作成、運用していたのですが・・・今年大人の事情でクローズしましたという話です。

記憶が風化する前に紆余曲折や LINE プラットフォームの感想についてまとめましたので、ミニアプリ開発を検討されてる方々の参考になれば幸いです。

要約 (ChatGPT)

  • LINE公式アカウントでテイクアウト注文を可能にした
  • システムは3つのアプリで構成​​
  • 2020年7月にプロジェクト開始、2021年5月に実店舗での運用開始、2022年12月にミニアプリ版リリース、2023年8月にサービス終了​
  • LINEプラットフォームは低い導入障壁と使いやすさが強みであり、複雑な業務システムにも応用可能と感じた

どのようなサービスか?

今では普通になりましたが、店舗の LINE 公式アカウントに Uber Eats のようなテイクアウトシステムを簡単に導入できる、というサービスです。

サービスの構成

以下の 3種類 のアプリケーションでサービスを実現しています。

ユーザ アプリ
注文者 LINE ミニアプリ (Web)
店舗側 管理画面 (Web)
店舗側 タブレットアプリ (Flutter)

プロジェクト概要

時期 内容
2020/7 プロジェクトスタート
2021/5 実店舗での運用開始
2022/12 ミニアプリ版リリース
2023/8 サービスクローズ

体制

  • 営業 1名
  • 開発 1名 (自分)

コロナ禍初期 2020/7 頃にこのような体制でプロジェクトをスタートしました。テイクアウトサービス自体はいろいろありましたが LINE を使ったサービスはまだまだ少なかった印象です。

そして弊社初の自社サービスであり、経験豊かな PdM が在籍しているわけでもない、開発は1人で3種類のアプリケーションを並行作業で作る、手探りで進めていくかなりチャレンジングなプロジェクトでした。

LINE プラットフォームを選択した理由

まず、LINE プラットフォームでは以下のアプリケーションが作成可能です。

種類 概要 審査
LINE Bot チャットボット
トーク画面上で動作
不要
LIFF Webアプリ
リッチメニューやリンクから起動
不要
ミニアプリ Webアプリ
リッチメニューやリンクから起動
LIFF の上位互換
必須

LINE アプリがインストールされていればすぐに動作可能なので、ネイティブアプリに比べると「導入コストが非常に低い」というのが大きなメリットになります。それが決め手になり「今回は LINE プラットフォームで実現しよう」となりました。

紆余曲折

beta1

本サービスは最初からミニアプリ版を作成したわけではなく、実際にはこのようなバージョンアップを経ています。

バージョン 種類
beta1 LINE Bot のみ
beta2 LINE Bot + LIFF
製品版 ミニアプリ

開発当初は「会話ベースで簡単に注文できること」を非常に大事なポイントにしていました。EC サイトでよくあるシンプルな購入フローよりも「LINE UI による会話形式」のほうがユーザフレンドリーであると考えたからです。それもあって「まずはチャットボット形式で実現しよう」となり、beta1 が完成します。

beta1 → beta2

最初の課題に直面しました。

飲食店のようにメニューが多い場合は「トーク画面上でのメニュー表示がむずかしい」という点です。当時は Flex Message を利用して大量のメニュー表示を実現していました。

developers.line.biz

Flex Message (公式画像)

画像のようなテンプレートを利用してメニュー1つ1つを表示。メニューが少ない場合は非常に良い UI なのですが、多い場合は一気に使いにくい、見にくい。大量メニューの閲覧は Web が最適では・・という理由で、

  • メニュー選択フローは Web (LIFF) で
  • 決定フローは Bot

という beta2 形式に変更となりました。

developers.line.biz

beta2 (店舗導入時)

この形で実店舗への導入を開始したのですが、すぐに大きな課題が発覚。

導入時の「店舗担当者の作業難易度が高い」という点です。具体的には「Developer Console を触るハードルが高い」ことです。

Developer Console

店舗側の LINE 公式アカウントに Bot 機能を取り込む場合、「Developer Console のトークン情報」などが必須となります。

開発者向けサイトなのでそれなりに IT リテラシーが求められますし、そもそも難しい画面を触っていただくのが申し訳ない、という想いがありました。

我々が代行作業すればよいのですが、店舗が増えれば増えるほど作業コストが高い。「Bot を利用する=店舗側の Developer Console 必須」なので、

  • Bot での運用を止めて LIFF だけにできないか?
  • それならいっそミニアプリ化したほうがいいのでは?

という案が出始めました。

製品版 (ミニアプリ化)

20231201201932 https://developers.line.biz/ja/news/2022/06/01/line-mini-app-pre-examination

そんな議論をしている最中の「LINE ミニアプリの事前審査がなくなる」というこのプレスリリース、かなりビッグニュースだったのを憶えています。

「検証すら難しかったミニアプリ」が検証可能になったので、すぐにサンプルを作って検証開始 →「ミニアプリで行こう」という結論になりました。

これで店舗担当者は、

  • 公式アカウントのリッチメニューに「ミニアプリ URL」を貼り付けるだけ
  • Developer Console を開く必要もない

というシンプルな導入フローを実現できました。

LINE プラットフォームを使用して感じたこと

会社の方針でサービスをクローズすることにはなりましたが、、冒頭でも述べた「導入障壁が低く、ユーザへ提供しやすい、すぐに価値を届けることができること」はかなり強い部分だと思いました。

LINE を使ったサービスは個人的にいくつか運用しているのですが、個人サービスレベルではなく、複雑な業務システムでも利用できることが体感できましたし、「サービス開発の最初の一手目」として相性が良いと改めて感じました。

というわけで悔しい決断をすることになりましたが、この知見を早速次のサービスに活かそうと思っております。

英語歌詞の発音に悩むボーカル仲間たちへ

AI がネイティブ発音チェックをしてくれる「ELSA Speak (無料)」を使うと発音練習が捗るかもしれないという話。

自分はステージで歌う際の英語の発音で悩んでいて。音楽の場は最近特に海外のお客さんも多いし、演奏してくださるミュージシャンの方で英語話せる方も多い。自分はいいかっこしいなので、そんな中でひどい英語で歌うのが年々恥ずかしくなっていて。

そんなことを英語が話せる友人に相談したら「これで練習するといいかもよ」とオススメされた。英語界隈だと有名なアプリらしい。あまりに感動したのでボーカル仲間に共有。

elsaspeak.com

試しに最近練習している曲をチェックした結果。サビなのにひどい。

というわけで本題。

単語帳を作る

作った単語帳を見る

チェック結果を見ると自分の発音力が丸わかり。これは練習しがいがある。

注意点

単語登録の流れのクセがかなり強い。

  • 修正ができない (削除はできる)
  • 並び替えができない

なので間違えると登録しなおしになる。

画像スキャンでも登録できるが・・・文字認識がイマイチ + 修正できないのであまりオススメしない。

こうやってみると、日本製のアプリのクオリティというかおもてなし感の素晴らしさ、実は世界的に見てもとんでもないのではなかろうか🙃

Nuxt3 アプリを Firebase Hosting へ最速でデプロイ (2023/8/12 時点)

自分が最近よく作っている、

  • Nuxt3 (SSR)
  • Tailwind CSS
  • Firebase Hosting

こんな構成のアプリを「新規作成~デプロイして公開する手順」をまとめました。自分は GCP 派なので Vercel ではなく Firebase Hosting を使っています。

(Mac か WSL なら) この手順だけでとりあえず大丈夫なはず。もっと楽な手順や漏れなどあればアドバイスぜひお願いします。

1. Nuxt3 アプリ新規作成

nuxt.com

// 新規作成 (例 "web" を作成)
npx nuxi@latest init web

// 起動 (localhost)
cd web
yarn install
yarn dev

2. Firebase 初期設定

firebase.google.com

Firebase コンソール

  • プロジェクト作成
  • 「Storage」を開く>始める>本番モード>リージョン選択
    • 自分はいつも「asia-northeast1 (東京)」で作成してる
    • Functions のデプロイで内部的に Storage を使うのでこの操作は必須ぽい

Firebase CLI をインストール

npm install -g firebase-tools

Firebase 初期化

firebase login
firebase init // 作成したプロジェクトを選択
// 以下を選択 (SSR 前提なので Functions 必須)
 ◯ Functions: Configure a Cloud Functions directory and its files
 ◯ Hosting: Configure files for Firebase Hosting and (optionally) set up GitHub Action deploys
// 抜粋
=== Functions Setup
? What language would you like to use to write Cloud Functions? TypeScript
? Do you want to use ESLint to catch probable bugs and enforce style? Yes
? Do you want to install dependencies with npm now? Yes

=== Hosting Setup
? What do you want to use as your public directory? public
? Configure as a single-page app (rewrite all urls to /index.html)? No
? Set up automatic builds and deploys with GitHub? No

✔  Firebase initialization complete!

3. デプロイ準備

Nuxt3 リソース整理

  • 「firebase.json」「public ディレクトリ内のファイルすべて」を削除
  • .firebaserc は残し

firebase.json 自動生成

// nuxt.config.ts に以下を追加
export default defineNuxtConfig({
  nitro: {
    preset: "firebase",
  },
})
yarn add --dev firebase-admin firebase-functions firebase-functions-test
yarn build

firebase.json 書き換え

  • プロジェクトID
    • Firebase コンソール>プロジェクトの設定>プロジェクトID
// firebase.json
<your_project_id> を書き換え

4. デプロイ実行

yarn build
npx firebase deploy

これでサイト公開まで完了。簡単に説明すると、

  • /server 配下が Functions へ
  • それ以外が Firebase Hosting へ

デプロイされる。

以下はおまけ。

5. Tailwind CSS 設定

tailwindcss.com

tailwind.config.js 自動生成

yarn add tailwindcss postcss autoprefixer --dev
npx tailwindcss init

tailwind.config.js

  // 以下を追加
  content: [
    "./components/**/*.{js,vue,ts}",
    "./layouts/**/*.vue",
    "./pages/**/*.vue",
    "./plugins/**/*.{js,ts}",
    "./nuxt.config.{js,ts}",
    "./app.vue",
  ],

assets/css/main.css (新規作成)

// main.css
@tailwind base;
@tailwind components;
@tailwind utilities;

nuxt.config.js

export default defineNuxtConfig({
  // 以下を追加
  css: ["~/assets/css/main.css"],
  postcss: {
    plugins: {
      tailwindcss: {},
      autoprefixer: {},
    },
  },
  ...
});

6. 画面 新規作成

app.vue

  • 以下のように修正
旧    <NuxtWelcome />
新    <NuxtPage />

pages/index.vue

  • 新規作成 (pages フォルダ)
  • 新規作成 (index.vue)
// pages/index.vue
<script setup>
</script>

<template>
  <p class="text-6xl">index</p>
</template>

Happy Coding🙃

つづき daichan4649.hatenablog.jp