Reputation: 421
I has been recording small audio clips for an audio book. I have the start time of each one in seconds. The music lenght is of, let's say 60 min. I am thinking in create a silence audio file of the same duration as the music, but how I can add each clip into the given start time ? No matter if the clips overlap. I tried using concat and inpoint without the blank file and the output is empty (I am using wav files), that why the idea of use a master blank file as base.
If possible I would really appreciate any example.
Thanks
Upvotes: 0
Views: 741
Reputation: 188
I hope to understand your question. To create a silent wav file:
ffmpeg -f lavfi -i anullsrc -t 01:00:00 silence.wav
Replace 01:00:00 (one hour) with the duration you need. Then, concat and mix the audio files. In this example, I use two small audio clip:
ffmpeg -i silence.wav -i clip1.wav -i clip2.wav -filter_complex "aevalsrc=0:d=10[s1];aevalsrc=0:d=20[s2];[s1][1:a]concat=n=2:v=0:a=1[ac1];[s2][2:a]concat=n=2:v=0:a=1[ac2];[0:a][ac1][ac2]amix=3[aout]" -map [aout] out.wav
It's a very long command to mix lots of clips. So, try the bash script below. Instructions:
Copy the code below in a empty sh file, called mixing.sh
Replace "positions" with the instants in seconds to trigger each clip (my start time clips are 10, 22 and 35 seconds).
Make sure that all clips are placed in a folder called "clips" (next to .sh file). Remember to number the files (1.wav, 2.wav...)
Open a terminal and type: bash mixing.sh
The file out.wav must contain the audio clips at the desired positions.
Here the script, good luck!
#!/bin/bash
positions=(10 22 35)
seconds_at_the_end=2
clips_folder="./clips/"
filetype=".mp3"
silence_file="silence"$filetype
output_file="out"$filetype
command="ffmpeg"
file_id=1
aevalsrc=""
concat=""
mix="[0:a]"
clips=($clips_folder*$filetype)
last_clip_length=$(ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 ${clips[-1]} | awk '{printf("%d\n",$1 + 0.5)}')
silence_length=$((${positions[-1]}+last_clip_length+seconds_at_the_end))
eval $(ffmpeg -f lavfi -i anullsrc -t $silence_length $silence_file)
for filename in $clips_folder*$filetype;
do
inputs=$inputs" -i "$filename
aevalsrc=$aevalsrc"aevalsrc=0:d=${positions[$((file_id-1))]}[s"$file_id"];"
concat=$concat"[s"$file_id"]["$file_id":a]concat=n=2:v=0:a=1[ac"$file_id"];"
mix=$mix"[ac"$file_id"]"
file_id=$((file_id+1))
done
mix=$mix"amix="$((${#positions[*]}+1))"[aout]"
eval $($command -i $silence_file $inputs -filter_complex "$aevalsrc$concat$mix" -map [aout] $output_file)
Tip: I prefer free formats, like ogg (vorbis) or flac, it's more comfortable format to edit or transform. You can perform more complex operations and you are free to use. More info: https://directory.fsf.org/wiki/Ogg_Vorbis
Upvotes: 3