use python-ffmpeg (run external ffmpeg) to generate video thumb as it also auto-rotates

This commit is contained in:
2022-07-21 20:59:05 +10:00
parent 0ea6a38269
commit 9164b2c9f6
2 changed files with 21 additions and 34 deletions

View File

@@ -45,6 +45,7 @@ import face_recognition
import re
import sys
import json
import ffmpeg
# global debug setting
@@ -1694,41 +1695,27 @@ def GenImageThumbnail(job, file):
# GenVideoThumbnail(): log and then generate the thumb for a video (this grabs the width/height of a frame from the video,
# and then reads the first few frames until the mean() fo the frame indicates its not just black frame, then make the thumbnail
####################################################################################################################################
def GenVideoThumbnail(job, file):
ProcessFileForJob( job, "Generate Thumbnail from Video file: {}".format( file ), file )
def GenVideoThumbnail( job, fname):
ProcessFileForJob( job, f"Generate Thumbnail from Video file: {fname}", fname )
height = THUMBSIZE
try:
vcap = cv2.VideoCapture(file)
res, frame = vcap.read()
first_res = res
first_frame = frame
frame_cnt=0
# if the mean pixel value is > 15, we have something worth making a sshot of (no black frame at start being the sshot)
# limit it to 1000 frames jic
while res and frame.mean() < 15 and frame_cnt < 1000:
res, frame = vcap.read()
frame_cnt += 1
# if we never got a frame that is not dark, then use first frame
if not res:
res = first_res
frame = first_frame
w = vcap.get(cv2.CAP_PROP_FRAME_WIDTH)
h = vcap.get(cv2.CAP_PROP_FRAME_HEIGHT)
if w > h:
factor = w / THUMBSIZE
else:
factor = h / THUMBSIZE
new_h = int(h / factor)
new_w = int(w / factor)
frame = cv2.resize(frame, (new_w, new_h), 0, 0, cv2.INTER_LINEAR)
res, thumb_buf = cv2.imencode('.jpeg', frame)
bt = thumb_buf.tobytes()
thumbnail = base64.b64encode(bt)
thumbnail = str(thumbnail)[2:-1]
except Exception as e:
AddLogForJob( job, f"ERROR: Failed to Generate thumbnail for video file: {file} - error={e}" )
probe = ffmpeg.probe(fname)
time = float(probe['streams'][0]['duration']) // 2
tmp_fname='/tmp/pa_tmp_'+os.path.basename(fname.split('.')[0])+'.jpg'
(
ffmpeg
.input(fname, ss=time)
.filter('scale', -1, height)
.output(tmp_fname, vframes=1)
.overwrite_output()
.run(capture_stdout=True, capture_stderr=True)
)
except ffmpeg.Error as e:
AddLogForJob( job, f"ERROR: Failed to Generate thumbnail for video file: {fname} - error={e}" )
return None
thumbnail, w, h = GenThumb( tmp_fname, False )
os.remove( tmp_fname )
return thumbnail
####################################################################################################################################