1

I have a video that is downloaded with youtube-dl. I want to create a video that is made out of an image and the downloaded video, using ffmpeg and the loop function.

./ffmpeg -f concat -safe 0 -i list.txt -c copy merged.mp4

Inside of my list.txt file is

file word_img.jpg
file youtube_video.mp4

Running the command at the bottom creates a new video. It's just that the it's the same exact thing as the youtube video. The other image never gets added. Could this have to do with the encoding?

I also tried another approach which went something like this.

./ffmpeg -t 125 -async 1 -i youtube_video.mp4\
   -t 5 -i word_img.jpg \
   -filter_complex "[0]loop=149:1:0[bgheld5]; \
                    [1]loop=149:1:0[fgheld5]; \
                    [bgheld5][fgheld5]overlay=eof_action=pass" out.mp4

This sort of works. There is a static image that get displayed for 5 seconds and then the 30 second youtube video gets played. The problems is that the audio and the video of the youtube video are out of sync by about 5 seconds.

Running ./ffmpeg -i img.jpg returns the following

Input #0, image2, from 'img.jpg':
Duration: 00:00:00.04, start: 0.000000, bitrate: 1258 kb/s
Stream #0:0: Video: mjpeg (Baseline), yuvj420p(pc, bt470bg/unknown/unknown), 640x356 [SAR 96:96 DAR 160:89], 25 tbr, 25 tbn, 25 tbc

Running ./ffmpeg -i video.mp4 returns the following

Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'video.mp4':
Metadata:
major_brand     : isom
minor_version   : 512
compatible_brands: isomiso2avc1mp41
encoder         : Lavf58.26.101
Duration: 00:02:00.04, start: 0.000000, bitrate: 575 kb/s
Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 640x356 [SAR 1:1 DAR 160:89], 440 kb/s, 24.98 fps, 24.98 tbr, 25k tbn, 49.95 tbc (default)
Metadata:
  handler_name    : ISO Media file produced by Google Inc. Created on: 
10/28/2018.
Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 128 kb/s (default)
Metadata:
  handler_name    : ISO Media file produced by Google Inc. Created on: 10/28/2018
  • Your question is a little bit confusing. Instead of showing us the source code (which is just distracting), please show the actual ffmpeg command that is being run (e.g., echo it), and the full, uncut command line output of that process. Also, I don't see your list.txt contents or the ffmpeg command that you are using to read that list.txt file (which I assume is the one that produces incorrect output), including its command-line output. – slhck Mar 10 '19 at 10:34
  • @slhck My apologies. I updated my question to include only the commands that I ran. Let me know if you need any more info. – Lance Mar 10 '19 at 17:42
  • That's much better, thanks. I think it's confusing that you wrote "I have two videos" where in fact what you really want is one video which is composed of a looping image for five seconds and then the downloaded YouTube video? I'll write up an answer… – slhck Mar 10 '19 at 17:54
2

I am assuming you have a static image file and a video that you would like to concatenate. The image should be shown for five seconds without audio; the video should follow.

You can run everything in one command with:

ffmpeg \
  -loop 1 -framerate 24 -t 5 -i image.png \
  -f lavfi -t 1 -i anullsrc \
  -i video.mp4 \
  -filter_complex " \
    [2:v]scale=320:240,setsar=sar=1[video]; \
    [0:v][1:a][video][2:a]concat=n=2:v=1:a=1 \
  " output.mp4

What it does:

  • Specify the image as input 0, looping it up to a length of 5 s at 24 fps.
  • Specify silent audio as second input 1, which is needed for concatenation
  • Specify the video as third input 2
  • Scale the video to the same size as the image (but you could of course also scale the image… just swap the input identifiers 2:v to 1:v and rename the label video)
  • Set its sample aspect ratio to 1 (this is a quick fix for differing SARs; you may have to be more explicit like shown here)
  • Concatenate logo + silent audio with the video.

You can also use the scale2ref filter (another example here) to scale the logo to the video:

-filter_complex " \
  [0:v][2:v]scale2ref[logo][video]; \
  [logo]setsar=sar=1[logo];  \
  [logo][1:a][video][2:a]concat=n=2:v=1:a=1 \
"
| improve this answer | |
  • That throws an error Input link in1:v0 parameters (size 320x240, SAR 1:1) do not match the corresponding output link in0:v0 parameters (640x356, SAR 96:96) [Parsed_concat_2 @ 0x7ffabec59800] Failed to configure output pad on Parsed_concat_2 Error reinitializing filters! Failed to inject frame into filter network: Invalid argument The image and the video both appear to have the same dimensions – Lance Mar 10 '19 at 18:27
  • Apparently they have different sizes – make sure that what the log shows is matching for both inputs. Your image seems to be 640x354, and the video 320x240. Can you please update your question and show ffmpeg -i image.jpg and ffmpeg -i youtube_video.mp4 console output? – slhck Mar 10 '19 at 18:45
  • Yep. No prob. I updated my question – Lance Mar 10 '19 at 18:52
  • See the updated answer. Maybe the scale2ref filter works; it scales up the logo to the video size. You have to manually set the sample/display aspect ratio if they differ. See also superuser.com/a/1191054/48078 – slhck Mar 10 '19 at 18:57
  • How would it work if I wanted to add have a sequence where there is the video playing for it's full duration followed by an image playing for 5 seconds followed by the video playing for its full duration again? – Lance Mar 10 '19 at 19:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.