Question
I am trying to figure out how to sample a video stream x[n]
every N
frames, starting at frame n_i
, i < N
, so that I end up with N
new videos of length len(x) / N
.
In formula this is simply: y_i[n] = x[n_i + n * N]
.
Here there is a diagram of what I am trying to achieve:
The greedy solution would be simply dumping the frames to a folder and then create new videos out of appropriately indexed frames.
I was hoping there were some more elegant solution with ffmpeg
since I have to process hundreds of video.
Implementation
Finally, I managed to write the final implementation, which I am reporting here for completeness.
It does scale the minimum dimension to 256
, does not process more than max_frames
; performs the sampling every k
frames, send the first k - 1
samples to one folder and the k
-th one to another one. It also set the output frame rate to the input average frame rate, since otherwise some videos will go at 120 Hz...
k=5
kk=$(awk "BEGIN{print 1/$k}")
ffmpeg \
-i $src_video_path \
-an \
-loglevel error \
-filter_complex \
"setpts=$kk*PTS, \
scale=w=2*trunc(128*max(1\, iw/ih)):h=2*trunc(128*max(1\, ih/iw))[m]; \
[m]select=n=$k:e=(mod(n\,$k)+1)*lt(n\,$max_frames) \
$(for ((i=1; i<=$k; i++)); do
echo -n "[a$i]"
done)" \
$(for ((i=1; i<$k; i++)); do
echo -n "-r $fps -map [a$i] $dst_video_path/$i.mp4 "
done
echo -n "-r $fps -map [a$k] $val_video_path/$k.mp4"
)