FFMPEG to remove audio but keeping background sound - ffmpeg

I am trying to add voice over to the existing video which has some audio in English and some background sound. I am trying to add other than English audio on top of it and keeping background sound. But when I add new audio it removes all the background sound and when it adds new audio which makes it robotic as original background sound is lost.
When I add new audio by using amix filter, it keeps all sound like English and new language both, and both plays together.
Is there any way to separate background sound and speaking audio from video separately?
Is it possible to mute or remove audio from only parts of video like offset between time frames?
Command that I am using for add new audio
ffmpeg -i independance_speech.mp4 -i 01.mp3 -filter_complex "[1]adelay=10000[s1];[s1]amix=inputs=2[a]" -map 0:v -map "[a]" -c:v copy result.mp4

Related

Multiple side-to-side video streams in one file without transcoding

I am investigating a possibility to store video streams which are coming from few sources already coded in h264 without video transcoding as the device I would like to use for this project won't be capable of transcoding combined video on the fly.
What I am looking for is two or more pictures side to side (not video concatenation) packed into mp4/avi/mkv.
I believe mkv container supports such kind of packaging but I've not been able to find appropriate options for ffmpeg or other tool to store it this way. What it does is very slow video transcoding into one big h264 stream.
If your player can handle it just make it perform the side-by-side view. No encoding or muxing required.
mpv video player
Example using mpv:
mpv --lavfi-complex="[vid1][vid2]hstack[vo];[aid1][aid2]amix[ao]" input1.mp4 --external-file=input2.mp4
The above example assumes each input has the same height. Otherwise you will have to add the scale, scale2ref, pad, and/or crop filters. Simple example using the crop filter to remove 20 pixels from the height:
mpv --lavfi-complex="[vid1]crop=iw:ih-20[c];[c][vid2]hstack[vo];[aid1][aid2]amix[ao]" input1.mp4 --external-file=input2.mp4
See the mpv documentation and FFmpeg Filters for more info.
Just specify multiple inputs.
ffmpeg -i [input 1] -i [input 2] ... -map 0 -map 1 ... -codec copy -f matroska [output]
As for the "side-to-side" part, it's up to the player to determine the presentation. If you don't control the player and you need a specific layout or presentation, then you must "burn" all these video streams into a new one and encode it as a new single stream.

Produce waveform video from audio using FFMPEG

I am trying to create a waveform video from audio. My goal is to produce a video that looks something like this
For my test I have an mp3 that plays a short clipped sound. There are 4 bars of 1/4 notes and 4 bars of 1/8 notes played at 120bpm. I am having some trouble coming up with the right combination of preprocessing and filtering to produce a video that looks like the image. The colors dont have to be exact, I am more concerned with the shape of the beats. I tried a couple of different approaches using showwaves and showspectrum. I cant quite wrap my head around why when using showwaves the beats go past so quickly, but using showspectrum produces a video where I can see each individual beat.
ShowWaves
ffmpeg -i beat_test.mp3 -filter_complex "[0:a]showwaves=s=1280x100:mode=cline:rate=25:scale=sqrt,format=yuv420p[v]" -map "[v]" -map 0:a output_wav.mp4
This link will download the output of that command.
ShowSpectrum
ffmpeg -i beat_test.mp3 -filter_complex "[0:a]showspectrum=s=1280x100:mode=combined:color=intensity:saturation=5:slide=1:scale=cbrt,format=yuv420p[v]" -map "[v]" -an -map 0:a output_spec.mp4
This link will download the output of that command.
I posted the simple examples because I didn't want to confuse the issue by adding all the variations I have tried.
In practice I suppose I can get away with the output from showspectrum but I'd like to understand where/how I am thinking about this incorrectly. Thanks for any advice.
Here is a link to the source audio file.
What showwaves does is show the waveform in realtime, and the display window is 1/framerate i.e. if the video output is 25 fps, then each frame shows the waveform of 40 ms of audio. There's no 'history' or 'memory' so you can't (directly) get a scrolling output like it seems your reference video shows.
The workaround for this is to use the showwavespic filter to produce a single frame showing the entire waveform at a high enough horizontal resolution. Then do a scrolling overlay of that picture over a desired background, at a speed such that the scroll lasts as long as the audio.
Basic command template would be:
ffmpeg -loop 1 -i bg.png -loop 1 -i wavespic.png -i audio.mp3
-filter_complex "[0][1]overlay=W-w*t/mp3dur:y=SOMEFIXEDVALUE" -shortest waves.mp4
mp3dur above should be replaced with the duration of the audio file.

ffmpeg - output silent audio track if source has no audio or audio is shorter than source video

I need a video file whose audio and video track duration are always the same. The file must contain an audio track even if source audio has no audio track. How do I tell ffmpeg to add a silent audio track when source has no audio trace. Also, if source has an audio track that is a different duration than the video, I need ffmpeg to append silent audio to make both output audio and video the same duration. Is this possible in one line with ffmpeg?
The command below will add a silent track of the same length* as the video, if there is no audio** in the source file.
ffmpeg -i video -f lavfi -i anullsrc=cl=1 -shortest -c:v libx264 -c:a aac output.mov
*Since video frame duration and audio frame duration aren't usually identical, the lengths won't be exactly the same.
**when map is not specified, ffmpeg selects a single audio stream from among the inputs with the highest channel count. If there are two or more streams with same no. of channels, it selects stream with lowest index. anullsrc here has one channel, so it will be passed over except when source has no audio.

FFMPEG Start 2 videos at the same time but hide one until the other is finished

I have a generic intro sequence (no audio) and a main video clip. I want the audio from the main clip to play as the intro sequence is playing then the video to switch from the finished intro sequence to the main video. So almost like playing both videos at the same time but hiding one until the other is finished. Is this possible with ffmpeg? Almost like a send to back function for the video on the main clip (but keep it's audio rolling so it's in sync when it shows as the intro clip finishes).
Looks like you want a J-cut. This can be done using the overlay filter.
ffmpeg -i main.mp4 -i intro.mp4 -filter_complex "[1][0]scale2ref[intro][base]; \
[base][intro]overlay=eof_action=pass[v]" -map "[v]" -map 0:a -c:a copy out.mp4
The scale2ref filter ensures that the intro is the same resolution as the main video. Then the intro is overlaid on top of the main video, in sync, and vanishes when it ends, leaving the main video on display. The audio is copied over - no processing required.

Create a watermark in a separate track with FFmpeg

I have a PNG (alpha) file and a video file. I want to create a video in which the first track is the image and the second track is the video (PNG over video). The problem is that the PNG doesn't preserves transparency.
I need create a watermark (PNG) in a separate track with ffmpeg over video track.
ffmpeg -i base.mov -i logo.png -map 0 -map 1 output.mov
I needed the watermark is on a track (stream) separately in order to enable or disable it with quicktime pro.
Thanks.

Resources