ffmpeg 2 audio files in one video file - audio

lets say I have a video file (video.mp4) and 2 audio files (audio1.mp3 and audio2.mp3.) The video has a length of 60 seconds, every audio file has a length of 30 seconds.
What I am trying to achive is:
the first 20 seconds of the video is with original audio stream, followed by 20 seconds of the first audio file (offset of 5 seconds with a length of 20s) and the same with the second audio file.
ffmpeg -i video.mp4 -ss 5 -t 20 -i audio1.mp3 -ss 5 -t 20 -i audio2.mp3 -vcodec copy -acodec copy -copyinkf -map 0:v:0 -map 1:a:0 -map 2:a:0 -shortest final.mp4
The command above takes the video stream of the first input and the audio stream of the third input. The audio stream of the second input seems to be overwritten. How can I put all audio streams together and how can I define the offset when the audio streams should begin?

I assume that you want the combined audio programme in one stream. Even if you applied timestamp offsets to the other audios, most players won't switch audio streams mid-playback.
So,
ffmpeg -i video.mp4 -ss 5 -t 20 -i audio1.mp3 -ss 5 -t 20 -i audio2.mp3
-filter_complex
"[0]atrim=0:20[a];[1]adelay=20000|20000[b];[2]adelay=40000|40000[c];[a][b][c]amix=3"
-vcodec copy -copyinkf -shortest final.mp4

Related

How to make FFmpeg automatically inject mp3 audio tracks in the single cycled muted video?

everybody here! So basically this is what I want to achieve:
I have a muted video about 3 minutes long.
I have a list of audio tracks in mp3 format (40 songs in a folder with duration 2 to 6 mins each one)
I want this video to play cycled automatically taking songs from playlist and injecting them to the video one by one. Every time a song finishes the next one from the list should start playing at the moment. Video continues playing and doesn't care duration of tracks.
I consider it as the first step on the way to broadcast radio with a video background on youtube in 24/7 mode with ability to put additional tracks to playlist without need to stop translation.
My problem is that I'm new in FFmpeg and I would appreciate any suggestions regarding which FFMpeg topic to start investigate with in order to achieve my goal
Use the concat demuxer
You can do live updates to the playlist for the concat demuxer, but each audio file must have the same attributes, the same number of streams, and all be the same format.
Create input.txt containing:
ffconcat version 1.0
file 'audio1.mp3'
file 'audio2.mp3'
file 'audio3.mp3'
file 'audio40.mp3'
All file names must be "safe" or it will fail with Unsafe file name. Basically no special characters in file names and only use absolute paths. See concat demuxer for more info.
Run ffmpeg to stream to YouTube:
ffmpeg -re -framerate 10 -loop 1 -i image.jpg -re -f concat -i input.txt -map 0:v -map 1:a -c:v libx264 -tune stillimage -vf format=yuv420p -c:a aac -g 20 -b:v 2000k -maxrate 2000k -bufsize 8000k -f flv rtmp://youtube
When you are ready to add new songs make temp.txt containing:
ffconcat version 1.0
file 'audio41.mp3'
file 'audio42.mp3'
file 'audio43.mp3'
Replace input.txt atomically:
mv temp.txt input.txt
See FFmpeg Wiki: Concatenate for lots more info.
If your audio files are not the same
The files listed in input.txt must all have the same:
Format (AAC, MP3, etc, but not mixed)
Sample rate (48000, 44100, etc)
Number of channels (mono, stereo, etc).
If they vary then you will have to pre-process them before adding them to the playlist. Bash example conforming each audio to stereo (-ac 2) with 44100 sample rate (-ar 44100) and save as AAC format in M4A container:
mkdir conformed
for f in *.mp3; do ffmpeg -i "$f" -map 0:a -ac 2 -ar 44100 -c:a aac "conformed/${f%.*}.m4a"; done
Outputting to AAC is recommended for streaming to YouTube.
If you do this then you can avoid re-encoding the audio in the ffmpeg command to YouTube. Just change -c:a aac to -c:a copy in step #2: Run ffmpeg to stream to YouTube.

Loop movie and mix with audio by ffmpeg

I have a movie file and an audio file with different length.
Audio file is longer than video file.
I want to loop video and mix with audio, then set length same as audio file.
ffmpeg -i "Pentagon_VJ_background_loop.mp4" -stream_loop -1 -t 60 -i "Out1.wav" -map 0:0 -map 1:0 output.mp4
With this I have -stream_loop -1 but movie doesn't loop. and have no way to set the length to audio file(I use -t 60 instead).
Does anyone help??
ffmpeg -stream_loop -1 -i "Pentagon_VJ_background_loop.mp4" -i "Out1.wav" -shortest -map 0:0 -map 1:0 output.mp4
Explanation:
-stream_loop -1 must be placed before the file that you want to loop
-shortest tells ffmpeg that output.mp4 should have the duration of the shortest input. Since the video is now an endless video, the shortest input is the audio file.

How to delay audio after a specific position with ffmpeg?

I have a 10 seconds a.mp4 with two streams: Stream #0 is a video stream and Stream #1 is a audio stream.
Now, I want to delay the audio stream by 4 seconds after the time position 00:03. It is to say, in the output file, I want that: 00:00-00:03 is the original audio, 00:03-00:07 has no sound, 00:07-00:14 is the original 00:03-00:10 audio.
I've tried this:
ffmpeg -i a.mp4 -t 00:00:03 -i a.map4 -itsoffset 4 -ss 00:00:03 -i a.mp4 -map 0:v -map 1:a -map 2:a -codec copy output.mp4
But it seems that there are two audio streams in the output.mp4 and only one of them can be played once. Then I tried amix filter:
ffmpeg -i a.mp4 -t 00:00:03 -i a.mp4 -itsoffset 4 -ss 00:00:03 -i a.mp4 -filter_complex "[1:a][2:a] amix=inputs=2" -map 0:v output.mp4
But it also doesn't work. I'm new to ffmpeg so I have no idea what should I do now? Any idea for me? Very much thanks!
Use the asetpts filter to change timestamps, and aresample to (optionally) insert silence in that gap.
ffmpeg -i a.mp4 -af "asetpts='if(lt(T\,3),PTS,PTS+4/TB)',aresample=async=1" -c:v copy output.mp4
Test without aresample to see if your player is tolerant of large gaps in the audio stream.

Concat mp4 videos and merge their audios to the final output

I have several videos and photos and need to merge them with the cross-dissolve effect. The algorithm is next:
Create videos from images and add silent audio to them (so they will also have a sound stream):
ffmpeg -y -f lavfi -i anullsrc -loop 1 -i /tmp/media/import-2020-Aug-19-Wednesday-05-40-34/ea5c93fd-d946-4742-b8f7-ea9ae4d43441.jpg -c:v libx264 -t 10 -pix_fmt yuv420p -vf scale=750:1280 /tmp/media/import-2020-Aug-19-Wednesday-05-40-34/ea5c93fd-d946-4742-b8f7-ea9ae4d43441.mp4
Combine all the videos and audios into one using this command:
ffmpeg
-i /tmp/media/import-2020-Aug-19-Wednesday-05-40-34/temp_68d437c0-f5e2-4651-b07e-91533480b6ef.mp4
-i /tmp/media/import-2020-Aug-19-Wednesday-05-40-34/temp_48f3c111-610d-40c7-ac71-6ce2fbb16184.mp4
-i /tmp/media/import-2020-Aug-19-Wednesday-05-40-34/temp_1593b5d8-7e16-417d-9372-2267581cd504.mp4
-i /tmp/media/import-2020-Aug-19-Wednesday-05-40-34/temp_1ac7f6be-1b12-4e31-b904-1491cc9b9494.mp4
-i /tmp/media/import-2020-Aug-19-Wednesday-05-40-34/temp_ea5c93fd-d946-4742-b8f7-ea9ae4d43441.mp4
-filter_complex
"[0:v]trim=start=0:end=8.032,setpts=PTS-STARTPTS[clip0];
[1:v]trim=start=2:end=13.047,setpts=PTS-STARTPTS[clip1];
[2:v]trim=start=2:end=13.558,setpts=PTS-STARTPTS[clip2];
[3:v]trim=start=2:end=13.186,setpts=PTS-STARTPTS[clip3];
[4:v]trim=start=2,setpts=PTS-STARTPTS[clip4];
[0:v]trim=start=9.032:end=10.032,setpts=PTS-STARTPTS[out0];
[1:v]trim=start=14.047:end=15.047,setpts=PTS-STARTPTS[out1];
[2:v]trim=start=14.558:end=15.558,setpts=PTS-STARTPTS[out2];
[3:v]trim=start=14.186:end=15.186,setpts=PTS-STARTPTS[out3];
[1:v]trim=start=0:end=2,setpts=PTS-STARTPTS[in1];
[2:v]trim=start=0:end=2,setpts=PTS-STARTPTS[in2];
[3:v]trim=start=0:end=2,setpts=PTS-STARTPTS[in3];
[4:v]trim=start=0:end=2,setpts=PTS-STARTPTS[in4];
[in1]format=pix_fmts=yuva420p,fade=t=in:st=0:d=2:alpha=1[fadein1];
[in2]format=pix_fmts=yuva420p,fade=t=in:st=0:d=2:alpha=1[fadein2];
[in3]format=pix_fmts=yuva420p,fade=t=in:st=0:d=2:alpha=1[fadein3];
[in4]format=pix_fmts=yuva420p,fade=t=in:st=0:d=2:alpha=1[fadein4];
[out0]format=pix_fmts=yuva420p,fade=t=out:st=0:d=2:alpha=1[fadeout0];
[out1]format=pix_fmts=yuva420p,fade=t=out:st=0:d=2:alpha=1[fadeout1];
[out2]format=pix_fmts=yuva420p,fade=t=out:st=0:d=2:alpha=1[fadeout2];
[out3]format=pix_fmts=yuva420p,fade=t=out:st=0:d=2:alpha=1[fadeout3];
[fadein1]fifo[fadein1fifo];
[fadein2]fifo[fadein2fifo];
[fadein3]fifo[fadein3fifo];
[fadein4]fifo[fadein4fifo];
[fadeout0]fifo[fadeout0fifo];
[fadeout1]fifo[fadeout1fifo];
[fadeout2]fifo[fadeout2fifo];
[fadeout3]fifo[fadeout3fifo];
[fadeout0fifo][fadein1fifo]overlay[crossfade0];
[fadeout1fifo][fadein2fifo]overlay[crossfade1];
[fadeout2fifo][fadein3fifo]overlay[crossfade2];
[fadeout3fifo][fadein4fifo]overlay[crossfade3];
[clip0][crossfade0][clip1][crossfade1][clip2][crossfade2][clip3][crossfade3][clip4]concat=n=9[output];
[0:a][1:a]acrossfade=d=10:c1=tri:c2=tri[A1];
[A1][2:a]acrossfade=d=10:c1=tri:c2=tri[A2];
[A2][3:a]acrossfade=d=10:c1=tri:c2=tri[A3];
[A3][4:a]acrossfade=d=10:c1=tri:c2=tri[audio] "
-vsync 0 -map "[output]" -map "[audio]" /tmp/media/final/some_filename_d0d2aab0-792a-4540-b2d3-e64abe98bf5c.mp4
And all works pretty well, but if I have, for example:
picture
video
video
picture
Then the sound from the second video is mapping to the first picture and sound from the third video to second video. And the third video actually goes without sound.
It seems like it's happening because the silent sound of the first picture is pretty short. An I right?
If so, how can I increase its duration?
I would much appreciate any help with this!
Assuming 5 inputs of 10 seconds each, all with audio streams*, with ffmpeg 4.3 or newer, use the xfade and acrossfade filters.
ffmpeg
-i in1.mp4
-i in2.mp4
-i in3.mp4
-i in4.mp4
-i in5.mp4
-filter_complex
" [0][1]xfade=transition=fade:duration=2:offset=8[V01];
[V01][2]xfade=transition=fade:duration=2:offset=16[V02];
[V02][3]xfade=transition=fade:duration=2:offset=24[V03];
[V03][4]xfade=transition=fade:duration=2:offset=32[video];
[0:a][1:a]acrossfade=d=2:c1=tri:c2=tri[A01];
[A01][2:a]acrossfade=d=2:c1=tri:c2=tri[A02];
[A02][3:a]acrossfade=d=2:c1=tri:c2=tri[A03];
[A03][4:a]acrossfade=d=2:c1=tri:c2=tri[audio]"
-vsync 0 -map "[video]" -map "[audio]" out.mp4
*if there's no existing audio stream, add one using the command in step 1.
If the existing audio stream of a file isn't 10 seconds long, use these filters on it before acrossfade.
[input]aresample=async=1:first_pts=0,apad,atrim=0:10[filtered]
and then use this filtered stream as input.

How can i use ffmpeg to extract audio from an video every 5 seconds

I need to extract audio from live stream. I want to generate an audio file every 5s.
if i use the command
ffmpeg -i ***.flv -c:a aac -fs 128k output.aac
I can only get one file. but i want generate a file every 5s.
if i use the commmand
ffmpeg -i ***.mp4 -vf fps=1/5.0 E:\image%d.jpg
I got an image every 1s.
How can i do the same thing to extract audio.
Use the segment muxer:
ffmpeg -i input -map 0:a -f segment -segment_time 5 output_%03d.aac
Add -c copy and use a compatible output container format if you don't want to re-encode.

Resources