Search code examples
macosopencvvideopython-3.5subsampling

Sample frames of video


I'm looking for a way in OS X/Python3.5 to take an .avi video file, subsample every 100th frame, and combine those frames into its own video.

In my particular case the video is 30 seconds at 20fps, so the new video would only be 6 frames long (I want to do this for multiple videos, then combine them all together later).

I installed opencv, but am having trouble finding documentation on how to do this. I could also use a different library if it's easier.


Solution

  • Using ffmpeg and creating a couple of custom bash functions:

    subsample () { export target=$2 ; find . -type f -name "*$1*" \
                  -execdir bash -c 'ffmpeg -i "${0}" -vf "select=not(mod(n\,100))" \
                  -vsync vfr -q:v 2 "${target}/${0}_%03d.png"' {} \; \
                  -execdir bash -c 'ffmpeg -r 60 -f image2 -i "${target}/${0}_%03d.png" \
                  -vcodec libx264 -crf 25 -pix_fmt yuv420p "${target}/clip_${0}"' {} \; \
                  ; rm -f ${target}/*$1_*.png ;
                 }
    
    subconcat () { export target=$2 ; ffmpeg -f concat -safe 0 -i \
                  <(printf "file '$PWD/%s'\n" ./clip_*.${1}) -copytb 1 \
                  -c copy ${2}/combined_output.${1} ; 
                 }
    

    Save the functions in your ~/.bash_profile.

    $ source ~/.bash_profile
    

    synopsis

    subsample|subconcat <ext> <target path>
    

    (eg. pwd /path/movies):

    subsample avi /path/to/output
    

    subsample - recursively find any avi and combine every 100th frame into a new video @ target.

    subconcat - combines all clip_*.ext videos of designated extension @ target.

    It's presumed you'll want to adjust the ffmpeg settings to suit you, although the examples above should give you a general idea of what is possible using only ffmpeg and bash find.