Skip to content

Instantly share code, notes, and snippets.

@phuocphn
Last active May 10, 2018 14:28
Show Gist options
  • Save phuocphn/ba154163a7e6b9069a3221b3d4036abb to your computer and use it in GitHub Desktop.
Save phuocphn/ba154163a7e6b9069a3221b3d4036abb to your computer and use it in GitHub Desktop.
import os
import sys
import subprocess
import timeout_decorator
import random
import logging
if sys.version_info[0] < 3:
import pipes as shlex
else:
import shlex
# If output is still image, the middle frame of the video will be chosen to be thumbnail image.
# If output is animated image, it is a collection of still images between 1 minute of the video.
def create_thumbnail(video_path, output_name, output_extension = '.jpeg', output_size = '320x240'):
video_path = shlex.quote(video_path)
output_name = shlex.quote(output_name)
output_extension = shlex.quote(output_extension)
output_size = shlex.quote(output_size)
logging.basicConfig(
format="%(asctime)s [%(threadName)-12.12s] [%(levelname)-5.5s] %(message)s",
level=logging.DEBUG,
handlers=[
logging.FileHandler("/var/tmp/{0}.log".format("__name__")),
logging.StreamHandler()
])
logger = logging.getLogger("__name__")
@timeout_decorator.timeout(60 * 10 , timeout_exception=OSError, use_signals=False)
def run_command(command):
p = subprocess.Popen(command, stdout = subprocess.PIPE, stderr = subprocess.STDOUT, shell = True)
(output, err) = p.communicate()
p_status = p.wait()
return (output.strip(), err)
# check video_path exists
if not os.path.exists(video_path):
logger.error ("Video path {} doesn't exists. Stop".format(video_path))
return None
if output_extension not in [".jpeg", ".jpg", ".png", ".gif"]:
logger.error ("Unsupported output file extension")
return None
if os.path.exists(output_name + output_extension):
os.remove(output_name + output_extension)
logger.info("Starting create thumbnail image")
try:
(total_time, err) = run_command("ffmpeg -i {0} 2>&1 | grep Duration | awk '{{print $2}}' | tr -d ,".format(video_path))
if err != None:
logger.error ("Can not execute ffmpeg command. Stop")
return None
(middle_offset, err) = run_command("echo '{0}' | awk -F ':' '{{print ($3+$2*60+$1*3600)/2}}'".format(total_time))
if err != None:
logger.error ("Can not execute ffmpeg command. Stop")
return None
if sys.version_info[0] == 3:
middle_offset = middle_offset.decode(encoding="utf-8")
if output_extension != '.gif':
command = "ffmpeg -ss {0} -i {1} -qscale:v 4 -frames:v 1 -huffman optimal -s {2} -y {3}{4}".format(middle_offset, video_path, output_size, output_name, output_extension)
logger.info(command)
(result, err) = run_command(command)
logger.info("Create still thumbnail done.")
return output_name + output_extension
else:
# generate by I - frame
# ffmpeg -i video_test.mp4 -vf "select='eq(pict_type,PICT_TYPE_I)'" -vsync vfr xxx.gif
middle_offset = int(float(middle_offset)) * 2
fps_time = int(middle_offset / 10)
random_name = random.randint(0, 2048)
command = "ffmpeg -i {0} -vf fps=1/{1} -s {2} thumb{3}%3d.jpg && convert -delay 100 -loop 0 thumb{3}*.jpg {4}.gif".format(video_path, fps_time, output_size, random_name, output_name )
logger.info(command)
(result, err) = run_command(command)
if err != None:
logger.error ("Can not execute ffmpeg command. Stop")
return None
run_command("rm -rf thumb{}*.jpg".format(random_name))
logger.info("Create animated thumbnail done.")
return "{}.gif".format(output_name)
except OSError as e:
logger.error ("[Error] FFmpeg command's execution exceed timeout. Stop")
return None
except Exception as e:
logger.exception ("[Error] Some problems happen during execution ffmpeg command")
return None
if __name__ == '__main__':
thumbnail = create_thumbnail(video_path = "/root/VIDEOS/20.flv", output_name = "/root/STORAGE/xf4", output_extension = ".jpeg")
print (thumbnail)
thumbnail = create_thumbnail(video_path = "/root/VIDEOS/04.20.flv", output_name = "/root/STORAGE/xf4", output_extension = ".gif")
print (thumbnail)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment