Search code examples
ffmpeg

FFmpeg: How to split video efficiently?


I wish to split a large avi video into two smaller consecutive videos. I am using ffmpeg.

One way is to run ffmpeg two times:

ffmpeg -i input.avi -vcodec copy -acodec copy -ss 00:00:00 -t 00:30:00 output1.avi
ffmpeg -i input.avi -vcodec copy -acodec copy -ss 00:30:00 -t 00:30:00 output2.avi

But according to manpage of ffmpeg, I can make more than one ouput file from one input file using just one line:

ffmpeg -i input.avi -vcodec copy -acodec copy -ss 00:00:00 -t 00:30:00 output1.avi \
   -vcodec copy -acodec copy -ss 00:30:00 -t 00:30:00 output2.avi

My question is, does the later approach save computation time and memory?


Solution

  • The ffmpeg wiki links back to this page in reference to "How to split video efficiently". I'm not convinced this page answers that question, so I did as @AlcubierreDrive suggested, a comparison.

    Preamble (2023): "fast" seeking

    The following comparisons are written using Output seeking. They can be both much quicker by adding -ss before the input file for a "fast seek" (Input seeking).

    Before FFmpeg 2.1, this type of seeking could be imprecise, but that is no longer the case.

    Comparison: one VS two separate commands

    echo "Two commands" 
    time ffmpeg -v quiet -y -i input.ts -vcodec copy -acodec copy -ss 00:00:00 -t 00:30:00 -sn test1.mkv
    time ffmpeg -v quiet -y -i input.ts -vcodec copy -acodec copy -ss 00:30:00 -t 01:00:00 -sn test2.mkv
    echo "One command" 
    time ffmpeg -v quiet -y -i input.ts -vcodec copy -acodec copy -ss 00:00:00 -t 00:30:00 -sn test3.mkv \
      -vcodec copy -acodec copy -ss 00:30:00 -t 01:00:00 -sn test4.mkv
    

    Which outputs...

    Two commands
    real    0m16.201s
    user    0m1.830s
    sys 0m1.301s
    
    real    0m43.621s
    user    0m4.943s
    sys 0m2.908s
    
    One command
    real    0m59.410s
    user    0m5.577s
    sys 0m3.939s
    

    I tested a SD & HD file, after a few runs & a little maths.

    Two commands SD 0m53.94 #2 wins  
    One command  SD 0m49.63  
    
    Two commands SD 0m55.00  
    One command  SD 0m52.26 #1 wins 
    
    Two commands SD 0m58.60 #2 wins  
    One command  SD 0m58.61 
    
    Two commands SD 0m54.60  
    One command  SD 0m50.51 #1 wins 
    
    Two commands SD 0m53.94  
    One command  SD 0m49.63 #1 wins  
    
    Two commands SD 0m55.00  
    One command  SD 0m52.26 #1 wins 
    
    Two commands SD 0m58.71  
    One command  SD 0m58.61 #1 wins
    
    Two commands SD 0m54.63  
    One command  SD 0m50.51 #1 wins  
    
    Two commands SD 1m6.67s #2 wins  
    One command  SD 1m20.18  
    
    Two commands SD 1m7.67  
    One command  SD 1m6.72 #1 wins
    
    Two commands SD 1m4.92  
    One command  SD 1m2.24 #1 wins
    
    Two commands SD 1m1.73  
    One command  SD 0m59.72 #1 wins
    
    Two commands HD 4m23.20  
    One command  HD 3m40.02 #1 wins
    
    Two commands SD 1m1.30  
    One command  SD 0m59.59 #1 wins  
    
    Two commands HD 3m47.89  
    One command  HD 3m29.59 #1 wins  
    
    Two commands SD 0m59.82  
    One command  SD 0m59.41 #1 wins  
    
    Two commands HD 3m51.18  
    One command  HD 3m30.79 #1 wins  
    

    SD file = 1.35GB DVB transport stream
    HD file = 3.14GB DVB transport stream

    Conclusion

    The single command is better if you are handling HD, it agrees with the manuals comments on using -ss after the input file to do a 'slow seek'. SD files have a negligible difference.