Skip to content

Instantly share code, notes, and snippets.

@diegorocha
Last active February 23, 2022 07:23
Show Gist options
  • Save diegorocha/751eded53f5e71917ab1a2941ef46988 to your computer and use it in GitHub Desktop.
Save diegorocha/751eded53f5e71917ab1a2941ef46988 to your computer and use it in GitHub Desktop.
Class to help to extract a frame from a video with ffmpeg
# coding=utf-8
from sys import argv
from math import ceil
from re import compile
from subprocess import Popen, PIPE
class FfmpegHelper(object):
def __init__(self, file_path):
self.file_path = file_path
self.ffmpeg = 'ffmpeg'
self.ffprobe = 'ffprobe'
@staticmethod
def time_to_seconds(duration):
seconds = 0
parts = map(lambda x: int(ceil(float(x))), duration.split(':'))
for i, part in enumerate(reversed(parts)):
seconds += 60**i * part
return seconds
@staticmethod
def seconds_to_time(seconds):
hours = seconds / 3600
seconds -= hours * 3600
minutes = seconds / 60
seconds -= minutes * 60
return '%02d:%02d:%02d' % (hours, minutes, seconds)
def get_default_frame_time(self):
return self.get_video_duration() / 2
def get_video_duration(self):
args = [self.ffprobe, self.file_path]
duration_regex = compile(r'Duration: ([0-9:.]*)')
p = Popen(args, stdout=PIPE, stderr=PIPE)
stdout, stderr = p.communicate()
output = stdout + stderr
match = duration_regex.findall(output)
if match:
return self.time_to_seconds(match[0])
def extract_frame(self, output, seconds=None):
if not seconds:
seconds = self.get_default_frame_time()
args = [self.ffmpeg, '-y', '-ss', seconds, '-i', self.file_path, '-vframes', '1', output]
p = Popen(args, stdout=PIPE, stderr=PIPE)
p.communicate()
return p.returncode == 0
if __name__ == '__main__':
arguments = argv[1:3]
if len(arguments) != 2:
raise ValueError('Please inform video and output args')
video_path, frame_path = arguments
ffmpeg = FfmpegHelper(video_path)
ffmpeg.extract_frame(frame_path)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment