ffmpeg concat drops audio frames - audio

I have an mp4 file and I want to take two sequential sections of the video out and render them as individual files, later recombining them back into the original video. For instance, with my video video.mp4, I can run
ffmpeg -i video.mp4 -ss 56 -t 4 out1.mp4
ffmpeg -i video.mp4 -ss 60 -t 4 out2.mp4
creating out1.mp4 which contains 00:00:56 to 00:01:00 of video.mp4, and out2.mp4 which contains 00:01:00 to 00:01:04. However, later I want to be able to recombine them again quickly (i.e., without reencoding), so I use the concat demuxer,
ffmpeg -f concat -safe 0 -i files.txt -c copy concat.mp4
where files.txt contains
file out1.mp4
file out2.mp4
which theoretically should give me back 00:00:56 to 00:01:04 of video.mp4, however there are always dropped audio frames where the concatenation occurs, creating a very unpleasant sound artifact, an audio blip, if you will.
I have tried using async and -af apad on initially creating the two sections of the video but I am still faced with the same problem, and have not found the solution elsewhere. I have experienced this issue in multiple different use cases, so hopefully this simple example will shed some light on the real problem.

I suggest you export segments to MOV with PCM audio, then concat those but with re-encoding audio.
ffmpeg -i video.mp4 -c:a pcm_s16le -ss 56 -t 4 out1.mov
...
and then
ffmpeg -f concat -safe 0 -i files.txt -c:v copy concat.mp4

Related

Cut a video in between key frames without re-encoding the full video using ffpmeg?

I would like to cut a video at the beginning at any particular timestamp, and it need to be precise, so the nearest key frame is not good enough.
Also, these videos are rather long - an hour or longer - so I would like to avoid re-encoding this altogether if possible, or otherwise only re-encode a minimal fraction of the total duration. Thus, would like to maximise the use of -vcodec copy.
How can I accomplish this using ffmpeg?
NOTE: See scenario, and my own rough idea for a possible solution below.
Scenario:
Original video
Length of 1:00:00
Has a key frame every 10s
Desired cut:
From 0:01:35 through till the end
Attempt #1:
Using -ss 0:01:35 -i blah.mp4 -vcodec copy, what results is a file where:
audio starts at 0:01:30
video also starts at 0:01:30
this starts both the audio and the video too early
using -i blah.mp4 -ss 0:01:35 -vcodec copy, what results is a file where:
audio starts at 0:01:35,
but the video is blank/ black for the first 5 seconds,
until 0:01:40, when the video starts
this starts the audio on time,
but the video starts too late
Rough idea
(1) cut 0:01:30 to 0:01:40
re-encode this to have new key frames,
including one at the target time of 0:01:35
then cut this to get the 5 seconds from 0:01:35 through 0:01:40
(2) cut 0:01:40 through till the end
without re-encoding, using -vcodec copy
(3) ffmpeg concat the first short clip (the 5 second one)
with the second long clip
I know/ can work out the commands for (2) and (3), but am unsure about what commands are needed for (1).
List timestamps of key frames:
ffprobe -v error -select_streams v:0 -skip_frame nokey -show_entries frame=pkt_pts_time -of csv=p=0 input.mp4
It will output something like:
0.000000
2.502000
3.795000
6.131000
10.344000
12.554000
16.266000
...
Let's say you want to delete timestamps 0 to 5, and then stream copy the remainder. The closest following key frame is 6.131.
Re-encode 5 to 6.131. Ensure the input and output match attributes and formats. For MP4 default settings should do most of the work, assuming H.264/AAC, but you may have to manually match the profile.
ffmpeg -i input.mp4 -ss 5 -to 6.131 trimmed.mp4
Make input.txt for the concat demuxer:
file 'trimmed.mp4'
file 'input.mp4'
inpoint 6.131
Concatenate:
ffmpeg -f concat -i input.mp4 -c copy output.mp4
try
ffmpeg -i src.mp4 -vcodec copy -reset_timestamps 1 -map 0 out.mp4
or
ffmpeg -i src.mp4 -vcodec copy -reset_timestamps 1 -map 0 src_.m3u8
which generates hls playlists

ffmpeg exported file is broken

I am using using ffmpeg to trim and join several audio files. The ouput audio file can be played as a normal file, but when I open it in some C# codes, exceptions are always throwing, says "MP3 Header is missing". I am new to ffmpeg and I googled for many times but seems no one is encountering this problem.
Here is my ffmpeg command to trim an audio file:
ffmpeg -i input_1.mp3 -ss 00:00:00.000 -to 00:00:01.000 -acodec libmp3lame 1.mp3
(The input audio format can be mp3/wma/wav/m4a/aac)
And the following is for joining all the audio files:
ffmpeg -safe 0 -f concat -i list.txt -acodec libmp3lame join.mp3
The list.txt contents:
file C:\\1.mp3
file C:\\2.mp3
file C:\\3.mp3
Problem soved! Thanks to Gyan's comment under my question.
The main point:
Make sure all converted files have same sampling rate and channel count i.e. add -ar 44100 -ac 2
The above parameters did solve my problem.

Using ffmpeg to split MP3 file to multiple equally sound length files

How to use the command line tool ffmpeg on Windows to split a sound file to multiple sound files without changing the sound properties same everything each one is fixed 30 seconds length. I got this manual example from here:
ffmpeg -i long.mp3 -acodec copy -ss 00:00:00 -t 00:00:30 half1.mp3
ffmpeg -i long.mp3 -acodec copy -ss 00:00:30 -t 00:00:30 half2.mp3
But is there a way to tell it to split the input file to equally sound files each one is 30 seconds and the last one is the remaining what ever length.
You can use the segment muxer.
ffmpeg -i long.mp3 -acodec copy -vn -f segment -segment_time 30 half%d.mp3
Add -segment_start_number 1 to start segment numbering from 1.

FFmpeg concat audio with video or gif looping

I'm looking for a solution in FFmpeg to merge audio (mp3) with a short video loop, or gif.
I've already been able to generate a video from an image by joining with audio, but the video stays static frame for the audio duration, the command to make this:
ffmpeg -loop 1 -i imagem.jpg -i audio.mp3 -vcodec h264 -tune stillimage -acodec aac -b:a 64k -pix_fmt yuv420p -shortest video.mp4
I need video that has the duration of the audio, but that uses a loop of another mp4 or a gif. To keep repeating for the duration of the audio.
To do this with a video (MP4 or other format) you should use the Concatenate demuxer.
First create a text file with a list of the paths of the videos you want to concatenate. In your case it will be a list of the same video file, like the following.
# mylist.txt
file /your/path/video.mp4
file /your/path/video.mp4
file /your/path/video.mp4
The paths can be absolute or relative.
Then you need to use the concat demuxer option.
ffmpeg -f concat -safe 0 -i mylist.txt -c copy output.mp4
This will generate an mp4 with your original video looping 3 times. If your original video is 4 seconds long, then the output will be 12 seconds long. I suggest that you create a video just a bit longer than your audio track and then use the -shortest option when creating your final video.
You can add the audio within this same command like you do in your post. So, all together will look like this:
ffmpeg -f concat -safe 0 -i mylist.txt -i audio.mp3 -c:v copy -c:a copy -shortest output.mp4
In my example I do a stream copy for my output (this will work just fine and will be very fast), but you can use the codecs you want for yours (like H264 and AAC like your post).
You can find more info in the concat demuxer documentation or better yet the concat wiki.
At the moment I don't know if there's a way to do this with a gif file.

ffmpeg leaves audio gap when concatening videos

I am trying to cut a video in 2 parts then reassembling with ffmpeg but the final output has a small audio glitch right where the segments meet. I am using the following command to split the video 1.mp4 in 2 parts:
ffmpeg -i 1.mp4 -ss 00:00:00 -t 00:00:02 -async 1 1-1.mp4
and
ffmpeg -i 1.mp4 -ss 00:00:02 -t 00:00:02 -async 1 1-2.mp4
Once I have the 2 parts I am concatening them back together with:
ffmpeg -f concat -i files.txt -c copy output.mp4
files.txt is correctly listing both files. Can anyone point me to where the problem might be?
Thanks
The glitch is likely due to the audio priming sample showing up in between.
Since you're re-encoding the segments, you can do this in one command:
ffmpeg -i 1.mp4 -filter_complex
"[0]trim=duration=2[v1];[0]trim=2:4,setpts=PTS-STARTPTS[v2];
[0]atrim=duration=2[a1];[0]atrim=2:4,asetpts=PTS-STARTPTS[a2];
[v1][a1][v2][a2]concat=n=2:v=1:a=1[v][a]"
-map "[v]" -map "[a]" output.mp4
I had the same problem for about 3 weeks.
just merge the mp3 files using sox
sox in1.mp3 in2.mp3 in3.mp3 out.mp3
When I used concat with FFMPEG it made 12.5ms (I saw them on using Audacity) audio gaps. (I don't know why)
Maybe for your case it'll be better to extract the audio and video to two separate files using ffmpeg, merge them (video using FFMPEG and audio using sox) then put the files together into one container (mp4) file

Resources