Add audio (with an offset) to video with FFMPEG - audio

I have a 10 minute video and a 50 minute audio mp3.
The video starts at 500 seconds into the audio.
Using FFMPEG, how can I add the the audio to the video but specify a 500 seconds audio offset (So that they sync up)?
EDIT:
Down the bottom of this page it suggests how to specify an offset.
$ ffmpeg -i video_source -itsoffet delay -i audio_source -map 0:x -map 1:y .......
However, when I apply this, it still starts the audio from the start.

We are 8 years later, and the -itsoffset does work.
Exactly as in your linked page:
ffmpeg -i input_1 -itsoffset 00:00:03 -i input_2
Note that you place the -itsoffset switch before the input you want to delay, in this case input_2 will be delayed.
So in your case that the video starts later, you would add -itsoffset 00:08:20 before the video input.

I couldn't get audio to offset properly either, and some searching suggests that -itsoffset is currently broken.
You could try and get/compile an old version of ffmpeg before it broke (which doesn't sound like much fun).
Alternately, you could pad your audio with the necessary silence using something like sox and then combine:
sox -null silence.mp3 trim 0 500 # use -r to adjust sample-rate if necessary
sox silence.mp3 input.mp3 padded_input.mp3
ffmpeg -i in.avi -i padded_input.mp3 out.avi

Related

Ffmpeg mixing audio only for n number of videos using offset with an altered duration

I want to mix audio stream of n amount of video files with ffmpeg, with certain parameters such as:
Duration: I want to specify how long each audio is going to play for each output. For example if I specify ffmpeg -i -d:5 first.mp4 -i second.mp4 it should play the audio from first.mp4 for 5 seconds (I don't know if -d:5 is a real tag it's just an example I've made ).
Starting point: I want to specify when a given file is going start on the output, I probably need to use -itsoffset 5 but I don't know if it's the right one in terms of interacting with other commands, in on itself it works fine. For example: ffmpeg -i -isoffset 5 first.mp -i second.mp4 causes the second.mp4 to start immediately, and first.mp4 to start after 5 seconds.
Segmentation: This is the tricky one, I want to specify at which point the input's audio should start. It's like the -ss flag but the problem is it's not working together with -itsoffset. For example when I say ffmpeg -i -ss 5 first.mp4 -i second.mp4 both files should start immediately on the output, but first.mp4 should start on it's 5 seconds. So the 5th second of first.mp4 is heard at the 1st second of the output.
This is what I'm trying to achieve, my problem is that I don't know how to implement 'duration' and -ss is not working together with -itsoffset.
At the end I should have something similar to this:
ffmpeg -y -d 5 -itsoffset 3.5 -i first.mp4 -d 10 -ss 10 -itsoffset 5.3 -i 3 -vn -copyts -async 1 -filter_complex amix=inputs=2 out.mp
Which should result in an audio that sounds like this: The first 3.5 seconds are empty, no audio is heard. Then first.mp4 is heard from it's beginning for 5 seconds. When the outputs timestamp reaches 5.3, the 10th seconds of second.mp4 is heard (while first.mp4 is still playing, it's supposed to play until 8.5, so I should hear both files at the same time.) for 10 seconds.
I can't find an example of this and some sources are out-of date.
Try something like this:
ffmpeg -t 5 -ss 0 -i first.mp4 \
-t 10 -ss 10 -i second.mp4 \
-filter_complex \
[0:a]adelay=3500:all=1[c1];\
[1:a]adelay=5300:all=1[c2];\
[c1][c2]amix=inputs=2[aout] \
-map [aout] out.mp3

FFMPEG encode audio and forced subtitles at same time?

I'm using latest static build of ffmpeg windows.
My input file (.mkv) is:
[video] - 1080, V_MPEG4/ISO/AVC, 14.6 Mbps, ID#0
[audio] - DTS 5.1, 1510 Kbps, ID#1
[subtitles] - S_TEXT/ASS Lossless English, ID#14
My problem is this: I convert the audio, so that my target player, a XB1 console (media support faq), is able to play audio/video. However sometimes its rather difficult to hear or parts may be in foreign language, so I want to force the english subtitles into the mix at the same time I convert the audio.
Currently for the audio, I use the following command
ffmpeg -i input.mkv -codec copy -acodec ac3 output.mkv
Can I somehow tie in the forced subtitles (onto the video) in order to save an extra process of taking the output.mkv and trying to force subtitles on?
Edit: I've tried using the following command to extract subtitles to be able to edit them
ffmpeg -i Movie.mkv -map 0:s:14 subs.srt
However i get the error: Stream map '0:s:14' matches no streams
Edit2: attempted to extract subtitles and succeeded with
ffmpeg -i input.mkv -map 0:14 -c copy subtitles.ass
but still looking to force the subtitles, nonetheless!
Also - a little bonus to this question - can I somehow extract the .ass file and edit it to only produce subtitles for foreign parts - so english audio doesn't have subtitles during the movie but foreign audio does have subtitles?
Cheers
Edit3:
When I try to use both of the commands at once (my earlier mentioned audio converter & one from the ffmpeg wiki)
ffmpeg -i input.mkv -codec copy -acodec ac3 -vf "ass=subs.ass" output.mkv
I get the following error from ffmpeg,
Filtergraph 'ass=subs.ass' was defined for video output stream 0:0 but codec copy was selected.
Filtering and streamcopy cannot be used together.
Since your media player does not support subtitles, the text has to be burnt onto the video image. For that, use
ffmpeg -i input.mkv -vf "ass=subs.ass" -c:v libx264 -crf 20 -c:a ac3 output.mkv
This will re-encode the video, since text is being added. The CRF value controls the video quality. Lower values produce better quality but larger files. 18 to 28 is a decent range to try.

FFMPEG merging audio and video to get resulting video

I need to merge audio and video using ffmpeg so that, it should result in a video with the same duration as of audio.
I have tried 2 commands for that requirement in my linux terminal. Both the commands work for a few of the input videos; but for some other input_videos, they produce output same as the input video, the audio doesn't get merged.
The commands, I have tried are -
ffmpeg -i wonders.mp4 -i Carefull.mp3 -c copy testvid.mp4
and
ffmpeg -i wonders.mp4 -i Carefull.mp3 -strict -2 testvid.mp4
and
ffmpeg -i video.mp4 -i audio.wav -c:v copy -c:a aac -strict
experimental output.mp4
and these are my input videos -
samplevid.mp4
https://vid.me/z44E
duration - 28 seconds
size - 1.1 MB
status - working
And
wonders.mp4
https://vid.me/gyyB
duration - 97 seconds
size - 96 MB
status - not working
I have observed that the large size (more than 2MB) of the input video is probably the issue.
But, still I want the fix.

How to add audio to video file at a specific time using ffmpeg

I have an avi and a wav file. Let's suppose the video file is one hour long, and the audio file 30 minutes long and it's associated with the last 30 minutes of the video file.
Is there a way to create a new video file with the video and audio combined but audio starting after the first 30 minutes of the video?
You can simply append a silent audio to the beginning of the audio file using aevalsrc filter. To create a 30 sec of silent audio,
aevalsrc=0:d=30
To do this you can use filter_complex with map options. Following is the FFmpeg command I'm suggesting.
ffmpeg -i input_video -i input_audio -filter_complex "
aevalsrc=0:d=30[s1];
[s1][1:a]concat=n=2:v=0:a=1[aout]" -c:v copy -map 0:v -map [aout] output_video
Else you can try amerge and adelay where doc itself has a clear explanation.
Hope this helps you!

Normalize audio in an avi file

I have an avi file that has different levels of audio. Is there a way to decrease and increase appropriately where needed the audio of my file using ffmpeg?
In ffmpeg you can use the volume filter to change the volume of a track. Make sure you download a recent version of the program.
Find out the gain to apply
First you need to analyze the audio stream for the maximum volume to see if normalizing would even pay off:
ffmpeg -i video.avi -af "volumedetect" -f null /dev/null
Replace /dev/null with NUL on Windows. This will output something like the following:
[Parsed_volumedetect_0 # 0x7f8ba1c121a0] mean_volume: -16.0 dB
[Parsed_volumedetect_0 # 0x7f8ba1c121a0] max_volume: -5.0 dB
[Parsed_volumedetect_0 # 0x7f8ba1c121a0] histogram_0db: 87861
As you can see, our maximum volume is -5.0 dB, so we can apply 5 dB gain. If you get a value of 0 dB, then you don't need to normalize the audio.
Apply the volume filter:
Now we apply the volume filter to an audio file. Note that applying the filter means we will have to re-encode the audio stream. What codec you want for audio depends on the original format, of course. Here are some examples:
Plain audio file: Just encode the file with whatever encoder you need:
ffmpeg -i input.wav -af "volume=5dB" output.mp3
Your options are very broad, of course.
AVI format: Usually there's MP3 audio with video that comes in an AVI container:
ffmpeg -i video.avi -af "volume=5dB" -c:v copy -c:a libmp3lame -q:a 2 output.avi
Here we chose quality level 2. Values range from 0–9 and lower means better. Check the MP3 VBR guide for more info on setting the quality. You can also set a fixed bitrate with -b:a 192k, for example.
MP4 format: With an MP4 container, you will typically find AAC audio. We can use ffmpeg's build-in AAC encoder.
ffmpeg -i video.mp4 -af "volume=5dB" -c:v copy -c:a aac -strict experimental -b:a 192k output.mp4
Here you can also use other AAC encoders. Some of them support VBR, too. See this answer and the AAC encoding guide for some tips.
In the above examples, the video stream will be copied over using -c:v copy. If there are subtitles in your input file, or multiple video streams, use the option -map 0 before the output filename.
The author's info is: Jon Skarpeteig in SuperUser
You can use my ffmpeg-normalize script for that.
First, install a recent version of ffmpeg. Then, install via pip install ffmpeg_normalize, then run it on an AVI file:
ffmpeg-normalize input.avi -o output.mkv -c:a aac -b:a 192k
Here, we're choosing to re-encode the audio with AAC at 192 kBit/s, and copy the video stream over to the output. This will perform EBU R128 normalization, but simple peak/RMS normalization is also possible.

Resources