#!/usr/bin/env python import os.path import sys import ffmpeg import time from datetime import datetime class VideoFile: def __init__(self,path_file_name,max_width=1024,*args,**kwargs): # super(VideoFile, self).__init__(*args, **kwargs) self.path_file_name = path_file_name self.max_width = max_width self.out = 'thumbnail.jpg' self.probe = ffmpeg.probe(self.path_file_name) self.video_capture_date = self.get_video_capture_date() self.video_stream = None self.audio_stream = None for i in self.probe['streams']: if self.video_stream is None: if 'video' == i['codec_type'].lower(): self.video_stream = i if self.audio_stream is None: if 'audio' == i['codec_type'].lower(): self.audio_stream = i self.format_stream = self.probe['format'] self.size_width = self.get_video_width() self.size_height = self.get_video_height() self.size = self.get_video_size() self.stream = {} @staticmethod def convert_from_seconds(seconds): return time.strftime("%H:%M:%S", time.gmtime(seconds)) def gen_video_thumbnail(self): """ Generate a thumbnail from a video """ time_seconds = self.stream['video']['seconds'] // 5 v_width = int(self.stream['video']['size']['width']) width = self.set_thumb_width(v_width) try: ( ffmpeg.input( self.path_file_name, ss = time_seconds ) .filter( 'scale', width, -1 ) .output( self.out, vframes = 1 ) .overwrite_output() .run( capture_stdout = True, capture_stderr = True ) ) except ffmpeg.Error as e: print(e.stderr.decode(), file = sys.stderr) return self.out def set_thumb_width(self, v_width): if v_width > self.max_width: width = self.max_width else: width = v_width return width def get_video_width(self): return self.video_stream['width'] def get_video_height(self): return self.video_stream['height'] def get_video_size(self): if self.size_width is None: self.size_width = self.get_video_width() if self.size_height is None: self.size_height = self.get_video_height() return f'{self.size_width}x{self.size_height}' def get_video_capture_date(self): #TODO: refactor this try/except logic. try: stamp = datetime.strptime( self.format_stream['tags']['creation_time'], '%Y-%m-%dT%H:%M:%S.%f%z' ) except: try: stamp = datetime.fromtimestamp( os.path.getctime( self.path_file_name ) ) except: stamp = datetime.strptime( str('1900:01:01 00:00:00'), '%Y:%m:%d %H:%M:%S' ) return stamp def video_meta(self): self.stream = { 'video': { 'bits_per_raw_sample': self.video_stream['bits_per_raw_sample'], 'codec_long_name': self.video_stream['codec_long_name'], 'duration': self.convert_from_seconds(float(self.video_stream['duration'])), 'encoding_brand': self.format_stream['tags']['major_brand'], 'pix_fmt': self.video_stream['pix_fmt'], 'profile': self.video_stream['profile'], 'r_frame_rate': self.video_stream['r_frame_rate'], 'size': { 'width_height': self.size, 'height': self.video_stream['height'], 'width': self.video_stream['width'] } }, 'audio': {}, 'format': {} } return self.stream