BitMover/_video.py

135 lines
4.6 KiB
Python

#!/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