#!/usr/bin/env python import os.path import sys import ffmpeg import time from datetime import datetime from _media_file import MediaFile class VideoFile(MediaFile): def __init__(self,max_width=1024,*args,**kwargs): super(VideoFile, self).__init__(*args, **kwargs) self.args = args self.kwargs = kwargs self.file = kwargs['file'] self.out = 'thumbnail.jpg' self.max_width = max_width self.probe = ffmpeg.probe(self.path_file_name) self.video_capture_date = self.get_video_capture_date() if 'video' == self.probe['streams'][0]['codec_type'].lower(): self.video_stream = self.probe['streams'][0] elif 'video' == self.probe['streams'][1]['codec_type'].lower(): self.video_stream = self.probe['streams'][1] elif 'video' == self.probe['streams'][2]['codec_type'].lower(): self.video_stream = self.probe['streams'][2] if 'audio' == self.probe['streams'][0]['codec_type'].lower(): self.audio_stream = self.probe['streams'][0] elif 'audio' == self.probe['streams'][1]['codec_type'].lower(): self.audio_stream = self.probe['streams'][1] elif 'audio' == self.probe['streams'][2]['codec_type'].lower(): self.audio_stream = self.probe['streams'][2] 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 """ self.get_video_meta() 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.file, 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 get_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