I'm using the following command to combine two video files together, overlaying the second one at a certain point in the first file. The result is what I want except the audio from the overlayed file is missing.
ffmpeg.exe -y -hide_banner -ss 00:00:00.067 -i promo.mov -i tag.mov -filter_complex "[1:v]setpts=PTS+6.5/TB[a];[0:v][a]overlay=enable=gte(t\,6.5)[out]" -map [out] -map 0:a -map 1:a -c:v mpeg2video -c:a pcm_s16le -ar 48000 -af loudnorm=I=-20:print_format=summary -preset ultrafast -q:v 0 -t 10 complete.mxf
Without the -map 0:a I get no audio at all, but the second -map 1:a does not pass the audio from -i tag.mov
I have also tried amix but that combines audio from both clips starting at the beginning, and I want the audio from the second file to begin when that file starts overlaying.
It would also be helpful if I could make the audio from the first clip drop lower at the time of the overlay.
amix doesn't support introducing an input mid-way, so the workaround is to add leading silence. You can use the adelay filter to do this.
make the audio from the first clip drop lower at the time of the overlay
This is possible using a sidechaincompressor which takes two inputs and lowers the volume of the first input based on the volume of the second input.
So use,
ffmpeg.exe -y -hide_banner -ss 00:00:00.067 -i promo.mov -i tag.mov -filter_complex "[1:v]setpts=PTS+6.5/TB[1v];[0:v][1v]overlay=enable=gte(t\,6.5)[vout];[1:a]adelay=6.5s,apad,asplit=2[1amix][1aref];[0:a][1aref]sidechaincompress[0asc];[0asc][1amix]amix=inputs=2:duration=first[aout]" -map [vout] -map [aout] -c:v mpeg2video -c:a pcm_s16le -ar 48000 -af loudnorm=I=-20:print_format=summary -preset ultrafast -q:v 0 -t 10 complete.mxf
Related
I explored google and StackOverflow for how to add background music to the video and many of them suggested to use
ffmpeg -i input.mp4 -i audio.mp3 -shortest output.mp4
I have been trying to achieve this but it just does not work. When I try to add map like
ffmpeg -i "input.mp4" -i bg.mp3 -map 0:v:0 -map 1:a:0 oo.mp4
The video sound is replaced by the bg.mp3
And if I try -map 0 -map 1:a:0 or not provide map, the audio is not added at all.
How do I add the background music? I don't also get any error.
-map is a selector; select a type of stream from an input "file". To merge two audio streams, you need an audio filter:
ffmpeg -i input.mp4 -i audio.mp3 -lavfi "[0:a][1:a]amerge[out]" -map 0:v -map [out]:a -shortest output.mp4
-lavfi: Same as -filter_complex, because you have two inputs
[0:a][1:a] take audio stream from the first and second inputs
-map 0:v select the video stream from the first input without processing
-map [out]:a select the audio stream from the filtergraph (processed)
The shortest option in the amerge filter is set by default.
If you have problems, you might want to check also the amix filter, the audio codecs of your files, and the volume filter to adjust the volume of the inputs in the filtergraph.
Additional references:
https://ffmpeg.org/ffmpeg-filters.html#amerge
https://ffmpeg.org/ffmpeg-filters.html#amix
https://ffmpeg.org/ffmpeg-filters.html#volume
If the video length is longer than music you can add "-stream_loop -1" to repeat music until end of video
ffmpeg -i video_with_audio.mkv -stream_loop -1 -i background_music.mp3 -lavfi "[0:a][1:a]amerge[out]" -map 0:v -map [out]:a -shortest video_with_audio_and_background_music.mkv
If you want increase or decrease the volume, follow this command:
ffmpeg -i video_with_audio.mkv -stream_loop -1 -i background_music.mp3 -lavfi "[1:a]volume=0.2,apad[A];[0:a][A]amerge[out]" -map 0:v -map [out]:a -shortest video_with_audio_and_background_music.mkv
I have a list of images: 1.png, 2.png... and a list of audio files 1.mp3, 2.mp3...
I'd like to generate a video file where audio clips are concatenated, and each image is displayed over the corresponding audio clip:
Think of the images as slides in a slideshow, and the audio as narration for the slide.
Are there any frameworks which would allow me to do this? I'd like to use FFmpeg CLI or something high level if possible.
Lazy method is to make each segment then concatenate with the concat demuxer:
ffmpeg -loop 1 -i 1.png -i 1.mp3 -c:v libx264 -preset stillimage -vf format=yuv420p -c:a aac -shortest 1.mp4
ffmpeg -loop 1 -i 2.png -i 2.mp3 -c:v libx264 -preset stillimage -vf format=yuv420p -c:a aac -shortest 2.mp4
ffmpeg -loop 1 -i 2.png -i 2.mp3 -c:v libx264 -preset stillimage -vf format=yuv420p -c:a aac -shortest 2.mp4
ffmpeg -f concat -i input.txt -c copy -movflags +faststart output.mp4
This assumes the image files are the same width & height, and the audio files have the same channel layout & sample rate.
More complicated method is to use the concat filter which allows you to do it all in one command, but you'll have to enter the duration of each image segment to match the corresponding audio duration.
So I have a video called 1.mkv and would like to mix in a variety of different audio clips at certain points. To do this I'm using the -filter_complex option. However, I'm running into some problems because when ffmpeg tries to mix in the first audio stream the audio works for a short while when the clip is playing and then all audio cuts out. I'm running ffmpeg version 2.8.15-0(which is up to date with my distro). Another "weird" thing about the video output is that in xplayer the video will freeze after the audio cuts out, and will work if you skip far enough ahead in the video(not sure if this is helpful but it might give some extra clues).
Full command:
ffmpeg -i "1.mkv" -i "5.wav" -i "2.wav" -i "3.wav" -i "6.wav" -i "7.wav" -i "4.wav" -i "9.wav" -i "8.wav" -i "10.wav" -filter_complex "[0:0]setdar=4/3[v0];
[2:a]aformat=sample_fmts=fltp:sample_rates=44100:channel_layouts=stereo,adelay=20000|20000,volume=0.5[ad2];
[4:a]aformat=sample_fmts=fltp:sample_rates=44100:channel_layouts=stereo,adelay=900000|900000,volume=0.5[ad4];
[3:a]aformat=sample_fmts=fltp:sample_rates=44100:channel_layouts=stereo,adelay=300000|300000,volume=0.5[ad3];
[1:a]aformat=sample_fmts=fltp:sample_rates=44100:channel_layouts=stereo,adelay=720000|720000,volume=0.5[ad1];
[7:a]aformat=sample_fmts=fltp:sample_rates=44100:channel_layouts=stereo,adelay=1140000|1140000,volume=0.5[ad7];
[9:a]aformat=sample_fmts=fltp:sample_rates=44100:channel_layouts=stereo,adelay=1260000|1260000,volume=0.5[ad9];
[8:a]aformat=sample_fmts=fltp:sample_rates=44100:channel_layouts=stereo,adelay=1020000|1020000,volume=0.5[ad8];
[5:a]aformat=sample_fmts=fltp:sample_rates=44100:channel_layouts=stereo,adelay=960000|960000,volume=0.5[ad5];
[6:a]aformat=sample_fmts=fltp:sample_rates=44100:channel_layouts=stereo,adelay=480000|480000,volume=0.5[ad6];
[0:1]volume=1[ad0];
[ad0][ad2][ad4][ad3][ad1][ad7][ad9][ad8][ad5][ad6]amix=inputs=10:duration=first:dropout_transition=0,dynaudnorm[a0]" -map "[v0]" -map "[a0]" -c:v libx264 -ar 44100 -c:a libmp3lame -preset ultrafast -crf 17 -b:v 1M out2.flv
partial command
ffmpeg -i "1.mkv" -i "2.wav" -filter_complex "[0:0]setdar=4/3[v0];
[1:a]aformat=sample_fmts=fltp:sample_rates=44100:channel_layouts=stereo,adelay=20000|20000,volume=0.5[ad2];
[0:1]volume=1[ad0];
[ad0][ad2]amix=inputs=2:duration=first:dropout_transition=0,dynaudnorm[a0]" -map "[v0]" -map "[a0]" -c:v libx264 -ar 44100 -c:a libmp3lame -preset ultrafast -crf 17 -b:v 1M out2.flv
So I managed to solve this by playing around with the audio filters. The fix was converting the mono stream into a stereo before applying the audio filters. I was considering deleting the question but I'll leave it up incase someone has the same problem in the future.
mono to stereo
[1][1]amerge=inputs=2[a1]
I have a project that requires merging of a video file with another audio file. The expected out put is an video file that will have both the audio from actual video and the merged audio file. The length of the output video file will be same to the size of the actual video file.
Is there a single line FFMPEG command to achieve this using copy and -map parameters ?
The video form I will be using is either flv or mp4
And the audio file format will be mp3
There can be achieved without using map also.
ffmpeg -i video.mp4 -i audio.mp3 output.mp4
In case you want the output.mp4 to stop as soon as one of the input stops (audio/video)
then use
-shortest
For example: ffmpeg -i video.mp4 -i audio.mp3 -shortest output.mp4
This will make sure that the output stops as and when any one of the inputs is completed.
Since you have asked that you want to do it with map. this is how you do it:
ffmpeg -i video.mp4 -i audio.mp3 -map 0:0 -map 1:0 -shortest output.mp4
Now, since you want to retain the audio of the video file, consider you want to merge audio.mp3 and video.mp4. These are the steps:
Extract audio from the video.mp4
ffmpeg -i video.mp4 1.mp3
Merge both audio.mp3 and 1.mp3
ffmpeg -i audio.mp3 -i 1.mp3 -filter_complex amerge -c:a libmp3lame -q:a 4 audiofinal.mp3
Remove the audio from video.mp4 (this step is not required. but just to do it properly)
ffmpeg -i video.mp4 -an videofinal.mp4
Now merge audiofinal.mp3 and videofinal.mp4
ffmpeg -i videofinal.mp4 -i audiofinal.mp3 -shortest final.mp4
note: in the latest version of ffmpeg it will only prompt you to use '-strict -2' in case it does then use this:
ffmpeg -i videofinal.mp4 -i audiofinal.mp3 -shortest -strict -2 final.mp4
hope this helps.
You can not do that using one cmd.
1. Get the audio from video file, the audio file name is a.mp3
ffmpeg.exe -i video.mp4 a.mp3
2. Merge two audio files(audio.mp3+a.mp3=audiofinal.mp3)
ffmpeg.exe -i audio.mp3 -i a.mp3 -filter_complex amerge -c:a libmp3lame -q:a 4 audiofinal.mp3
3. Merge video file and audio file(video.mp4+audiofinal.mp3=output.mp4)
ffmpeg.exe -i video.mp4 -i audiofinal.mp3 -map 0:v -map 1:a -c copy -y output.mp4
I don't think extracting the audio from the video is necessary. We can just use -filter_complex amix to merge both audios:
ffmpeg -i videowithaudio.mp4 -i audiotooverlay.mp3 -filter_complex amix -map 0:v -map 0:a -map 1:a -shortest videowithbothaudios.mp4
-filter_complex amix overlays the audio from the first input file on top of audio in the second input file.
-map 0:v video stream of the first input file.
-map 0:a audio stream of the first input file.
-map 1:a audio stream of the second input file.
-shortest the length of the output is the length of the shortest input
Use case:
add music to your background
you rendered a video, but muted some part of it, so you don't want to render it again(coz it's too long), instead you render only audio track(fast) and wanna merge it with original video.
Assuming
you have your video with you speech (or just audio track, whatever)
your music_file is not loud. Otherwise, you will not hear yourself D:
Steps:
1) Extract audio from the video
ffmpeg -i test.mp4 1.mp3
test.mp4 - your file
2) Merge both audio.mp3 and 1.mp3
ffmpeg -i audio.mp3 -i 1.mp3 -filter_complex amerge -c:a libmp3lame -q:a 4 audiofinal.mp3
audiofinal.mp3 - audio with music
3) Delete audio from original
ffmpeg -i example.mkv -c copy -an example-nosound.mkv
example-nosound.mkv - your video without audio
4) Merge with proper audio
ffmpeg -i audiofinal.mp3 -i example-nosound.wmv -c:v copy -vcodec copy final.wmv
final.wmv - your perfect video.
This is very easy with FFmpeg:
ffmpeg -i vid.mp4 -i audio.mp3 -codec:a libmp3lame -ar 44100 -ab 64k -ac 1 -q:v 1 -pix_fmt yuv420p -map 0:0 -map 1:0
First remove the sound from video if you are not able to merge video and audio by using this command:
ffmpeg -i video.mp4 -an videofinal.mp4
I would really appreciate if someone could give some pointers regarding the use of itsoffset with ffmpeg. I have read a number of posts on this subject, some of them explain very clearly how to re-synchronize audio and video with -itsoffset, but I haven't been able to make it work.
My avi file is encoded with ffmpeg, in two passes, using the following command for the second pass:
ffmpeg -i whole-vts_01.avs -pass 2 -y -vcodec libxvid -vtag XVID -b:v 1300K -g 240 -trellis 2 -mbd rd -flags +mv4+aic -acodec ac3 -ac 2 -ar 48000 -b:a 128k output.avi
For whatever reason, I end up with a 1 sec delay in the video (or the audio is 1 sec early). It doesn't happen too often but I see it from time to time.
Among other attempts, I have tried the following:
(1) ffmpeg -i output.avi -itsoffset 00:00:01.0 -i output.avi -vcodec copy -acodec copy -map 0:0 -map 1:1 output-resynched.avi
(2) ffmpeg -i output.avi -itsoffset 00:00:01.0 -i output.ac3 -vcodec copy -acodec copy -map 0:0 -map 1:0 output-resynched2.avi
(3) ffmpeg -itsoffset -00:00:01.00 -i output.avi output-resynched8.avi
(4) ffmpeg -i output.avi -itsoffset -1.0 -i output.avi -vcodec copy -acodec copy -map 0:1 -map 1:0 output-resynched13.avi
Here are the results:
Audio garbled and only 5m 35 s long vs. 1h 41m.
(Output.ac3 is audio component of output.avi) Video and audio
identical to original, offset didn't work
Audio did get shifted, but original encoding parameters replaced with default ones (as expected).
Audio garbled and only 9m 56s long vs. 1h 41m.
I see that many people explain, and apparently use the process described above, but it doesn't seem to be working for me. Am I missing something obvious? I would very much like to be able to use -itsoffset as it is cleaner than my workaround solution.
FWIW, here is a different, and longer way of obtaining the desired result:
First create a shifted video only file using -ss:
ffmpeg -i output.avi -ss 1.0 -vcodec copy -an oupput_videoshifted.avi
Then extract the audio:
ffmpeg -i output.avi -vn -acodec copy outputaudioonly.ac3
And finally remux both components:
ffmpeg -i output_videoshifted.avi -i output_audioonly.ac3 -vcodec copy -acodec copy -map 0:0 -map 1:0 output-resynched14.avi
The process works, is fast enough, but I would really prefer to use the one pass -itsoffset solution.
Here is what I did and it work for me
The first input setting -i and the second input is come from the same one video file.
Delay 1 second in first input video and the second input audio just make a copy
ffmpeg -y -itsoffset 00:00:01.000 -i "d:\Video1.mp4" -i "d:\Video1.mp4"
-map 0:v -map 1:a -vcodec copy -acodec copy
-f mp4 -threads 2 -v warning "Video2.mp4"
Delay 1 second in second input audio and the first input video just make a copy
ffmpeg -y -i "d:\Video1.mp4" -itsoffset 00:00:01.000 -i "d:\Video1.mp4"
-map 0:v -map 1:a -vcodec copy -acodec copy
-f mp4 -threads 2 -v warning "Video2.mp4"
The problem is located on -vcodec copy -acodec copy because the shifting will only work on keyframes. I have had the same problem.
Just don't copy (audio/)video, try the thing with -itsoffset, but use
-vcodec libxvid -vtag XVID -b:v 1300K -g 240 -trellis 2 -mbd rd -flags +mv4+aic -acodec ac3 -ac 2 -ar 48000 -b:a 128k
for re-encoding. It should work.