2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

プログラミング未経験者が一ヶ月で歌姫を作ってみた

Posted at

プログラミング未経験者が一ヶ月で歌姫を作ってみた

はじめに

みなさん、こんにちは!🎵

私、つい最近までプログラミング未経験だったのですが、「音楽×AI」という夢のコラボで楽曲制作アプリを作ってみました。今回は、FastAPIとReactを使って作った「あなたの青春ソングメーカー」の開発秘話をお届けします!

✨ このアプリで何ができるの?

Qiita用音楽アプリ画面スクショ.jpg

スクリーンショット 2024-11-29 13.41.12.png

  • あなたの青春時代について5つの質問に答えるだけで、AIがオリジナルの歌詞を作ってくれます
  • 答えは声で話しかけるだけでOK!(音声認識搭載)
  • 質問は可愛らしい声で読み上げてくれます(VOICEVOXさん大活躍)
  • 黒板をイメージしたレトロ可愛いデザイン

🔧 どんな技術を使ったの?

フロントエンド(見た目の部分)は:

  • React(JavaScriptのフレームワーク)
  • Tailwind CSS(デザインを簡単にするやつ)
  • Lucide Icons(かわいいアイコン集)

バックエンド(裏側で動く部分)は:

  • FastAPI(Pythonのフレームワーク)
  • VOICEVOX(音声合成の神アプリ)
  • Google Cloud Speech-to-Text(音声認識の賢い子)
  • AWS Bedrock(歌詞を作ってくれる魔法使い)

どんな仕組みで動いてるの?

アプリの中身はこんな感じです:

実装のポイント(ここが大変だった!)

1. 見た目の部分(フロントエンド)

かわいい黒板風デザイン

チョークで書いたような雰囲気を出すために、Tailwind CSSを使ってこんな感じにしました:

<div className="min-h-screen bg-gradient-to-b from-wood-light to-wood-DEFAULT">
  <div className="bg-chalkboard rounded-lg shadow-2xl p-8 relative border-8 border-wood-dark">
    {/* ここに中身を書いていきます */}
  </div>
</div>

音声録音機能

スマートフォンのマイクみたいな機能を作るのにこんなコードを書きました:

const startRecording = async () => {
  try {
    const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
    mediaRecorder.current = new MediaRecorder(stream);
    const chunks = [];

    mediaRecorder.current.ondataavailable = (e) => chunks.push(e.data);
    mediaRecorder.current.onstop = async () => {
      const blob = new Blob(chunks, { type: 'audio/webm' });
      // ここで録音した声をサーバーに送ります
    };

    mediaRecorder.current.start();
    setIsRecording(true);
  } catch (error) {
    console.error('録音開始でエラーが出ちゃいました...:', error);
  }
};

2. サーバー側の部分(バックエンド)

FastAPIで作った主要な機能はこんな感じ:

@app.post("/start")
async def start_interview():
    """インタビューを始めるところ"""
    greeting = "こんにちは!青春ソングを作るためのインタビューを始めましょう。"
    return {"message": greeting, "status": "success"}

@app.post("/speak")
async def speak_text(text: dict):
    """VOICEVOXさんに喋ってもらうところ"""
    await synthesize_voicevox(text["message"])
    return {"status": "success"}

ハマったところとその解決策

1. 音声合成が遅くてイライラ問題

何が起きたの?
VOICEVOXさんが音声を作るのに時間がかかって、ユーザーさんを待たせてしまう...😢

どうやって解決したの?

  • 音声を作る処理を非同期(平行して動かせるように)にしました
  • 「ただいま音声を準備中です♪」みたいな表示を追加
  • 音声を作ってる間は他のボタンを押せないようにしました

2. 開発中によく出たエラー(CORS)との戦い

何が起きたの?
ブラウザからサーバーにアクセスしようとすると怒られる...😱

どうやって解決したの?

app.add_middleware(
    CORSMiddleware,
    allow_origins=["http://localhost:3000"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

このコードで「大丈夫だよ〜」ってブラウザに教えてあげました。

これから追加したい機能

  1. 実際に曲も作れるようにしたい!
  2. もっといろんな質問パターンを増やしたい
  3. ユーザーさんに合わせた質問ができるようにしたい
  4. 作った歌詞を編集できるようにしたい

まとめ

プログラミング未経験でも、「作りたい!」という気持ちがあれば、こんな感じのアプリが作れちゃいました!
特に大事だと感じたポイントは:

  1. 少しずつ機能を追加していく
  2. エラーが出ても慌てない(必ずどこかに解決策があります!)
  3. 使う人のことを考えながら作る
  4. 非同期処理って大事!

参考にさせていただいたサイト

みなさんも、ぜひチャレンジしてみてください!わからないことがあったら、コメントで質問してくださいね!😊

ライセンス

このプロジェクトはMITライセンスで公開しています(著作権表示だけ忘れずに、あとは自由に使ってね!)

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?