完全ローカルで動作するQwen3.6-35B-A3Bでプログラムを作る環境が安定してきたので、さらにプログラムを作ってみた
参考:前回の記事
https://qiita.com/Qapla/items/35d55c64f509906912c1
参考:Qwen3.6-35B-A3Bのトークン速度向上方法
https://qiita.com/Qapla/items/d834c926d343b20cefd7
完成したプログラム
YouTubeのURLを入力すると、動画の音声を抽出してMP3ファイルとして保存するCLIアプリケーションです。
外部のサービスを使わずローカルで実行できます(もちろん、YouTubeへのアクセス自体は外部への通信ですが)
Windowsで動作確認をしています
※無論ですが、不適切な目的で使用してはいけません
上記のプログラムを作るまでの流れ
以下の流れで作成した
1.設計書を作る
以下のプロンプトでスタートした
アプリを作りたいので、設計の手伝いをしてください
ゴールは、設計書(mdファイル)を作成することです
不明点や考慮すべき点を私に提案してください。私があなたの質問に答えることで情報をそろえていき、設計書に必要な情報をまとめてください。
# アプリの機能
YouTubeのURLを入れると、その動画の音声部分を抽出してmp3にする
ブラウザで利用できる無料のオンラインサイトは珍しくないですが、同じことをWindowsのアプリでやりたいです
# 参考情報
例えば、オンラインサイトの yt2mp3.sc は以下のような説明が書かれています
(以下 yt2mp3.sc のWebサイトをコピペした内容)
生成AIが「ローカルで使うのか」とか「外部依存があっても良いのか」とか「著作権は」とか色々と聞いてくれるので順に答えていく
最終的な設計書は以下
# YouTube MP3抽出CLIアプリ 設計書 v1.0
## 1. 概要
YouTubeのURLを入力すると、動画の音声を抽出しMP3ファイルとして保存するCLIアプリケーション。
- 実行環境:Windows + Python
- 実行方式:対話型CLI(無限ループ)
- 利用範囲:個人利用(ローカル)
- 外部依存:
- yt-dlp(動画取得)
- FFmpeg(音声変換、PATH必須)
---
## 2. 要件定義
### 2.1 機能要件
| 項目 | 内容 |
|------|------|
| 入力 | YouTube URL(1件) |
| 処理 | 音声抽出 + MP3変換 |
| 出力 | MP3ファイル |
| ファイル名 | 動画タイトル |
| メタデータ | 付与する(タイトル) |
| 進捗表示 | CLIにパーセント表示 |
| 実行形態 | 無限ループ |
---
### 2.2 非機能要件
| 項目 | 内容 |
|------|------|
| 並列処理 | なし |
| ログ | 標準出力のみ |
| エラー処理 | メッセージ表示して継続 |
| 配布 | Pythonスクリプト |
---
## 3. システム構成
```
main.py
├─ config_loader.py
├─ downloader.py
├─ filename_sanitizer.py
```
---
## 4. 設定ファイル
### config.json
```json
{
"output_dir": "C:\\mp3",
"bitrate": "192"
}
````
---
## 5. 処理フロー
```
起動
↓
config読み込み
↓
ループ開始
↓
URL入力
↓
動画情報取得
↓
タイトル取得
↓
ファイル名サニタイズ
↓
ダウンロード + 変換
↓
完了表示
↓
ループ継続
```
---
## 6. 詳細設計
### 6.1 メインループ
```python
while True:
url = input("YouTube URLを入力してください(終了: Ctrl+C)\n> ")
if not url.strip():
continue
try:
process(url)
except Exception as e:
print(f"エラー: {e}")
```
---
### 6.2 yt-dlp設定
```python
ydl_opts = {
'format': 'bestaudio/best',
'outtmpl': f"{output_dir}/%(title)s.%(ext)s",
'progress_hooks': [progress_hook],
'postprocessors': [
{
'key': 'FFmpegExtractAudio',
'preferredcodec': 'mp3',
'preferredquality': bitrate,
},
{
'key': 'FFmpegMetadata',
}
],
}
```
---
### 6.3 進捗表示
```python
def progress_hook(d):
if d['status'] == 'downloading':
percent = d.get('_percent_str', '').strip()
print(f"\r進捗: {percent}", end='')
elif d['status'] == 'finished':
print("\n変換中...")
```
---
### 6.4 ファイル名サニタイズ
```python
INVALID_MAP = {
'\\': '\',
'/': '/',
':': ':',
'*': '*',
'?': '?',
'"': '”',
'<': '<',
'>': '>',
'|': '|'
}
def sanitize(title):
for k, v in INVALID_MAP.items():
title = title.replace(k, v)
return title
```
---
### 6.5 ダウンロード処理
```python
import yt_dlp
def download(url, config):
ydl_opts = create_opts(config)
with yt_dlp.YoutubeDL(ydl_opts) as ydl:
ydl.download([url])
```
---
## 7. エラーハンドリング
| ケース | 対応 |
| --------- | ---------- |
| URL不正 | 無視して再入力 |
| 動画取得失敗 | エラーメッセージ表示 |
| ffmpeg未設定 | 実行時例外 |
| 書き込み失敗 | エラー表示 |
---
## 8. 実行方法
### 8.1 依存インストール
```bash
pip install yt-dlp
```
---
### 8.2 ffmpeg
* 事前にインストールし、PATHを通しておくこと
---
### 8.3 起動
```bash
python main.py
```
または
```bat
@echo off
python main.py
pause
```
---
## 9. 制約事項
* YouTube仕様変更に依存
* ffmpegが必須
* DRMコンテンツは非対応
---
## 10. 拡張余地
* GUI化
* プレイリスト対応
* 並列処理
* 保存先選択UI
---
## 11. 注意事項
* yt-dlpの`%(title)s`はサニタイズされないため、必要に応じて後処理でリネームする
* Windowsコンソールで進捗表示が崩れる場合がある
* 日本語ファイル名対応のため、UTF-8環境(PowerShell推奨)での実行が望ましい
---
## 12. まとめ
* 最小構成で実現可能なシンプル設計
* yt-dlpに処理を委譲し、保守性を確保
* 設定ファイルにより柔軟な変更が可能
* CLIベースでも実用的なUXを実現
2.設計書からプログラムを作る
設計書をClaude Codeが見える場所に置いた後、以下の指示でコーディングを開始する
あなたは自律型ソフトウェア開発エージェントです。
mdファイルに記載された設計と方針に従い、TDD(テスト駆動開発)でアプリを作成してください。
以下を人間の介入なしに完了してください:
- タスク分割
- 詳細設計
- テスト設計(最初に実施)
- テスト作成(実装前に作成)
- 実装
- テスト実行
- エラー修正
- リファクタリング
- README作成
TDDルール(厳守):
- 必ず「テスト→実装」の順で進めること
- 実装前にテストコードを作成すること
- まず失敗するテスト(Red)を作ること
- 次にテストを通す最小限の実装(Green)を行うこと
- その後リファクタリング(Refactor)を行うこと
- このサイクルを機能単位で繰り返すこと
- 総合テストは利用可能であればGUIテストを行うこと。例えばブラウザアプリであれば「playwright」を使用する。
追加ルール:
- ユーザーに質問せず、自分で仮定して進める
- 必要なファイルはすべて自動作成する
- コマンドは自動で実行する
- テストが無限ループに入るなど応答が無くなることを想定し、テストにはタイムアウトを設定する
- テストが失敗した場合は修正して再実行する
- 全テストが成功するまで繰り返す
- 完了するまで止まらない
完了条件:
- 全テストが成功
- コードがリファクタリングされている
- アプリが起動可能
- デバッグビルド、リリースビルドが完成
今すぐ開始してください。
途中で、Claude Codeがファイルに書き込むとき、内部ツールで書き込まずに、わざわざファイルにテキストを書き込むPythonコードを作って実行するという二度手間な現象が見られました。
以下のプロンプトで、やめさせられました
ファイルを編集するときはbash を使うより、Claude Codeが内部で持っているツールで編集することを優先してください
3.完成後、Gitに入れる
完成したと報告があったので手動でテストをして問題が無いことを確認した。(もし問題があればそのままClaudeCodeに再チェックさせたり、Codexにデバッグさせたりする)
その後はGitで管理できるようにするが、最初に「.gitignore」を作らせる
このプロジェクトのファイルをGit管理したいです。セキュリティなどを考慮してまず、.gitignoreを作成してください
正常に終わったら、さらにGitHubにも入れる
※先にGitHubでプロジェクトを作っておきました
Git管理を始めて、GitHubの以下(非公開)に入れてください
https://github.com/qapla-blog/yy2mp3
これですべて終了
コーディングを全くせずに意図通りのプログラムを生成できました