Skip to main content

Enhanced fork of monkeyplug — censors profanity in audio files using speech recognition with Groq API, AI instrumental generation, and batch processing.

Project description

monkeyplug-enhanced

Latest Version

monkeyplug-enhanced is an enhanced fork of mmguero/monkeyplug (available on PyPI as monkeyplug). It censors profanity in audio files using speech recognition, detecting profanity timestamps and either muting, beeping, or splicing in instrumental audio using FFmpeg.

The CLI command is still monkeyplug — only the package name changed to avoid conflicting with the original.

Enhancements over the original

  • Groq API integration (fast, default mode)
  • AI instrumental generation via sherpa-onnx source separation
  • Wildcard/batch processing with automatic vocal detection
  • Transcript save/reuse for faster reprocessing
  • Config file support with sensible defaults

How It Works

  1. Speech recognition produces word-level timestamps (using Groq, Whisper, or Vosk)
  2. Each word is checked against a built-in profanity list (or your custom list)
  3. FFmpeg creates a cleaned audio file by either muting, beeping, or replacing profanity sections with instrumental audio
  4. Optionally, transcripts can be saved and reused to skip transcription on future runs

If provided a video file, monkeyplug processes the audio stream and remultiplexes it with the original video stream.

Installation

pip install monkeyplug-enhanced

Or install from GitHub:

pip install 'git+https://github.com/ljbred08/monkeyplug'

Prerequisites

  • FFmpeg — install via your OS package manager or from ffmpeg.org
  • Python 3.6+
  • Groq API key (for default mode) — see Groq API Setup
  • Optional: Whisper or Vosk for offline recognition

Groq API Setup

The default mode uses Groq's fast Whisper API. Configure your API key using one of these methods (in order of priority):

Command-line parameter:

monkeyplug -i input.mp3 -o output.mp3 --groq-api-key gsk_...

Environment variable:

export GROQ_API_KEY=gsk_...

Config file (~/.groq/config.json):

{"api_key": "gsk_..."}

Project-local file (add .groq_key to .gitignore):

echo 'gsk_...' > .groq_key

Quick Start

# Basic usage — mutes profanity using Groq API and built-in word list
monkeyplug -i song.mp3 -o song_clean.mp3

# Verbose output to see what's happening
monkeyplug -i song.mp3 -o song_clean.mp3 -v

# Use local Whisper instead of Groq
monkeyplug -i song.mp3 -o song_clean.mp3 -m whisper

Censorship Modes

Three modes are available. Priority order: --mute > --beep > --instrumental.

Mute

Silences profanity sections with short fade transitions.

monkeyplug -i song.mp3 -o song_clean.mp3 --mute

Beep

Replaces profanity with a beep tone.

# Basic beep
monkeyplug -i song.mp3 -o song_clean.mp3 -b

# Customize beep frequency and mix
monkeyplug -i song.mp3 -o song_clean.mp3 -b -z 1000 --beep-mix-normalize

Instrumental

Replaces profanity sections with instrumental audio for a professional-sounding clean edit. Supports several sub-modes:

Provide an instrumental file directly

monkeyplug -i explicit.mp3 -o clean.mp3 --instrumental instrumental.mp3

Auto mode (default)

Searches for an instrumental file using fuzzy matching. If not found, falls back to AI generation.

# Default behavior — searches for matching instrumental, generates if not found
monkeyplug -i song.mp3 -o song_clean.mp3 --instrumental auto

# This is also the default when no --instrumental flag is given
monkeyplug -i song.mp3 -o song_clean.mp3

AUTO fuzzy matching searches the same directory for audio files with similar names (30% similarity threshold). Examples:

  • 1-satisfied.mp3 → finds satisfied-inst.mp3
  • MySong_v2.mp3 → finds MySong_instrumental.mp3

Prefix search

Searches for instrumental files using a specific prefix/suffix pattern:

# Searches for: song_inst.mp3, song-inst.mp3, inst_song.mp3, etc.
monkeyplug -i song.mp3 -o song_clean.mp3 --instrumental prefix --instrumental-prefix inst

AI Generation (force)

Uses sherpa-onnx to AI-generate instrumental sections for profanity segments. Skips all instrumental file searching.

monkeyplug -i song.mp3 -o song_clean.mp3 --instrumental generate

The AI separation process:

  1. Extracts profanity segments from the original audio
  2. Concatenates them with configurable padding (default: 1.0s)
  3. Separates vocals from instrumental using a Spleeter model
  4. Splices the AI-generated instrumental back into the original

Separation models are cached at ~/.cache/monkeyplug/separation_models/ (downloaded on first use).

Wildcard / Batch Mode

Process multiple files at once using * wildcards:

# Process all MP3s in current directory
monkeyplug -i "*.mp3" -o "*_clean.mp3" --instrumental generate

# With verbose output
monkeyplug -i "*.mp3" -o "*_clean.mp3 -v

Vocal detection

In wildcard mode, monkeyplug automatically detects which files have vocals by transcribing a 10-second sample from the middle of each file. Instrumental files (no speech detected) are skipped.

With --instrumental generate, vocal detection is skipped by default (all files are processed) since you're generating instrumentals anyway. Use --filter-instrumentals to re-enable it:

# Process all files (default — no vocal detection)
monkeyplug -i "*.mp3" -o "*_clean.mp3" --instrumental generate

# Skip files detected as instrumentals
monkeyplug -i "*.mp3" -o "*_clean.mp3" --instrumental generate --filter-instrumentals

Files matching the output pattern are automatically skipped (already processed).

Transcript Workflow

Save and reuse transcripts to avoid redundant API calls (up to 22x faster on repeat runs):

# Generate and save transcript alongside output
monkeyplug -i song.mp3 -o song_clean.mp3 --save-transcript
# Creates: song_clean.mp3 + song_clean_transcript.json

# Second run: automatically finds and reuses the transcript
monkeyplug -i song.mp3 -o song_clean.mp3 --save-transcript

# Force new transcription (ignore existing transcript)
monkeyplug -i song.mp3 -o song_clean.mp3 --save-transcript --force-retranscribe

# Manually specify a transcript to load
monkeyplug -i song.mp3 -o song_clean_strict.mp3 --input-transcript song_clean_transcript.json -w strict_swears.txt

Custom Profanity Lists

# Use a custom text file (one word per line, or word|replacement)
monkeyplug -i podcast.mp3 -o podcast_clean.mp3 -w custom_swears.txt

# Use a custom JSON file (array of strings)
monkeyplug -i podcast.mp3 -o podcast_clean.mp3 -w custom_swears.json

# Custom words are merged with the built-in profanity list

Config File

monkeyplug looks for a JSON config file in this order (first found wins):

  1. ./.monkeyplug.json (current directory — project-specific)
  2. ~/.cache/monkeyplug/config.json (user-specific)

If neither exists, a default config is auto-created at ~/.cache/monkeyplug/config.json:

{
  "pad_milliseconds": 10,
  "pad_milliseconds_pre": 10,
  "pad_milliseconds_post": 10,
  "separation_padding": 1.0,
  "beep_hertz": 1000
}

Config values provide defaults that can be overridden by CLI arguments.

Clean all caches (models, config) with:

monkeyplug --clean-cache

Padding Control

Add padding around profanity for smoother transitions:

# Equal padding on both sides
monkeyplug -i song.mp3 -o clean.mp3 --pad-milliseconds 100

# Different pre and post padding
monkeyplug -i song.mp3 -o clean.mp3 --pad-milliseconds-pre 50 --pad-milliseconds-post 100

Full Usage Reference

usage: monkeyplug <arguments>

Core Options:
  -i, --input <string>              Input file, URL, or wildcard pattern
  -o, --output <string>             Output file or pattern
  -v [concise|full], --verbose      Verbose output
  -m [groq|whisper|vosk], --mode    Speech recognition engine (default: groq)

Censorship Modes:
  --mute                            Mute profanity (disables instrumental mode)
  -b, --beep                        Beep instead of silence
  --instrumental <mode|file>        Instrumental mode: auto, generate, prefix, or file path
  --instrumental-prefix <string>    Prefix to search for instrumental file (default: AUTO)
  --instrumental-auto-candidates <int>  Top candidates for AUTO matching (default: 5)

Profanity:
  -w, --swears <file>               Custom profanity list (text or JSON)
  --pad-milliseconds <int>          Padding around profanity (default: 10)
  --pad-milliseconds-pre <int>      Padding before profanity (default: 10)
  --pad-milliseconds-post <int>     Padding after profanity (default: 10)

Beep Options:
  -z, --beep-hertz <int>            Beep frequency in Hz (default: 1000)
  --beep-mix-normalize              Normalize audio/beep mix
  --beep-audio-weight <int>         Non-beeped audio weight (default: 1)
  --beep-sine-weight <int>          Beep weight (default: 1)
  --beep-dropout-transition <int>   Dropout transition for beep (default: 0)

Transcript:
  --save-transcript                 Save transcript JSON alongside output
  --input-transcript <file>         Load existing transcript JSON
  --output-json <file>              Save transcript to specific file
  --force-retranscribe              Force new transcription

AI Separation:
  --separation-padding <seconds>    Context padding for AI generation (default: 1.0)
  --filter-instrumentals            Filter out instrumental files in wildcard mode with generate

Audio Output:
  -f, --format <string>             Output format (default: inferred from extension or "MATCH")
  -c, --channels <int>              Output channels (default: 2)
  -s, --sample-rate <int>           Output sample rate (default: 48000)
  -r, --bitrate <string>            Output bitrate (default: 256K)
  -a, --audio-params <string>       FFmpeg audio parameters
  -q, --vorbis-qscale <int>         qscale for libvorbis (default: 5)

Other:
  --force                           Process file even if already tagged
  --clean-cache                     Delete all cached data (models, config) and exit

Groq Options:
  --groq-api-key <string>           Groq API key
  --groq-model <string>             Groq Whisper model (default: whisper-large-v3)

Whisper Options:
  --whisper-model-dir <string>      Model directory (default: ~/.cache/whisper)
  --whisper-model-name <string>     Model name (default: small.en)
  --torch-threads <int>             CPU inference threads (default: 0)

VOSK Options:
  --vosk-model-dir <string>         Model directory (default: ~/.cache/vosk)
  --vosk-read-frames-chunk <int>    WAV frame chunk (default: 8000)

Contributing

Pull requests welcome!

Authors

  • Seth Grover - Initial work - mmguero
  • Lincoln Brown - Enhanced fork (Groq API, AI generation, batch mode) - ljbred08

License

BSD 3-Clause License — see the LICENSE file for details.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

monkeyplug_enhanced-2.2.4.tar.gz (36.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

monkeyplug_enhanced-2.2.4-py3-none-any.whl (37.7 kB view details)

Uploaded Python 3

File details

Details for the file monkeyplug_enhanced-2.2.4.tar.gz.

File metadata

  • Download URL: monkeyplug_enhanced-2.2.4.tar.gz
  • Upload date:
  • Size: 36.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for monkeyplug_enhanced-2.2.4.tar.gz
Algorithm Hash digest
SHA256 748eb8e60597dca2e8c65bd729726c1321a5ed364b2dfd15b2edca9dd99339af
MD5 ff36d285e361b65ab78aeb47cbe07af6
BLAKE2b-256 d65c4e4dced8b9ea9fb0107c03caa89711d0ca1db3251c4f49119011fcaabd3c

See more details on using hashes here.

File details

Details for the file monkeyplug_enhanced-2.2.4-py3-none-any.whl.

File metadata

File hashes

Hashes for monkeyplug_enhanced-2.2.4-py3-none-any.whl
Algorithm Hash digest
SHA256 8f0e4118691427517022372889802c774328ec59e75e8dc53c1d760949cbb76d
MD5 1637c6cbbb4e1d84152fde9cb33e659b
BLAKE2b-256 5f64e317b1293b1eee807a962b2a1fffd32b7cc1c1dc72c573da15221e9b4555

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page