Last active
May 10, 2018 14:28
-
-
Save phuocphn/ba154163a7e6b9069a3221b3d4036abb to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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