I am trying to pad a series of wav files with silence at the beginning and end using ffmpeg.
the line of code for this i gleaned from elsewhere on this amazing site:
ffmpeg -f concat -i input.txt -codec copy output.wav
where input.txt is simply a list of 3 filenames: silence.wav 0.wav silence.wav
indicating what is to be concatenated
I can do this for an individual file and then update line 2 manually, but there are 1000 files. They are named 0.wav 1.wav 2.wav.
I figure this is trivial in a loop:
COUNTER=1
for FILE in *.wav
do
ffmpeg -f concat -i input.txt -codec copy $FILE
echo $FILE
echo $COUNTER
sed -i "2s/.*/file \'${COUNTER}.wav\'/" input.txt
((COUNTER=COUNTER 1))
done
However the loop doesn't iterate sequentially 0.wav 1.wav 2.wav - rather more erratically (0.wav, 10.wav, 11.wav) - so my counter is out of sync. and my saved filenames are not aligned with their original filenames.
Is there a work around that strips the name from the file itself rather than relying on a counter?
CodePudding user response:
If the counter is already contained in the file name, why not just reuse the file name? That would avoid the issue with string sorting (in which "11" < "9"
) versus numerical sorting (in which 11 > 9
) and it would also work fine if the file names (numbers) were sparse. Also, the output file should not be the same file as one of the inputs. (It might be the case that ffmpeg
can handle it gracefully using temporary files, bu I wouldn’t bet on that.)
for file in *.wav; do
sed -i "2s/.*/file \'${file}\'/" input.txt
ffmpeg -f concat -i input.txt -codec copy "output-${file}"
mv "output-${file}" "$file" # replaces original file!
done
CodePudding user response:
The main problem with your setup is that you read your files in alphabetical order. so after 1.wav comes 10.wav.
Your code then becomes:
ffmpeg -f concat -i input.txt -codec copy 10.wav
sed -i "2s/.*/file \'2.wav\'/" input.txt
so ffmpeg works with 10.wav, while you replace something about 2.wav in input.txt.
Looks like you loop through your files in alphabetical order.
Maybe you could do something like this to loop over your files:
COUNTER=1
while [ $COUNTER -le 1000 ]
do
echo "Filename: ${COUNTER}.wav"
((COUNTER=COUNTER 1))
done
I don't know if ffmpeg starts a new process, but the loop might start ffmpeg, but not waiting till it is finished. This way you could end up with 1000 ffmpeg processes running at the same time.
CodePudding user response:
You should try replacing
for FILE in *.wav
with
for FILE in $(ls *.wav | sort -t '.' -k 1 -n)
Let me know if it worked.