censorbot 0.0.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- censorbot-0.0.3/CLAUDE.md +269 -0
- censorbot-0.0.3/MANIFEST.in +8 -0
- censorbot-0.0.3/PKG-INFO +460 -0
- censorbot-0.0.3/README.md +410 -0
- censorbot-0.0.3/badwords.txt +6 -0
- censorbot-0.0.3/censor.py +1157 -0
- censorbot-0.0.3/censorbot.egg-info/PKG-INFO +460 -0
- censorbot-0.0.3/censorbot.egg-info/SOURCES.txt +15 -0
- censorbot-0.0.3/censorbot.egg-info/dependency_links.txt +1 -0
- censorbot-0.0.3/censorbot.egg-info/entry_points.txt +2 -0
- censorbot-0.0.3/censorbot.egg-info/not-zip-safe +1 -0
- censorbot-0.0.3/censorbot.egg-info/requires.txt +23 -0
- censorbot-0.0.3/censorbot.egg-info/top_level.txt +1 -0
- censorbot-0.0.3/pyproject.toml +86 -0
- censorbot-0.0.3/requirements.txt +28 -0
- censorbot-0.0.3/setup.cfg +4 -0
- censorbot-0.0.3/setup.py +79 -0
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
# CLAUDE.md
|
|
2
|
+
|
|
3
|
+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
4
|
+
|
|
5
|
+
## Project Overview
|
|
6
|
+
|
|
7
|
+
CensorBot is a Python-based video profanity censoring tool that uses a multi-stage detection approach:
|
|
8
|
+
1. **Embedded subtitles** (extracted from video)
|
|
9
|
+
2. **Downloaded subtitles** (from OpenSubtitles via Subliminal)
|
|
10
|
+
3. **AI transcription** (Whisper-based fallback with hardware acceleration)
|
|
11
|
+
|
|
12
|
+
**Hardware Acceleration Support**:
|
|
13
|
+
- **Apple Silicon**: MLX framework with Metal/Neural Engine acceleration
|
|
14
|
+
- **NVIDIA GPUs**: CUDA acceleration with faster-whisper
|
|
15
|
+
- **CPU**: Multi-threaded processing fallback
|
|
16
|
+
|
|
17
|
+
## Development Commands
|
|
18
|
+
|
|
19
|
+
### Docker Build
|
|
20
|
+
```bash
|
|
21
|
+
# Build for current platform
|
|
22
|
+
docker buildx build --platform $(uname -m) -t censorbot .
|
|
23
|
+
|
|
24
|
+
# Multi-platform build
|
|
25
|
+
docker buildx create --use
|
|
26
|
+
docker buildx build --platform linux/amd64,linux/arm64 -t censorbot --push .
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
### Running the Tool
|
|
30
|
+
```bash
|
|
31
|
+
# Basic usage (auto-detects acceleration)
|
|
32
|
+
docker run -v $(pwd):/app censorbot -i input.mp4 -o output.mp4
|
|
33
|
+
|
|
34
|
+
# NVIDIA GPU acceleration
|
|
35
|
+
docker run --gpus all -v $(pwd):/app censorbot -i input.mp4 -o output.mp4
|
|
36
|
+
|
|
37
|
+
# Force CPU processing
|
|
38
|
+
docker run -v $(pwd):/app censorbot -i input.mp4 -o output.mp4 --force-cpu
|
|
39
|
+
|
|
40
|
+
# Beep mode instead of mute
|
|
41
|
+
docker run -v $(pwd):/app censorbot -i input.mp4 -o output.mp4 --mode beep
|
|
42
|
+
|
|
43
|
+
# Use custom wordlist
|
|
44
|
+
docker run -v $(pwd):/app censorbot -i input.mp4 -o output.mp4 -w badwords.txt
|
|
45
|
+
|
|
46
|
+
# Use external subtitles
|
|
47
|
+
docker run -v $(pwd):/app censorbot -i input.mp4 -o output.mp4 -s subtitles.srt
|
|
48
|
+
|
|
49
|
+
# Single audio track (censored only)
|
|
50
|
+
docker run -v $(pwd):/app censorbot -i input.mp4 -o output.mp4 --single-audio
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### Testing Changes
|
|
54
|
+
```bash
|
|
55
|
+
# Run directly with Python (for development)
|
|
56
|
+
python3 censor.py -i test_video.mp4 -o output.mp4
|
|
57
|
+
|
|
58
|
+
# Test with custom wordlist
|
|
59
|
+
python3 censor.py -i test_video.mp4 -o output.mp4 -w custom_badwords.txt
|
|
60
|
+
|
|
61
|
+
# Test with external subtitles
|
|
62
|
+
python3 censor.py -i test_video.mp4 -o output.mp4 -s subtitles.srt
|
|
63
|
+
|
|
64
|
+
# Test beep mode
|
|
65
|
+
python3 censor.py -i test_video.mp4 -o output.mp4 --mode beep
|
|
66
|
+
|
|
67
|
+
# Force CPU mode (for testing without GPU)
|
|
68
|
+
python3 censor.py -i test_video.mp4 -o output.mp4 --force-cpu
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## Architecture
|
|
72
|
+
|
|
73
|
+
### Core Processing Pipeline
|
|
74
|
+
The `CensorBot` class implements a three-stage subtitle acquisition strategy:
|
|
75
|
+
|
|
76
|
+
1. **extract_embedded_subtitles()** - Uses FFmpeg to extract subtitle streams from video
|
|
77
|
+
2. **download_subtitles()** - Falls back to Subliminal + OpenSubtitles API
|
|
78
|
+
3. **transcribe_audio()** - Final fallback using Faster-Whisper with word-level timestamps
|
|
79
|
+
|
|
80
|
+
### Hardware Acceleration Strategy (REWRITTEN)
|
|
81
|
+
Platform detection and acceleration setup happens in `setup_acceleration()`:
|
|
82
|
+
|
|
83
|
+
**Apple Silicon (MLX Backend)**:
|
|
84
|
+
- Uses `mlx-whisper` with native Metal/Neural Engine acceleration
|
|
85
|
+
- TRUE hardware acceleration (not fake "CoreML" claims)
|
|
86
|
+
- Significantly faster than CPU-only processing
|
|
87
|
+
- Automatically detected on ARM64 Darwin systems
|
|
88
|
+
|
|
89
|
+
**NVIDIA GPUs (CUDA Backend)**:
|
|
90
|
+
- Uses `faster-whisper` with CUDA acceleration
|
|
91
|
+
- Float16 compute type for optimal performance
|
|
92
|
+
- Requires `--gpus all` flag in Docker
|
|
93
|
+
|
|
94
|
+
**CPU Fallback**:
|
|
95
|
+
- Uses `faster-whisper` with multi-threaded CPU processing
|
|
96
|
+
- INT8 quantization for reduced memory usage
|
|
97
|
+
- Automatically uses all available CPU cores
|
|
98
|
+
|
|
99
|
+
### Audio Processing Modes (SIMPLIFIED & FIXED)
|
|
100
|
+
Two censoring approaches using simplified FFmpeg filter chains:
|
|
101
|
+
|
|
102
|
+
**Mute Mode** (default):
|
|
103
|
+
- Chains volume filters: `volume=enable='between(t,start,end)':volume=0,...`
|
|
104
|
+
- Clean, accurate silencing of profanity
|
|
105
|
+
- Single FFmpeg command, no batching complexity
|
|
106
|
+
|
|
107
|
+
**Beep Mode**:
|
|
108
|
+
- Creates continuous sine wave, enables at censor points
|
|
109
|
+
- Mixes beep with muted audio using filter_complex
|
|
110
|
+
- 1000Hz tone at 30% volume
|
|
111
|
+
- Accurate timing without complex adelay calculations
|
|
112
|
+
|
|
113
|
+
**Output Format**:
|
|
114
|
+
- Dual audio tracks by default (original + censored)
|
|
115
|
+
- Use `--single-audio` to keep only censored track
|
|
116
|
+
- Video stream copied (no re-encoding)
|
|
117
|
+
|
|
118
|
+
## Key Implementation Details
|
|
119
|
+
|
|
120
|
+
### Dockerfile Multi-Stage Build (IMPROVED)
|
|
121
|
+
The Dockerfile uses platform-specific build stages with runtime detection:
|
|
122
|
+
|
|
123
|
+
**Build Stages**:
|
|
124
|
+
- `base`: Common Ubuntu 22.04 foundation with FFmpeg
|
|
125
|
+
- `apple_silicon`: ARM64 with CPU PyTorch + MLX for Metal acceleration
|
|
126
|
+
- `nvidia`: CUDA 12.1 base with GPU-enabled PyTorch
|
|
127
|
+
- `cpu_only`: AMD64 with CPU-only PyTorch
|
|
128
|
+
- `final`: Lightweight runtime with conditional package installation
|
|
129
|
+
|
|
130
|
+
**Key Improvements**:
|
|
131
|
+
- Runtime platform detection (not build-time copying)
|
|
132
|
+
- Smaller final image size
|
|
133
|
+
- Automatic MLX installation on ARM64
|
|
134
|
+
- Conditional CUDA support on AMD64
|
|
135
|
+
|
|
136
|
+
### Subtitle Caching
|
|
137
|
+
Subliminal uses a DBM cache (`cachefile.dbm`) to avoid re-downloading subtitles. The cache directory is created at `/root/.cache/subliminal` in the Docker container.
|
|
138
|
+
|
|
139
|
+
### Word Matching
|
|
140
|
+
The default badwords list (`DEFAULT_BADWORDS` in censor.py) includes:
|
|
141
|
+
- Common profanity and variations (f*ck, sh*t)
|
|
142
|
+
- Racial slurs
|
|
143
|
+
- Sexual terms
|
|
144
|
+
- Compound words (motherfucker, bullshit)
|
|
145
|
+
|
|
146
|
+
Additional words can be loaded from `badwords.txt` or custom file via `-w` flag.
|
|
147
|
+
|
|
148
|
+
### Timestamp Alignment
|
|
149
|
+
Default padding is 0.2s before/after detected segments to account for:
|
|
150
|
+
- Whisper timestamp variance
|
|
151
|
+
- Subtitle sync drift
|
|
152
|
+
- Audio attack/decay times
|
|
153
|
+
|
|
154
|
+
Configurable via `--padding` argument.
|
|
155
|
+
|
|
156
|
+
## Dependencies (UPDATED)
|
|
157
|
+
|
|
158
|
+
### Critical Version Constraints
|
|
159
|
+
- **numpy**: Pinned to `<2.0.0` for faster-whisper compatibility
|
|
160
|
+
- **torch**: `>=2.2.0` with platform-specific index URLs
|
|
161
|
+
- **faster-whisper**: `>=1.0.0` (updated from 0.9.0)
|
|
162
|
+
- **mlx-whisper**: `>=0.4.0` for Apple Silicon only
|
|
163
|
+
|
|
164
|
+
### Platform-Specific Packages
|
|
165
|
+
|
|
166
|
+
**Apple Silicon (Darwin ARM64)**:
|
|
167
|
+
- `mlx>=0.4.0`: Apple's ML framework for Metal acceleration
|
|
168
|
+
- `mlx-whisper>=0.4.0`: Whisper with native Metal support
|
|
169
|
+
- `torch>=2.2.0` (CPU index): No CUDA overhead
|
|
170
|
+
|
|
171
|
+
**NVIDIA GPUs (Linux AMD64)**:
|
|
172
|
+
- `torch>=2.2.0` (CUDA 12.1 index): GPU-accelerated PyTorch
|
|
173
|
+
- CUDA runtime from base image
|
|
174
|
+
|
|
175
|
+
**CPU-Only (All Platforms)**:
|
|
176
|
+
- `torch>=2.2.0` (CPU index): Lightweight PyTorch
|
|
177
|
+
- `faster-whisper>=1.0.0`: Multi-threaded transcription
|
|
178
|
+
|
|
179
|
+
## Working with Video Formats
|
|
180
|
+
|
|
181
|
+
### Supported Input Formats
|
|
182
|
+
- MP4, MKV, AVI (any format FFmpeg can decode)
|
|
183
|
+
- Must contain at least one audio stream
|
|
184
|
+
- Subtitles can be embedded or external (SRT format)
|
|
185
|
+
|
|
186
|
+
### Output Format
|
|
187
|
+
Always outputs MP4 with:
|
|
188
|
+
- Original video stream (copied, not re-encoded)
|
|
189
|
+
- Dual audio tracks (stream 0: original, stream 1: censored)
|
|
190
|
+
- Use `--single-audio` to keep only censored track
|
|
191
|
+
|
|
192
|
+
## Code Architecture
|
|
193
|
+
|
|
194
|
+
### Main Function Flow
|
|
195
|
+
The rewritten implementation follows a clean, linear flow:
|
|
196
|
+
|
|
197
|
+
1. **Initialization**: `CensorBot.__init__()` sets up hardware acceleration
|
|
198
|
+
2. **Subtitle Acquisition**: 3-stage fallback (embedded → download → transcribe)
|
|
199
|
+
3. **Audio Extraction**: Extract audio from video to WAV
|
|
200
|
+
4. **Segment Detection**: Find profanity timestamps from subtitles or transcription
|
|
201
|
+
5. **Audio Censoring**: Apply mute/beep using simplified FFmpeg filters
|
|
202
|
+
6. **Video Merging**: Merge censored audio back with video
|
|
203
|
+
7. **Subtitle Embedding**: Optionally embed censored subtitles
|
|
204
|
+
|
|
205
|
+
### Critical Implementation Notes
|
|
206
|
+
|
|
207
|
+
**What Was Fixed**:
|
|
208
|
+
- ❌ Removed broken batching logic (382 lines → 70 lines)
|
|
209
|
+
- ❌ Removed fake "CoreML acceleration" claims
|
|
210
|
+
- ❌ Fixed audio output format (single censored track, not dual-channel merge)
|
|
211
|
+
- ❌ Removed process_video() function (unified execution path)
|
|
212
|
+
- ✅ Simplified FFmpeg filter chains (chained volume filters)
|
|
213
|
+
- ✅ Added real MLX acceleration for Apple Silicon
|
|
214
|
+
- ✅ Clean error handling and logging
|
|
215
|
+
|
|
216
|
+
**FFmpeg Filter Strategy**:
|
|
217
|
+
- **Old**: Batch segments → create temp files → concatenate (broken)
|
|
218
|
+
- **New**: Chain volume filters in single command (works correctly)
|
|
219
|
+
|
|
220
|
+
Example mute filter:
|
|
221
|
+
```bash
|
|
222
|
+
-af "volume=enable='between(t,5,10)':volume=0,volume=enable='between(t,15,20)':volume=0"
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
Example beep filter:
|
|
226
|
+
```bash
|
|
227
|
+
-filter_complex "sine=frequency=1000:duration=300[sine];[sine]volume=enable='between(t,5,10)':volume=0.3[beep];[0:a]volume=enable='between(t,5,10)':volume=0[muted];[muted][beep]amix=inputs=2[out]"
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
## Development Guidelines
|
|
231
|
+
|
|
232
|
+
### Testing Censorship Logic
|
|
233
|
+
```bash
|
|
234
|
+
# Test with known profanity
|
|
235
|
+
echo "This is a fucking test" > test.srt
|
|
236
|
+
# Convert to proper SRT format and test
|
|
237
|
+
|
|
238
|
+
# Verify FFmpeg filter output
|
|
239
|
+
ffmpeg -i input.wav -af "volume=enable='between(t,5,10)':volume=0" output.wav
|
|
240
|
+
ffprobe output.wav # Check audio is valid
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
### Adding New Bad Words
|
|
244
|
+
Edit `badwords.txt` or pass custom file via `-w`:
|
|
245
|
+
```bash
|
|
246
|
+
python3 censor.py -i video.mp4 -o output.mp4 -w custom_words.txt
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
### Debugging Hardware Acceleration
|
|
250
|
+
Check logs for acceleration backend:
|
|
251
|
+
```
|
|
252
|
+
✓ Using Apple Silicon Metal acceleration (MLX)
|
|
253
|
+
✓ Using NVIDIA CUDA acceleration
|
|
254
|
+
Using CPU multi-threaded processing
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
If MLX/CUDA not detected when expected:
|
|
258
|
+
1. Verify platform: `uname -m` (arm64/aarch64 for Apple Silicon)
|
|
259
|
+
2. Check CUDA: `torch.cuda.is_available()` in Python
|
|
260
|
+
3. Check MLX: `python3 -c "import mlx_whisper"` (should not error)
|
|
261
|
+
|
|
262
|
+
## Recent Changes (2024 Rewrite)
|
|
263
|
+
|
|
264
|
+
Complete rewrite addressing critical bugs:
|
|
265
|
+
- **censor.py**: Full rewrite with simplified logic and real acceleration
|
|
266
|
+
- **Dockerfile**: Improved multi-stage build with runtime detection
|
|
267
|
+
- **requirements.txt**: Updated to modern versions with MLX support
|
|
268
|
+
|
|
269
|
+
All changes focused on fixing broken censoring functionality and adding genuine hardware acceleration.
|