简体   繁体   中英

FFmpeg mix audio clips at given time into a main audio file

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

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:

  1. Copy the code below in a empty sh file, called mixing.sh

  2. Replace "positions" with the instants in seconds to trigger each clip (my start time clips are 10, 22 and 35 seconds).

  3. 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...)

  4. Open a terminal and type: bash mixing.sh

  5. 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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM