I'm trying to use ffmpeg
and subprocess
in python to split a few clips from the given audio and combine them.
The command works in my terminal :
ffmpeg -i input.mp3 \
-af "aselect='between(t, 4, 6) between(t, 70, 80)', asetpts=N/SR/TB" out.wav
However when I try to replicate the same using subprocess
, I get the following error:
[NULL @ 0x7fc5f600a600] Unable to find a suitable output format for 'between(t, 4, 6) between(t, 70, 80)'
between(t, 4, 6) between(t, 70, 80): Invalid argument
CompletedProcess(args=['ffmpeg', '-i', 'input.mp3', '-af', '"aselect=\'', 'between(t, 4, 6) between(t, 70, 80)', "', ", 'asetpts = N/SR/TB"', 'out.wav'], returncode=1)
Code :
import subprocess
input_url = 'input.mp3'
output_file = 'out.wav'
clips = [[4, 6], [70,80]] #start, end
clip_parts = []
for clip_stamps in clips:
start, end = clip_stamps
temp_part = "between" "(" "t, " str(start) ", " str(end) ")"
if clip_parts is None:
clip_parts = [temp_part]
else:
clip_parts.append(temp_part)
subprocess.run([
"ffmpeg",
"-i",
input_url,
"-af",
"\"aselect='",
' '.join(clip_parts),
"', ",
"asetpts = N/SR/TB\"",
output_file
])
CodePudding user response:
There are two issues regarding subprocess.run
:
subprocess.run
automatically adds"
character around arguments with special characters.
For example,"\"aselect='
becomes"\"aselect='"
, so there is extra"\"
- Every element in the list is a command line argument.
"aselect='between(t, 4, 6) between(t, 70, 80)', asetpts=N/SR/TB"
is a single argument, and should not be split to into ["\"aselect='"
,' '.join(clip_parts)
,"', "
,"asetpts = N/SR/TB\""
].
For inspecting the actual command line, you may add -report
argument, and check the log file created by FFmpeg.
Your command (with -report
) is translated to:
ffmpeg -i input.mp3 -af "\"aselect='" "between(t, 4, 6) between(t, 70, 80)" "', " "asetpts = N/SR/TB\"" out.wav -report
As you can see there are extra "
characters.
Corrected code:
import subprocess
input_url = 'input.mp3'
output_file = 'out.wav'
clips = [[4, 6], [70,80]] #start, end
clip_parts = []
for clip_stamps in clips:
start, end = clip_stamps
temp_part = "between" "(" "t, " str(start) ", " str(end) ")"
if clip_parts is None:
clip_parts = [temp_part]
else:
clip_parts.append(temp_part)
subprocess.run([
"ffmpeg",
"-i",
input_url,
"-af",
"aselect='" ' '.join(clip_parts) "', " "asetpts=N/SR/TB",
output_file
])