[FFmpeg-user] Replacing Specific Frames with Specific Other

Oliver Fromme oliver at fromme.com
Thu May 15 10:01:50 CEST 2014


Sam Logan wrote:
 > On 5/7/14, Sam Logan <shapableline at gmail.com> wrote:
 > > I have a video file "Foobar.mp4" (stream 0 is a video stream, stream 1
 > > is an audio stream).
 > > 
 > > My goal is to replace video frames 56-98 (a total of exactly 43
 > > frames) of the video with a back-and-forth loop of frames 46-55 (a
 > > total of 10 frames). In other words, I want to replace frames 56, 57,
 > > 58, ..., 98 in the video with this exact sequence of 43 frames:
 > > 
 > > 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, 47, 48, 49, 50, 51, 52, 53,
 > > 54, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, 47, 48, 49, 50, 51, 52,
 > > 53, 54, 55, 54, 53, 52, 51, 50, 49
 > > 
 > > (If the pattern is not clear, it first goes down to frame 46, then
 > > goes up to frame 55, and then repeats until we get to 43 frames.)
 > > 
 > > Does anyone know how to write a filtergraph command that will
 > > accomplish this? Below, I detail my failed attempt.
 > > 
 > > ****
 > > 
 > > Anyway, my failed attempt: I tried using the overlay filter as
 > > follows. First, I extracted frames to PNGs:
 > > 
 > > ffmpeg -t 00:00:10 -i "Foobar.mp4" "Frame%04d.png"
 > > 
 > > Then I manually copied/renamed the PNGs for frames 46-55 so that they
 > > were in the order I gave above, giving them new filenames:
 > > 
 > > Frame0001.png = frame 55
 > > Frame0002.png = frame 54
 > > ...
 > > Frame0043.png = frame 49
 > > 
 > > and then deleted all other PNGs except for these 43 frames. Then I did:
 > > 
 > > ffmpeg -i "Foobar.mp4" -i "Frame%04d.png" -filter_complex
 > > "[0:v][1:v]overlay=enable='between(n,56,98)'[out]" -acodec copy -map
 > > "[out]" -map 0:1 "FoobarEdited.mp4"
 > > 
 > > But this did not work: frames 56-98 of "FoobarEdited.mp4" were indeed
 > > replaced, but all 43 frames were replaced with 43 copies of
 > > "Frame0043.png" instead of with what I was expecting: "Frame0001.png",
 > > "Frame0002.png", "Frame0003.png", etc.
 > > 
 > > Does again, anyone know how to write a filtergraph command that will
 > > accomplish my goal? Thanks.
 > > 
 > 
 > No one knows? Can anyone please help? Thanks.

My approach would be to do it without a complex filter, but
in several steps.  I haven't tried this, but I think this
should work.

1. Extract the audio track to a separate file (-acodec copy
   -vn).  Typically I use MKV as the container format for
   "temporary storage".

2. Extract frames 1 to 98, then arrange them in the way you
   want, i.e copy frames 46 to 55 to frames 56 to 98 as you
   described.  Do NOT delete frames 1 to 55.

3. Encode the PNG files 1 to 98 to a video sequence (without
   audio).  Be sure to get the parameters right, especially
   the frame rate (-r option).  Again, I recommend MKV for
   the container format.

4. Encode the rest of the source video starting at frame 99
   into another separate video file (again, without audio).
   This can be done with the -ss option.

5. Concatenate the two video sequences from step 3 and 4.
   I think this can be done without re-encoding, i.e. with
   -vcodec copy, so it should be lossless.

6. Finally, mux the resulting video with the audio track
   from step 1.

7. Check the result, especially whether video and audio is
   still in sync after frame 99.  If it isn't, go back to
   step 4 and increase or decrease the value for the -ss
   option.

There's probably a way to do it in fewer steps, but I'm
pretty sure that the above should work.

Best regards
   Oliver

-- 


More information about the ffmpeg-user mailing list