Split video into images with ffmpeg-python
Question:
As far as I understand ffmpeg-python
is main package in Python to operate ffmpeg
directly.
Now I want to take a video and save it’s frames as separate files at some fps.
There are plenty of command line ways to do it, e.g. ffmpeg -i video.mp4 -vf fps=1 img/output%06d.png
described here
But I want to do it in Python. Also there are solutions [1] [2] that use Python’s subprocess
to call ffmpeg
CLI, but it looks dirty for me.
Is there any way to to make it using ffmpeg-python
?
Answers:
I’d suggest you try imageio module and use the following code as a starting point:
import imageio
reader = imageio.get_reader('imageio:cockatoo.mp4')
for frame_number, im in enumerate(reader):
# im is numpy array
if frame_number % 10 == 0:
imageio.imwrite(f'frame_{frame_number}.jpg', im)
You can also use openCV for that.
Reference code:
import cv2
video_capture = cv2.VideoCapture("your_video_path")
video_capture.set(cv2.CAP_PROP_FPS, <your_desired_fps_here>)
saved_frame_name = 0
while video_capture.isOpened():
frame_is_read, frame = video_capture.read()
if frame_is_read:
cv2.imwrite(f"frame{str(saved_frame_name)}.jpg", frame)
saved_frame_name += 1
else:
print("Could not read the frame.")
The following works for me:
ffmpeg
.input(url)
.filter('fps', fps='1/60')
.output('thumbs/test-%d.jpg',
start_number=0)
.overwrite_output()
.run(quiet=True)
@norus solution is actually good, but for me it was missing the ss and r parameters in the input. I used a local file instead of a url.
This is my solution:
ffmpeg.input(<path/to/file>, ss = 0, r = 1)
.filter('fps', fps='1/60')
.output('thumbs/test-%d.jpg', start_number=0)
.overwrite_output()]
.run(quiet=True)
ss is the starting second in the above code starts on 0
r is the ration, because the filter fps is set to 1/60 an r of 1 will return 1 frame per second, of 2 1 frame every 2 seconds, 0.5 a frame every half second….
As far as I understand ffmpeg-python
is main package in Python to operate ffmpeg
directly.
Now I want to take a video and save it’s frames as separate files at some fps.
There are plenty of command line ways to do it, e.g. ffmpeg -i video.mp4 -vf fps=1 img/output%06d.png
described here
But I want to do it in Python. Also there are solutions [1] [2] that use Python’s subprocess
to call ffmpeg
CLI, but it looks dirty for me.
Is there any way to to make it using ffmpeg-python
?
I’d suggest you try imageio module and use the following code as a starting point:
import imageio
reader = imageio.get_reader('imageio:cockatoo.mp4')
for frame_number, im in enumerate(reader):
# im is numpy array
if frame_number % 10 == 0:
imageio.imwrite(f'frame_{frame_number}.jpg', im)
You can also use openCV for that.
Reference code:
import cv2
video_capture = cv2.VideoCapture("your_video_path")
video_capture.set(cv2.CAP_PROP_FPS, <your_desired_fps_here>)
saved_frame_name = 0
while video_capture.isOpened():
frame_is_read, frame = video_capture.read()
if frame_is_read:
cv2.imwrite(f"frame{str(saved_frame_name)}.jpg", frame)
saved_frame_name += 1
else:
print("Could not read the frame.")
The following works for me:
ffmpeg
.input(url)
.filter('fps', fps='1/60')
.output('thumbs/test-%d.jpg',
start_number=0)
.overwrite_output()
.run(quiet=True)
@norus solution is actually good, but for me it was missing the ss and r parameters in the input. I used a local file instead of a url.
This is my solution:
ffmpeg.input(<path/to/file>, ss = 0, r = 1)
.filter('fps', fps='1/60')
.output('thumbs/test-%d.jpg', start_number=0)
.overwrite_output()]
.run(quiet=True)
ss is the starting second in the above code starts on 0
r is the ration, because the filter fps is set to 1/60 an r of 1 will return 1 frame per second, of 2 1 frame every 2 seconds, 0.5 a frame every half second….