Skip to content

Commit 7c65257

Browse files
committed
improvements to audio output options
- added wav as an output format - set default audio sample rate to 48000 - allow overriding audio sample rate via command-line parameter
1 parent 6bd1898 commit 7c65257

4 files changed

Lines changed: 52 additions & 25 deletions

File tree

README.md

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -55,33 +55,32 @@ usage: monkeyplug.py <arguments>
5555
monkeyplug.py
5656
5757
options:
58-
-v [true|false], --verbose [true|false]
58+
-v, --verbose [true|false]
5959
Verbose/debug output
60-
-m <string>, --mode <string>
61-
Speech recognition engine (whisper|vosk) (default: whisper)
62-
-i <string>, --input <string>
63-
Input file (or URL)
64-
-o <string>, --output <string>
60+
-m, --mode <string> Speech recognition engine (whisper|vosk) (default: whisper)
61+
-i, --input <string> Input file (or URL)
62+
-o, --output <string>
6563
Output file
6664
--output-json <string>
6765
Output file to store transcript JSON
68-
-w <profanity file>, --swears <profanity file>
66+
-w, --swears <profanity file>
6967
text file containing profanity (default: "swears.txt")
70-
-a APARAMS, --audio-params APARAMS
68+
-a, --audio-params APARAMS
7169
Audio parameters for ffmpeg (default depends on output audio codec)
72-
-c <int>, --channels <int>
73-
Audio output channels (default: 2)
74-
-f <string>, --format <string>
70+
-c, --channels <int> Audio output channels (default: 2)
71+
-s, --sample-rate <int>
72+
Audio output sample rate (default: 48000)
73+
-f, --format <string>
7574
Output file format (default: inferred from extension of --output, or "MATCH")
7675
--pad-milliseconds <int>
7776
Milliseconds to pad on either side of muted segments (default: 0)
7877
--pad-milliseconds-pre <int>
7978
Milliseconds to pad before muted segments (default: 0)
8079
--pad-milliseconds-post <int>
8180
Milliseconds to pad after muted segments (default: 0)
82-
-b [true|false], --beep [true|false]
81+
-b, --beep [true|false]
8382
Beep instead of silence
84-
-h <int>, --beep-hertz <int>
83+
-h, --beep-hertz <int>
8584
Beep frequency hertz (default: 1000)
8685
--beep-mix-normalize [true|false]
8786
Normalize mix of audio and beeps (default: False)
@@ -103,7 +102,9 @@ Whisper Options:
103102
--whisper-model-dir <string>
104103
Whisper model directory (~/.cache/whisper)
105104
--whisper-model-name <string>
106-
Whisper model name (small.en)
105+
Whisper model name (base.en)
106+
--torch-threads <int>
107+
Number of threads used by torch for CPU inference (0)
107108
```
108109

109110
### Docker

setup.cfg

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[metadata]
22
name = monkeyplug
3-
version = 2.1.4
3+
version = 2.1.5
44
author = Seth Grover
55
author_email = mero.mero.guero@gmail.com
66
description = monkeyplug is a little script to censor profanity in audio files.

src/monkeyplug/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
"""monkeyplug is a little script to censor profanity in audio files."""
22

3-
__version__ = "2.1.4"
3+
__version__ = "2.1.5"
44
__author__ = "Seth Grover <mero.mero.guero@gmail.com>"
55
__all__ = []
66

src/monkeyplug/monkeyplug.py

Lines changed: 35 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,16 @@
2020

2121
###################################################################################################
2222
CHANNELS_REPLACER = 'CHANNELS'
23+
SAMPLE_RATE_REPLACER = 'SAMPLE'
2324
AUDIO_DEFAULT_PARAMS_BY_FORMAT = {
24-
"flac": ["-c:a", "flac", "-ar", "44100", "-ac", CHANNELS_REPLACER],
25-
"m4a": ["-c:a", "aac", "-b:a", "128K", "-ar", "44100", "-ac", CHANNELS_REPLACER],
26-
"aac": ["-c:a", "aac", "-b:a", "128K", "-ar", "44100", "-ac", CHANNELS_REPLACER],
27-
"mp3": ["-c:a", "libmp3lame", "-b:a", "128K", "-ar", "44100", "-ac", CHANNELS_REPLACER],
28-
"ogg": ["-c:a", "libvorbis", "-qscale:a", "5", "-ar", "44100", "-ac", CHANNELS_REPLACER],
29-
"opus": ["-c:a", "libopus", "-b:a", "128K", "-ar", "48000", "-ac", CHANNELS_REPLACER],
30-
"ac3": ["-c:a", "ac3", "-b:a", "128K", "-ar", "44100", "-ac", CHANNELS_REPLACER],
25+
"flac": ["-c:a", "flac", "-ar", SAMPLE_RATE_REPLACER, "-ac", CHANNELS_REPLACER],
26+
"m4a": ["-c:a", "aac", "-b:a", "128K", "-ar", SAMPLE_RATE_REPLACER, "-ac", CHANNELS_REPLACER],
27+
"aac": ["-c:a", "aac", "-b:a", "128K", "-ar", SAMPLE_RATE_REPLACER, "-ac", CHANNELS_REPLACER],
28+
"mp3": ["-c:a", "libmp3lame", "-b:a", "128K", "-ar", SAMPLE_RATE_REPLACER, "-ac", CHANNELS_REPLACER],
29+
"ogg": ["-c:a", "libvorbis", "-qscale:a", "5", "-ar", SAMPLE_RATE_REPLACER, "-ac", CHANNELS_REPLACER],
30+
"opus": ["-c:a", "libopus", "-b:a", "128K", "-ar", SAMPLE_RATE_REPLACER, "-ac", CHANNELS_REPLACER],
31+
"ac3": ["-c:a", "ac3", "-b:a", "128K", "-ar", SAMPLE_RATE_REPLACER, "-ac", CHANNELS_REPLACER],
32+
"wav": ["-c:a", "pcm_s16le", "-ar", SAMPLE_RATE_REPLACER, "-ac", CHANNELS_REPLACER],
3133
}
3234
AUDIO_CODEC_TO_FORMAT = {
3335
"aac": "m4a",
@@ -36,10 +38,12 @@
3638
"mp3": "mp3",
3739
"opus": "opus",
3840
"vorbis": "ogg",
41+
"pcm_s16le": "wav",
3942
}
4043

4144
AUDIO_DEFAULT_FORMAT = "mp3"
4245
AUDIO_DEFAULT_CHANNELS = 2
46+
AUDIO_DEFAULT_SAMPLE_RATE = 48000
4347
AUDIO_MATCH_FORMAT = "MATCH"
4448
AUDIO_INTERMEDIATE_PARAMS = ["-c:a", "pcm_s16le", "-ac", "1", "-ar", "16000"]
4549
AUDIO_DEFAULT_WAV_FRAMES_CHUNK = 8000
@@ -234,6 +238,7 @@ def __init__(
234238
outputJson,
235239
aParams=None,
236240
aChannels=AUDIO_DEFAULT_CHANNELS,
241+
aSampleRate=AUDIO_DEFAULT_SAMPLE_RATE,
237242
padMsecPre=0,
238243
padMsecPost=0,
239244
beep=False,
@@ -323,7 +328,13 @@ def __init__(
323328
if self.aParams.startswith("base64:"):
324329
self.aParams = base64.b64decode(self.aParams[7:]).decode("utf-8")
325330
self.aParams = self.aParams.split(' ')
326-
self.aParams = [str(aChannels) if aParam == CHANNELS_REPLACER else aParam for aParam in self.aParams]
331+
self.aParams = [
332+
{
333+
CHANNELS_REPLACER: str(aChannels),
334+
SAMPLE_RATE_REPLACER: str(aSampleRate),
335+
}.get(aParam, aParam)
336+
for aParam in self.aParams
337+
]
327338

328339
# if we're actually just replacing the audio stream(s) inside a video file, the actual output file is still a video file
329340
self.outputVideoFileFormat = (
@@ -523,6 +534,7 @@ def __init__(
523534
outputJson,
524535
aParams=None,
525536
aChannels=AUDIO_DEFAULT_CHANNELS,
537+
aSampleRate=AUDIO_DEFAULT_SAMPLE_RATE,
526538
wChunk=AUDIO_DEFAULT_WAV_FRAMES_CHUNK,
527539
padMsecPre=0,
528540
padMsecPost=0,
@@ -561,6 +573,7 @@ def __init__(
561573
outputJson=outputJson,
562574
aParams=aParams,
563575
aChannels=aChannels,
576+
aSampleRate=aSampleRate,
564577
padMsecPre=padMsecPre,
565578
padMsecPost=padMsecPost,
566579
beep=beep,
@@ -683,6 +696,7 @@ def __init__(
683696
outputJson,
684697
aParams=None,
685698
aChannels=AUDIO_DEFAULT_CHANNELS,
699+
aSampleRate=AUDIO_DEFAULT_SAMPLE_RATE,
686700
padMsecPre=0,
687701
padMsecPost=0,
688702
beep=False,
@@ -694,7 +708,7 @@ def __init__(
694708
force=False,
695709
dbug=False,
696710
):
697-
if (torchThreads > 0):
711+
if torchThreads > 0:
698712
self.torch = mmguero.DoDynamicImport("torch", "torch", debug=dbug)
699713
if self.torch:
700714
self.torch.set_num_threads(torchThreads)
@@ -715,6 +729,7 @@ def __init__(
715729
outputJson=outputJson,
716730
aParams=aParams,
717731
aChannels=aChannels,
732+
aSampleRate=aSampleRate,
718733
padMsecPre=padMsecPre,
719734
padMsecPost=padMsecPost,
720735
beep=beep,
@@ -839,6 +854,15 @@ def RunMonkeyPlug():
839854
default=AUDIO_DEFAULT_CHANNELS,
840855
help=f"Audio output channels (default: {AUDIO_DEFAULT_CHANNELS})",
841856
)
857+
parser.add_argument(
858+
"-s",
859+
"--sample-rate",
860+
dest="aSampleRate",
861+
metavar="<int>",
862+
type=int,
863+
default=AUDIO_DEFAULT_SAMPLE_RATE,
864+
help=f"Audio output sample rate (default: {AUDIO_DEFAULT_SAMPLE_RATE})",
865+
)
842866
parser.add_argument(
843867
"-f",
844868
"--format",
@@ -1009,6 +1033,7 @@ def RunMonkeyPlug():
10091033
args.outputJson,
10101034
aParams=args.aParams,
10111035
aChannels=args.aChannels,
1036+
aSampleRate=args.aSampleRate,
10121037
wChunk=args.voskReadFramesChunk,
10131038
padMsecPre=args.padMsecPre if args.padMsecPre > 0 else args.padMsec,
10141039
padMsecPost=args.padMsecPost if args.padMsecPost > 0 else args.padMsec,
@@ -1035,6 +1060,7 @@ def RunMonkeyPlug():
10351060
args.outputJson,
10361061
aParams=args.aParams,
10371062
aChannels=args.aChannels,
1063+
aSampleRate=args.aSampleRate,
10381064
padMsecPre=args.padMsecPre if args.padMsecPre > 0 else args.padMsec,
10391065
padMsecPost=args.padMsecPost if args.padMsecPost > 0 else args.padMsec,
10401066
beep=args.beep,

0 commit comments

Comments
 (0)