128 lines
4.8 KiB
Python
128 lines
4.8 KiB
Python
#!/usr/bin/env python
|
|
|
|
import sys
|
|
import ffmpeg
|
|
import time
|
|
|
|
class Video:
|
|
def __init__(self,max_width=1024,*args,**kwargs):
|
|
super(Video,self).__init__()
|
|
self.args = args
|
|
self.kwargs = kwargs
|
|
self.file = kwargs['file']
|
|
self.out = 'thumbnail.jpg'
|
|
self.max_width = max_width
|
|
|
|
self.stream = {
|
|
'video': {},
|
|
'format': {},
|
|
'audio': {}
|
|
}
|
|
|
|
self.stream['video']['duration'] = ''
|
|
self.stream['video']['creation_time'] = ''
|
|
self.stream['video']['encoding_brand'] = ''
|
|
self.stream['video']['codec_name'] = ''
|
|
self.stream['video']['codec_long_name'] = ''
|
|
self.stream['video']['profile'] = ''
|
|
self.stream['video']['size'] = {}
|
|
self.stream['video']['size']['width'] = int()
|
|
self.stream['video']['size']['height'] = int()
|
|
self.stream['video']['display_aspect_ratio'] = str()
|
|
self.stream['video']['level'] = ''
|
|
self.stream['video']['color_range'] = ''
|
|
self.stream['video']['field_order'] = ''
|
|
self.stream['video']['is_avc'] = ''
|
|
self.stream['video']['r_frame_rate'] = '' # -> expect for 120fps: 120000/1001
|
|
self.stream['video']['avg_frame_rate'] = '' # -> expect for 120fps: 120000/1001
|
|
self.stream['video']['time_base'] = '' # -> expect for 120fps: 1/120000
|
|
self.stream['video']['bit_rate'] = ''
|
|
self.stream['video']['bits_per_raw_sample'] = ''
|
|
self.stream['video']['nb_frames'] = ''
|
|
self.stream['video']['language'] = ''
|
|
self.stream['video']['handler_name'] = ''
|
|
self.stream['video']['encoder'] = ''
|
|
self.stream['video']['pix_fmt'] = ''
|
|
|
|
self.stream['format'] = {}
|
|
self.stream['format']['major_brand'] = ''
|
|
self.stream['format']['compatible_brands'] = ''
|
|
self.stream['format']['creation_time'] = ''
|
|
|
|
self.stream['audio'] = {}
|
|
self.stream['audio']['codec_long_name'] = ''
|
|
self.stream['audio']['channels'] = ''
|
|
self.stream['audio']['sample_fmt'] = ''
|
|
self.stream['audio']['sample_rate'] = ''
|
|
self.stream['audio']['bits_per_sample'] = ''
|
|
self.stream['audio']['bit_rate'] = ''
|
|
|
|
@staticmethod
|
|
def convert_from_seconds(s):
|
|
seconds = s
|
|
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 = 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)
|
|
.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_meta(self):
|
|
probe = ffmpeg.probe(self.file)
|
|
|
|
if 'video' == probe['streams'][0]['codec_type'].lower():
|
|
video_stream = probe['streams'][0]
|
|
elif 'video' == probe['streams'][1]['codec_type'].lower():
|
|
video_stream = probe['streams'][1]
|
|
elif 'video' == probe['streams'][2]['codec_type'].lower():
|
|
video_stream = probe['streams'][2]
|
|
|
|
if 'audio' == probe['streams'][0]['codec_type'].lower():
|
|
audio_stream = probe['streams'][0]
|
|
elif 'audio' == probe['streams'][1]['codec_type'].lower():
|
|
audio_stream = probe['streams'][1]
|
|
elif 'audio' == probe['streams'][2]['codec_type'].lower():
|
|
audio_stream = probe['streams'][2]
|
|
|
|
format_stream = probe['format']
|
|
|
|
self.stream['video']['size']['width'] = video_stream['width']
|
|
self.stream['video']['size']['height'] = video_stream['height']
|
|
self.stream['video']['r_frame_rate'] = video_stream['r_frame_rate']
|
|
self.stream['video']['bits_per_raw_sample'] = video_stream['bits_per_raw_sample']
|
|
self.stream['video']['seconds'] = float(video_stream['duration'])
|
|
self.stream['video']['duration'] = self.convert_from_seconds(
|
|
self.stream['video']['seconds']
|
|
)
|
|
self.stream['video']['encoding_brand'] = format_stream['tags']['major_brand']
|
|
self.stream['video']['codec_long_name'] = video_stream['codec_long_name']
|
|
self.stream['video']['profile'] = video_stream['profile']
|
|
self.stream['video']['pix_fmt'] = video_stream['pix_fmt']
|
|
|
|
return self.stream
|