Create background sound for video with ffmpeg - ffmpeg

I have a video file without sound and a stereo audio file. Video is several times longer than audio. I'd like to create a background sound which starts from 2 second silence, then trim silence of the audio at both ends and duplicate trimmed audio several times to the end of the video.
I found how to trim audio:
ffmpeg -y -i audio.wav -af silenceremove=start_periods=1:start_threshold=-75dB,areverse,silenceremove=start_periods=1:start_threshold=-75dB,areverse trimmed_audio.wav
And how to create silence:
ffmpeg -y -f lavfi -i anullsrc=channel_layout=stereo:sample_rate=48000:duration=2 silence.wav
How can I duplicate the audio and combine it with the video?

Basic syntax is
ffmpeg -an -i video -stream_loop -1 -i trimmed_audio.wav -af adelay=2000:all=1 -shortest -fflags +shortest -max_interleave_delta 100M out.mp4
Use ffmpeg 4.1 or newer.

Related

FFmpeg create muted audio file from video without audio

I have a webm file with only the video track. I would like to know if is it possible to create a new file with an only muted audio track of the same duration as the video file. Let's say that we have a webm vp8 and I want to create another file with the same duration with a muted AAC track.
Yes, using pipes, like this.
ffmpeg -an -i in.webm -f lavfi -i anullsrc -c:v copy -c:a aac -shortest -fflags +shortest -max_interleave_delta 200M -f nut - | ffmpeg -f nut -i - -vn -c copy silent.m4a

Convert mp4 video with joining animation mp4 + audio(wav, mp3) using ffmpeg shell command

I want to create .mp4 video by joining short animation(.mp4) + audio(wav, mp3) using ffmpeg shell command.
I have tried few commands to join mp4 + audio here is my example command which will generate output video.
./ffmpeg -y -i ./output/preview-2.mp4 -i ./output/audio-file.mp3 -vf "pad=ceil(iw/2)*2:ceil(ih/2)*2" -r 25 -vcodec libx264 -pix_fmt yuv420p ./output/converted-video.mp4
But I want to play my animation till audio playing. The above FFMPEG command only join my animation(short video .mp4) file with audio and stopped animation playing after duration of short video reached to end (let's say animation file duration is 10seconds and stopped playing after 10 seconds). But my audio is about 3 minutes and I want to re-play the animation video again and again till the audio file duration (3 minutes). Just like a looping effect.
Add -stream_loop -1 and -shortest:
./ffmpeg -y -stream_loop -1 -i ./output/preview-2.mp4 -i ./output/audio-file.mp3 -vf "pad=ceil(iw/2)*2:ceil(ih/2)*2" -r 25 -vcodec libx264 -pix_fmt yuv420p -shortest ./output/converted-video.mp4

FFMPEG vsync drop and regeneration

According to the ffmpeg documentation
-vsync parameter
Video sync method. For compatibility reasons old values can be specified as numbers. Newly added values will have to be
specified as strings always.
drop
As passthrough but destroys all timestamps, making the muxer
generate fresh timestamps based on frame-rate.
It appears that the mpegts mux does not regenerate the timestamps correctly (PTS/DTS); however, piping the output after vsync drop to a second process as raw h264 does force mpegts to regenerate the PTS.
Generate test stream
ffmpeg -f lavfi -i testsrc=duration=20:size=1280x720:rate=50 -pix_fmt yuv420p -c:v libx264 -b:v 4000000 -x264-params ref=1:bframes=0:vbv-maxrate=4500:vbv-bufsize=4000:nal-hrd=cbr:aud=1:bframes=0:intra-refresh=1:keyint=30:min-keyint=30:scenecut=0 -f mpegts -muxrate 5985920 -pcr_period 20 video.ts -y
Generate output ts that has correctly spaced PTS values
ffmpeg -i video.ts -vsync drop -c:v copy -bsf:v h264_mp4toannexb -f h264 - | ffmpeg -fflags +igndts -fflags +nofillin -fflags +genpts -r 50 -i - -c:v copy -f mpegts -muxrate 5985920 video_all_pts_ok.ts -y
Generate output ts where all PTS are zero
ffmpeg -i video.ts -vsync drop -c:v copy -bsf:v h264_mp4toannexb -f mpegts - | ffmpeg -fflags +igndts -fflags +nofillin -fflags +genpts -r 50 -i - -c:v copy -f mpegts -muxrate 5985920 video_all_pts_zero.ts -y
It appears that vsync drop does destroy them but the mpegts doesn't regenerate them? Any ideas on what needs adding to get it to work as a single ffmpeg command?
Tested on both Linux and Windows with the same result
Try recoding the video just using -vsync 1, without -fflags +genpts. I found some good information here. This guy talking about streaming video. So highest quality isn't his objective. But there is useful info.
https://videoblerg.wordpress.com/2017/11/10/ffmpeg-and-how-to-use-it-wrong/
Section one – Constant frame rate
"-r is used to specify the output frame rate. This must be the same as the input frame rate to eliminate judder. This is used in conjunction with the -vsync parameter using the 1 option which will retime the PTS/DTS timestamps accordingly"
Section six – Audio [Has some good advice too]
"-af "aresample=async=1:min_hard_comp=0.100000:first_pts=0" helps to keep your audio lined up with the beginning of your video. It is common for a container to have the beginning of the video and the beginning of the audio start at different points. By using this your container should have little to no audio drift or offset as it will pad the audio with silence or trim audio with negative PTS timestamps if the audio does not actually start at the beginning of the video."
I haven't tried this yet, no videos with sync problems at the moment.

Create muted video and black screen video with FFmpeg

I'm trying to use FFmpeg to generate the following from a local mp4 file:
A copy of the original video with no audio
A copy of the original video with audio but without visuals (a black screen instead). This file also needs to be in mp4 format.
After reading through the documentation I am struggling to get the terminal commands right. To remove the audio I have tried this command without any success:
ffmpeg -i file.mp4 -map 0:0 -map 0:2 -acodec copy -vcodec copy
Could anyone guide me towards how to accomplish this?
Create black video and silent audio
Use the color and anullsrc filters. Example to make 10 second output, 1280x720, 25 frame rate, stereo audio, 44100 sample rate:
ffmpeg -f lavfi -i color=size=1280x720:rate=25:color=black -f lavfi -i anullsrc=channel_layout=stereo:sample_rate=44100 -t 10 output.mp4
Remove audio
Only keep video:
ffmpeg -i input.mp4 -map 0:v -c copy output.mp4
Keep everything except audio:
ffmpeg -i input.mp4 -map 0 -map -0:a -c copy output.mp4
See FFmpeg Wiki: Map for more info on -map.
Make video black but keep the audio
Using the drawbox filter.
ffmpeg -i input.mp4 -vf drawbox=color=black:t=fill -c:a copy output.mp4
Generate silent audio
See How to add a new audio (not mixing) into a video using ffmpeg? and refer to the anullsrc example.
To remove the audio you can use this:
ffmpeg -i file.mp4 -c copy -an file-nosound.mp4
notice the -an option
-an (output)
Disable audio recording.
To keep audio but "replace" the video with a black screen, you could do this:
ffmpeg -i file.mp4 -i image.png -filter_complex overlay out.mp4
image.png is a black wallpaper that is placed on top of the video, but there should be better ways of full removing the frames, you could either extract the audio and later create a new video with the audio as a background

Mix audio/video of different lengths with ffmpeg

I want to mix video from video.mp4 (1 minute duration) and audio from audio.mp3 (10 minute duration) into one output file with a duration of 1 minute. The audio from audio.mp3 should be from the 4 min - 5 min position. How can I do this with ffmpeg?
If video.mp4 has no audio
You can use this command:
ffmpeg -i video.mp4 -ss 00:04:00 -i audio.mp3 -c copy -shortest output.mkv
The audio will be from the 4 minute position (-ss 00:04:00) as requested in the question.
This example will stream copy (re-mux) the video and audio–no re-encoding will happen.
If video.mp4 has audio
You will have to add the -map option as described here: FFmpeg mux video and audio (from another video) - mapping issue.
If the audio is shorter than the video
Add the apad filter to add silent padding:
ffmpeg -i video.mp4 -ss 00:04:00 -i audio.mp3 -c:v copy -af apad -shortest output.mkv
Note that filtering requires re-encoding, so the audio will be re-encoded in this example.

Resources