Skip to content

Add APE+CUE splitting via ffmpeg convert-then-split#133

Open
mprachar wants to merge 1 commit intogolift:mainfrom
mprachar:feature/ape-cue-splitting
Open

Add APE+CUE splitting via ffmpeg convert-then-split#133
mprachar wants to merge 1 commit intogolift:mainfrom
mprachar:feature/ape-cue-splitting

Conversation

@mprachar
Copy link
Copy Markdown

Summary

  • Adds APE (Monkey's Audio) + CUE sheet splitting support alongside existing FLAC+CUE
  • APE files are converted to a temporary FLAC via ffmpeg (compression level 0), then split using the existing splitFLAC() pipeline — zero changes to the proven FLAC splitting path
  • Graceful fallback: when ffmpeg is not installed, returns ErrFFmpegNotFound instead of silently failing
  • resolveCueAudioPath() now tries .ape alongside .flac in all fallback paths

Motivation

Closes Unpackerr/unpackerr#605 — APE+CUE albums are common in music downloads but were silently ignored by the .flac-only format gate. Lidarr cannot import single-image APE files, so they sit in completed directories forever.

Approach: Convert-Then-Split (vs alternatives)

A pure-Go APE codec doesn't exist (and a prior attempt was described as "pretty bleak"). This PR takes the minimal-risk approach:

  1. Detect .ape audio file via CUE sheet resolution
  2. Convert APE → temporary FLAC via ffmpeg -c:a flac -compression_level 0
  3. Split using the existing splitFLAC() — sample-accurate, battle-tested
  4. Cleanup temp FLAC after splitting

The conversion is lossless (APE → PCM → FLAC is a bit-for-bit round-trip). Compression level 0 minimizes conversion time since the file is split immediately anyway.

Changes

File Change
cue.go Format dispatch: .flacsplitFLAC(), .apeconvertAndSplitAPE()
cue.go New convertToFLAC() — ffmpeg shell-out with temp dir cleanup
cue.go resolveCueAudioPath() — adds .ape to all fallback resolution paths
errors.go New ErrFFmpegNotFound; updated ErrUnsupportedAudio message
cue_test.go 4 new tests (all skip gracefully when ffmpeg unavailable)

New tests

  • TestCueAPEConvertAndSplit — full end-to-end: generate FLAC → convert to APE → split via CUE → verify FLAC tracks + VorbisComment tags
  • TestCueAPENoFFmpeg — verifies ErrFFmpegNotFound when PATH is overridden
  • TestCueWavReferenceAPEFile — CUE says .wav but only .ape exists
  • TestCueBaseNameAPEFallback — CUE filename mismatch, resolved via basename + .ape

Test plan

  • go test ./... passes (existing FLAC tests unaffected)
  • APE tests pass when ffmpeg is installed
  • APE tests skip gracefully when ffmpeg is not installed
  • Manual test with real APE+CUE album on Unpackerr instance

Prerequisites

Systems using APE splitting need ffmpeg installed with APE decoder support:

ffmpeg -decoders 2>/dev/null | grep -i ape
# Expected: " A....D ape    Monkey's Audio"

🤖 Generated with Claude Code

APE (Monkey's Audio) files paired with CUE sheets are now split into
individual FLAC tracks, matching the existing FLAC+CUE behavior. Since
no pure-Go APE codec exists, the approach converts APE to a temporary
FLAC via ffmpeg (compression level 0 for speed), then runs the proven
splitFLAC pipeline unchanged. The temp file is cleaned up after splitting.

Changes:
- ExtractCUE now dispatches .ape files to convertAndSplitAPE()
- New convertToFLAC() shells out to ffmpeg with graceful error when
  ffmpeg is not installed (ErrFFmpegNotFound)
- resolveCueAudioPath now tries .ape alongside .flac in all fallback
  paths (wav->ape, basename->ape)
- ErrUnsupportedAudio message updated to mention APE
- Tests: full APE split, ffmpeg-not-found error path, wav->ape
  resolution, basename fallback (all ffmpeg tests skip when unavailable)

Closes Unpackerr/unpackerr#605

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@davidnewhall
Copy link
Copy Markdown
Contributor

Thanks for putting time into this. We need to remove the call to ffmpeg before merging. Might be a while since no one is making an APE library for Go.

@mprachar
Copy link
Copy Markdown
Author

mprachar commented Apr 3, 2026 via email

@davidnewhall
Copy link
Copy Markdown
Contributor

This module is used by others. I do not wish to add calls to os.Exec as those calls can get flagged by security scanning tools. If someone swapped the ffmpeg binary for something else, it could raise privileges. Indeed, these are problems home users do not typically encounter.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

APE Splits like Flac/Cue

2 participants