70 lines
1.9 KiB
Python
70 lines
1.9 KiB
Python
import platform
|
|
import re
|
|
import subprocess
|
|
import tempfile
|
|
import os
|
|
|
|
from hachoir.metadata import extractMetadata
|
|
from hachoir.parser import createParser
|
|
from hachoir.core import config as hachoir_config
|
|
|
|
from telegram_upload.exceptions import ThumbVideoError
|
|
|
|
|
|
hachoir_config.quiet = True
|
|
|
|
|
|
def video_metadata(file):
|
|
return extractMetadata(createParser(file))
|
|
|
|
|
|
def call_ffmpeg(args):
|
|
try:
|
|
return subprocess.Popen([get_ffmpeg_command()] + args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
|
except FileNotFoundError:
|
|
raise ThumbVideoError('ffmpeg command is not available. Thumbnails for videos are not available!')
|
|
|
|
|
|
def get_ffmpeg_command():
|
|
return os.environ.get('FFMPEG_COMMAND',
|
|
'ffmpeg.exe' if platform.system() == 'Windows' else 'ffmpeg')
|
|
|
|
|
|
def get_video_size(file):
|
|
p = call_ffmpeg([
|
|
'-i', file,
|
|
])
|
|
stdout, stderr = p.communicate()
|
|
video_lines = re.findall(': Video: ([^\n]+)', stderr.decode('utf-8', errors='ignore'))
|
|
if not video_lines:
|
|
return
|
|
matchs = re.findall("(\d{2,6})x(\d{2,6})", video_lines[0])
|
|
if matchs:
|
|
return [int(x) for x in matchs[0]]
|
|
|
|
|
|
def get_video_thumb(file, output=None, size=200):
|
|
output = output or tempfile.NamedTemporaryFile(suffix='.jpg').name
|
|
metadata = video_metadata(file)
|
|
if metadata is None:
|
|
return
|
|
duration = metadata.get('duration').seconds if metadata.has('duration') else 0
|
|
ratio = get_video_size(file)
|
|
if ratio is None:
|
|
raise ThumbVideoError('Video ratio is not available.')
|
|
if ratio[0] / ratio[1] > 1:
|
|
width, height = size, -1
|
|
else:
|
|
width, height = -1, size
|
|
p = call_ffmpeg([
|
|
'-ss', str(int(duration / 2)),
|
|
'-i', file,
|
|
'-filter:v',
|
|
'scale={}:{}'.format(width, height),
|
|
'-vframes:v', '1',
|
|
output,
|
|
])
|
|
p.communicate()
|
|
if not p.returncode and os.path.lexists(file):
|
|
return output
|