Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

335 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Codec Carver

Python CLI for carving long recordings into metadata-preserved FLAC/Opus files.

Convert supported audio recordings to FLAC or, only when needed to fit each output under a target size, high-bitrate Opus. The tool preserves originals and writes generated files to a separate output directory. Each generated output is kept below the configured size target and below four hours; longer sources are split at long silence intervals when possible.

Install

Requires Python 3.10+ and ffmpeg/ffprobe on PATH.

pip install -e .            # CLI core (stdlib only)
pip install -e ".[web]"     # + FastAPI upload service
pip install -e ".[mcp]"     # + MCP server

This installs the codec-carver console command:

codec-carver /path/to/recordings --execute --output-dir under_2gb

Web service (Docker)

docker build -t codec-carver .
docker run -p 8000:8000 codec-carver   # upload UI at http://localhost:8000

Verified command for this folder

Run from media_shrink_tool/:

python3 media_shrinker.py .. \
  --execute \
  --download-icloud \
  --include-under-limit \
  --flac-all \
  --exclude-dir-prefix split_over \
  --max-duration-seconds 14400 \
  --workers 2 \
  --ffmpeg-threads 0 \
  --output-dir under_2gb \
  --report under_2gb/conversion_report.json

Outputs are written under ../under_2gb/. Existing generated output directories and split_over* directories should be excluded from scans to avoid reconverting generated media. Files under 2GB are included by default; use --over-limit-only only when intentionally processing oversized sources exclusively.

Config file for repeat workflows

Instead of re-typing long flag sets, store them once in a .codec-carver.json file in the scan root (checked first) or the current working directory:

{
    "flac_all": true,
    "exclude_dir_prefix": ["split_over"],
    "max_duration_seconds": 14400,
    "workers": 2,
    "output_dir": "under_2gb"
}

Then repeat runs collapse to python3 media_shrinker.py .. --execute --download-icloud.

  • Keys map 1:1 to CLI options with dashes replaced by underscores (--target-bytes becomes target_bytes).
  • Explicit CLI flags always override config values; without a config file, behavior is identical to a plain invocation.
  • root and --execute are intentionally not configurable: the config file is discovered via the scan root, and a config file must never silently turn a dry run into a real conversion.
  • Unknown keys, wrong value types, and malformed JSON abort with a clear error listing the valid keys.
  • JSON is used instead of TOML because the stdlib TOML parser requires Python 3.11+, while this project also supports Python 3.10.

Duration splitting

  • --max-duration-seconds 14400 keeps every generated file below four hours.
  • When a source is at or above that duration, the tool runs FFmpeg silencedetect and prefers the latest safe point inside a long silence before the four-hour boundary.
  • If no suitable silence is detected before a boundary, the tool hard-splits just under the configured maximum so the duration rule is still enforced.
  • Split outputs are named with part suffixes, for example meeting.wav.part0001.flac, meeting.wav.part0002.flac.
  • Tune silence detection with --silence-noise and --silence-min-duration-seconds when recordings need stricter or looser silence boundaries.

Metadata tagging

  • --set-title, --set-artist, --set-album, and --set-comment stamp the corresponding tags on every generated output, so archived files stay searchable in players and music libraries.
  • Generated commands already copy source metadata with -map_metadata 0; the --set-* values are injected after it, so each provided key overrides that specific source tag while all other source metadata is preserved (standard ffmpeg semantics).
  • When none of the --set-* options are passed, generated ffmpeg commands are byte-identical to the untagged behavior.
  • Values are passed to ffmpeg as single argv items without a shell, so spaces, quotes, and other special characters are safe as given.
python3 media_shrinker.py .. --execute \
  --set-album "Board Meetings 2026" \
  --set-comment "archived by codec-carver"

Output format

  • --format auto (default) keeps the original behaviour: FLAC for lossless (or --flac-all) input, high-bitrate Opus otherwise.
  • --format flac / --format opus force that codec.
  • --format aac (.m4a) and --format mp3 produce broadly-compatible lossy output fitted to the target size — useful for players/devices that don't handle FLAC or Opus.

Transcription (optional)

Turn each shrunk recording into searchable text. With --transcribe, a text and JSON transcript sidecar is written next to every generated audio file (recording.wav.flacrecording.wav.flac.txt / .json):

python3 media_shrinker.py .. --execute --output-dir under_2gb --transcribe

Transcription is opt-in and uses faster-whisper, imported lazily. Install it to enable the feature:

pip install faster-whisper        # then pass --transcribe

If it is not installed, conversion runs normally and transcription is skipped with a TRANSCRIBE_SKIP notice. A failing transcript never aborts a conversion. Choose a model with --transcribe-model (default base).

Safety notes

  • Source files selected by the scan are protected from deletion or overwrite; keep --output-dir as a generated-only directory so excluded originals are never mistaken for stale generated outputs.
  • Generated output names include the original filename and suffix, for example clip.wav.flac and clip.m4a.flac, so same-stem inputs cannot collide during parallel conversion.
  • For lossy sources, --flac-all first creates FLAC to avoid additional loss; if that output exceeds the target size, the generated FLAC is removed and a high-bitrate Opus output is created instead.
  • Filesystem metadata preservation is best effort: permissions, nanosecond access/modified times, extended attributes, and macOS creation date are copied when the operating system allows it.
  • Video-containing files with supported container extensions are rejected unless --allow-video is set to extract their audio track.
  • For real media runs, keep --output-dir as a generated-only directory such as under_2gb and avoid --overwrite unless that directory contains no original source files.

Verification

python3 -m unittest discover -s tests
python3 -m py_compile media_shrinker.py

About

긴 녹음을 메타데이터를 보존한 FLAC/Opus 조각으로 안전하게 변환하는 Python CLI.

Topics

Resources

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages