2020
2121###################################################################################################
2222CHANNELS_REPLACER = 'CHANNELS'
23+ SAMPLE_RATE_REPLACER = 'SAMPLE'
2324AUDIO_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}
3234AUDIO_CODEC_TO_FORMAT = {
3335 "aac" : "m4a" ,
3638 "mp3" : "mp3" ,
3739 "opus" : "opus" ,
3840 "vorbis" : "ogg" ,
41+ "pcm_s16le" : "wav" ,
3942}
4043
4144AUDIO_DEFAULT_FORMAT = "mp3"
4245AUDIO_DEFAULT_CHANNELS = 2
46+ AUDIO_DEFAULT_SAMPLE_RATE = 48000
4347AUDIO_MATCH_FORMAT = "MATCH"
4448AUDIO_INTERMEDIATE_PARAMS = ["-c:a" , "pcm_s16le" , "-ac" , "1" , "-ar" , "16000" ]
4549AUDIO_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