Files
small-scripts/specs/mp3-to-mp4.spec.md
Paul O'Reilly 765f32b4fa Add mp3-to-mp4: convert MP3 to MP4 with static title card
Uses ffmpeg to generate an H.264/AAC video from an MP3 file with a
centred title overlay. Supports optional background image (title at
bottom) or solid colour (title centred). Includes spec, dryrun support,
and 10 tests.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 18:34:50 +12:00

100 lines
3.5 KiB
Markdown

# mp3-to-mp4
## Purpose
Convert an MP3 audio file into an MP4 video that displays a static title card, suitable for uploading to video platforms.
## Dependencies
- `ffmpeg` (6.x+) — video/audio encoding
## Usage
```
mp3-to-mp4 [OPTIONS] <input.mp3>
```
### Arguments
| Argument | Description |
|---|---|
| `<input.mp3>` | Path to the MP3 file to convert (required) |
### Options
| Flag | Description |
|---|---|
| `--title`, `-t` | Title text to display on the video (required) |
| `--output`, `-o` | Output file path (default: same name as input with `.mp4` extension) |
| `--resolution`, `-r` | Video resolution as WxH (default: `1920x1080`) |
| `--font-size` | Font size in pixels (default: `72`) |
| `--font-color` | Font colour (default: `white`) |
| `--bg-color` | Background colour (default: `black`; ignored when `--image` is set) |
| `--image`, `-i` | Background image path (optional; scaled to fill the resolution) |
| `--dryrun`, `-n` | Preview what would happen without creating files |
| `--help`, `-h` | Show usage information |
## Behaviour
1. **Validate inputs.** Check that `<input.mp3>` exists and is readable. Check that `ffmpeg` is on PATH. Check that `--title` is provided. Exit 1 with a clear message if any check fails.
2. **Determine duration.** Use `ffprobe` to get the audio duration in seconds.
3. **Generate video.** Use ffmpeg to:
- **Without `--image`:** Create a solid colour background at the specified resolution for the audio duration. Title is centred both horizontally and vertically.
- **With `--image`:** Scale the image to fill the resolution (crop to fit). Title is centred horizontally near the bottom of the frame.
- Mux the MP3 audio as the audio stream
- Encode with H.264 video and AAC audio for broad compatibility
- Use `-shortest` to match video duration to audio duration
4. **Report.** Print the output path on success.
## Dryrun Behaviour
When `--dryrun` / `-n` is passed:
```
[dryrun] Input: /path/to/episode.mp3
[dryrun] Output: /path/to/episode.mp4
[dryrun] Title: My Podcast Episode
[dryrun] Duration: 3m 42s
[dryrun] Resolution: 1920x1080
[dryrun] Font size: 72
[dryrun] Font color: white
[dryrun] Background: black (or image path when --image is used)
[dryrun] Dependencies OK: ffmpeg 6.1.1
[dryrun] Would generate .mp4 video file
```
No files are created or modified.
## Edge Cases
- **Input file not found:** Exit 1 with `Error: file not found: <path>`
- **ffmpeg not installed:** Exit 1 with `Error: ffmpeg not found. Install with: sudo apt install ffmpeg`
- **--title not provided:** Exit 1 with `Error: --title is required`
- **Output file already exists:** Overwrite without prompting (standard pipeline behaviour)
- **Title text is very long:** ffmpeg's drawtext wraps naturally; no special handling needed
- **Input is not a valid audio file:** ffprobe will fail; exit 1 with `Error: could not read audio duration from: <path>`
- **--image file not found:** Exit 1 with `Error: image not found: <path>`
- **--image with --bg-color:** `--bg-color` is silently ignored when `--image` is provided
## Examples
```bash
# Basic conversion
mp3-to-mp4 -t "My Podcast Episode" episode.mp3
# Custom output and resolution
mp3-to-mp4 -t "Talk Title" -o talk.mp4 -r 1280x720 recording.mp3
# Custom styling
mp3-to-mp4 -t "Keynote" --font-size 96 --font-color yellow --bg-color "#1a1a2e" speech.mp3
# With a background image (title at bottom)
mp3-to-mp4 -t "Keynote 2026" -i cover.jpg recording.mp3
# Preview without creating files
mp3-to-mp4 --dryrun -t "Test" audio.mp3
```