How can I avoid a few seconds of blank video when using -vcodec copy?

5,525

Matt's suggestion about keyframes, combined with a timely hint posted to the ffmpeg mailing list, led me to a solution, although I'm not sure if it's the best solution.

First, I had to move the -ss and -t options in my extraction command so they appeared before the -i option. This causes the extraction to begin at the next earliest keyframe. So let's say I use -ss 25 -t 15 to extract from 0:25 to 0:40 in my clip, but I have keyframes every 10 seconds. Previously I would get a 15 second sample starting with 5 seconds of blank video. Now I will get a 20 second sample, running from 0:20 to 0:40, but with no blank video. In other words, I avoid the blank video but lose the accuracy of my clip selection.

To address that, I had to add the -g option to my conversion command to reformat the keyframes. I used -g 15 with -r 15 to make a keyframe every second. This allows me to choose sample locations to the nearest second, so -ss 25 -t 15 will give me the 15 second clip I asked for. I would expect the extra keyframes to make my full clip larger, but it is only about 2% larger in my tests, and that's a good trade-off for my project.

So, I changed my two commands above to:

ffmpeg -i uploaded.mov -f mp4 -vcodec libx264 -vpre medium -acodec libfaac -r 15 -g 15 -b 360k -ab 48k -ar 22050 -s 480x320 formatted.mp4

ffmpeg -ss 0 -t 30 -i formatted.mp4 -vcodec copy -acodec copy formatted_sample.mp4

And all seems well. If someone has a more efficient solution, please post and I'll change my chosen answer.

Share:
5,525

Related videos on Youtube

TheSociety
Author by

TheSociety

Updated on September 18, 2022

Comments

  • TheSociety
    TheSociety almost 2 years

    I'm processing user-uploaded videos on a CentOS web server with ffmpeg. I need to convert each video to a standard size and format, then extract a 30-second sample clip from each video. I want to use the "-vcodec copy" flag in the extraction command to avoid encoding a second time.

    This command works for my initial conversion:

    ffmpeg -i uploaded.mov -f mp4 -vcodec libx264 -vpre medium -acodec libfaac -r 15 -b 360k -ab 48k -ar 22050 -s 480x320 formatted.mp4
    

    And this sometimes works for the extraction:

    ffmpeg -i formatted.mp4 -vcodec copy -acodec copy -ss 0 -t 30 formatted_sample.mp4
    

    However, when I run the extraction command on some videos, the extracted sample clip starts with several seconds of blank video. The audio starts right away but the video doesn't start for 3-6 seconds.

    To demonstrate the problem, I've uploaded two video clips and run the above commands on them. I created the first clip in Final Cut Express and encoded it with Handbrake before uploading to the web server:

    1a) uploaded clip

    1b) converted with first command

    1c) extracted with second command, missing first six seconds

    By comparison, this second clip comes from Apple's website and does not show the problem:

    2a) uploaded clip

    2b) converted with first command

    2c) extracted with second command, no problem

    Can anyone see what's different about the two source clips? And if so, is there anything I can do in my conversion command so that when the extraction command runs, the clip is set up to avoid the missing video?

    By the way, I initially had the problem with ffmpeg 0.6.1 installed from yum, but I upgraded to the latest git version and the problem remains.

    • Macho Matt
      Macho Matt over 12 years
      How frequently do the keyframes occur in the source video? If it doesn't start with a keyframe, the output may not be displaying anything until it hits the next one.
  • slhck
    slhck over 12 years
    I didn't know that using different positions for the ss and t options would cause different outcomes.
  • TheSociety
    TheSociety over 12 years
    Yes, I haven't seen any documentation on that, but someone posted to the ffmpeg-user list, "Keyframe seeking can occur if you ask it (ie you put -ss before -i)."
  • Ryan
    Ryan about 4 years
    If I need precision shorter than 1 second, I'm not sure how to do that, especially given superuser.com/questions/1356862/…