Required first step:
just setupInitialises the ffmpeg-statigo submodule and downloads platform-specific FFmpeg static libraries.
Development environment:
nix develop # Enter NixOS development shell (ffmpeg, lame, mediainfo, just, go)just build # Build binary with version from git tags (CGO_ENABLED=1)
just test # Run all Go tests
just test-encoder # Integration test: encode testdata/LMP67.flac
just clean # Remove build artifacts and test outputs (*.mp3)cmd/jivedrop/main.go # CLI entry, mode detection (Hugo vs Standalone), argument validation
internal/
encoder/ # FFmpeg-based MP3 encoding via ffmpeg-statigo
encoder.go # Core encode pipeline: decode → filter → encode
metadata.go # Hugo frontmatter parsing (YAML between --- delimiters)
stats.go # Duration/filesize extraction from encoded MP3
id3/ # ID3v2.4 tag writing via bogem/id3v2
writer.go # Tag frames: TIT2, TALB, TPE1, TDRC, COMM, APIC
artwork.go # Cover art scaling (1400-3000px range for Apple Podcasts)
ui/ # Bubbletea TUI for encoding progress
encode.go # Progress model with realtime speed calculation
cli/ # Lipgloss-styled output
help.go # Custom Kong help printer
styles.go # Colour palette (matches Jivefire sibling project)
third_party/ffmpeg-statigo/ # Git submodule: FFmpeg 8.0 static bindings
- Hugo mode:
jivedrop audio.flac episode.md— reads metadata from Hugo frontmatter - Standalone mode:
jivedrop audio.flac --title X --num N --cover Y— explicit flags - Mode detection: second argument ending in
.mdtriggers Hugo mode
- Required fields in episode markdown:
episode,title,episode_image - After encoding, Jivedrop calculates
podcast_durationandpodcast_bytes - Prompts user to update frontmatter if values differ or are missing
- Mono (default): CBR 112kbps, 44.1kHz, LAME quality 3, 20.5kHz lowpass
- Stereo (
--stereo): CBR 192kbps, 44.1kHz, LAME quality 3, 20.5kHz lowpass
- Uses
ffmpeg-statigosubmodule for static FFmpeg bindings (no system FFmpeg needed) - Filter graph: resample → channel downmix → LAME encode
- All FFmpeg types prefixed with
ffmpeg.AV*
- British English spelling in user-facing text and comments
- Lipgloss styles in
internal/cli/styles.godefine the colour palette - Kong for CLI parsing with custom help printer
- Bubbletea for interactive progress UI during encoding
- Use
cli.PrintError()andcli.PrintInfo()for user-facing messages - Wrap errors with context:
fmt.Errorf("failed to X: %w", err) - Clean up partial files on encoding failure
- Use
cli.PrintError()andcli.PrintInfo()for user-facing messages - Wrap errors with context:
fmt.Errorf("failed to X: %w", err) - Clean up partial files on encoding failure
testdata/contains sample FLAC, markdown, and artwork files- Tests output to
testdata/*.mp3(cleaned byjust clean) - Run
just test-encoderfor integration testing with real audio files
- OS: NixOS with
flake.nixdevelopment shell - Shell: Fish (interactive), bash (scripts)
- CGO required: Set
CGO_ENABLED=1for builds
This project uses ffmpeg-statigo for FFmpeg 8.0 static bindings:
- Location:
third_party/ffmpeg-statigo/ - Auto-generated files:
*.gen.gofiles (e.g.,functions.gen.go,structs.gen.go) — do not edit - C headers:
include/directory for CGO compilation - Libraries:
lib/<os>_<arch>/libffmpeg.a(gitignored, downloaded byjust setup)
For submodule-specific instructions, see third_party/ffmpeg-statigo/.github/copilot-instructions.md.