#!/usr/bin/env python """ export-video Little scrip to export video file for The Internet :D """ import sys import getopt import os import subprocess import logging logging.basicConfig(format='%(levelname)s:%(message)s', level=logging.DEBUG) def usage(): """ Print usage""" print("export-video -i input -o output [-d --desinterlace]") params = { "desinterlace": False, "file_output": "", "file_input": "", "vbitrate": "600k", "abitrate": "96k", "h264_vcommand": [ "-trellis", "0", "-me_method", "umh", "-subq", "8", "-me_range", "16", "-bf", "3", "-rc_lookahead", "16", "-g", "250" ], "h264_acommand": ["-strict", "experimental"], "webm_vcommand": [ "-rc_lookahead", "16", "-keyint_min", "0" "-g", "250", "-skip_threshold", "0", "-level", "116" ], "webm_acommand": ["-strict", "experimental"], "verbose": True, "pattern": "*", "twopass": False, "recursive": False, "format": [], "delay": "" } VERSION = "0.1dev" def execute(command, shell=False): """ Execute a system command and return its results. Thanxx Strycote from Lutris.net """ try: stdout, stderr = subprocess.Popen(command, shell=shell, stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate() except OSError as ex: logging.error('Could not run command %s: %s', command, ex) return return stdout.strip() def find_executable(exec_name): """ find executable with which command exec_name (string) : executable to find """ if not exec_name: raise ValueError("find_executable: exec_name required") return execute(['which', exec_name]) def list_file(directory, pattern, recursive): """ list files from a directory directory (string) : source directory pattern (string) : regex used to found files recursive (boolean) : should i serach on sub-folder? """ logging.info( 'searching in directory %s with pattern %s recursive : %s', directory, pattern, recursive ) files_list = [] try: dirs = os.listdir(directory) except OSError: logging.error('error : %s not a directory?', directory) return for i in dirs: logging.debug(' working on file / dir %s', i) if os.path.isdir(os.path.join(directory, i)) and recursive: logging.info('directory found : %s', i) files_list.extend(list_file( os.path.join(directory, i), pattern, recursive )) else: if i.endswith("." + pattern): logging.info('file found : %s', i) files_list.append(directory + "/" + i) return files_list def get_file_name(path): """ find basename without extension path (string) : complete path + file """ return os.path.splitext(os.path.basename(path))[0] def process_arg(sysarg): """ Process arguments sysarg (list) : list of arguments """ try: opts, args = getopt.getopt( sysarg, "hi:o:dp:a:v:2f:t:", [ "help", "input=", "output=", "desinterlace", "pattern=", "abitrate=", "vbitrate=", "twopass", "format=", "delay=" ] ) except getopt.GetoptError: usage() sys.exit(2) for opt, arg in opts: if opt in ("-h", "--help"): usage() sys.exit() if opt in ("-o", "--output"): params["file_output"] = arg if opt in ("-d", "--desinterlace"): logging.info("Desinterlace activated") params["h264_vcommand"] += ["-vf", "yadif"] params["webm_vcommand"] += ["-vf", "yadif"] if opt in ("-i", "--input"): params["file_input"] = arg if opt in ("-p", "--pattern"): params["pattern"] = arg if opt in ("-a", "--abitrate"): params["abitrate"] = arg if opt in ("-v", "--vbitrate"): params["vbitrate"] = arg if opt in ("-2", "--twopass"): params["twopass"] = True if opt in ("-r", "--recursive"): params["recursive"] = True if opt in ("-f", "--format"): params["format"] = arg if opt in ("-t", "--delay"): params["delay"] = arg def encode_h264(src, dest): """ Encode file src (string) : source video file dest (string) : destination file """ if params["twopass"]: logging.debug("two pass encoding started ...") firstpass = [ EXEC_FFMPEG, "-y", "-i", src, "-codec:va", "libx264", "-b:v", params["vbitrate"], "-pass", "1", ] + params["h264_vcommand"] + [ "-f", "rawvideo", "/dev/null" ] secondpass = [ EXEC_FFMPEG, "-i", src, "-pass", "2", "-codec:v", "libx264", "-b:v ", params["vbitrate"] ] + params["h264_vcommand"] + [ "-b:a", params["abitrate"] ] + params["h264_acommand"] + [ dest+".mp4" ] logging.debug("First Pass command %s", firstpass) execute(firstpass) logging.debug("Second pass command %s", secondpass) execute(secondpass) else: logging.debug("one pass encoding started ...") encode = [ EXEC_FFMPEG, "-i", src, "-codec:v", "libx264", "-b:v ", params["vbitrate"] ] + params["h264_vcommand"] + [ "-b:a", params["abitrate"] ] + params["h264_acommand"] + [ dest+".mp4", ] logging.debug(encode) execute(encode) def extract_jpg(src, dest, delay): """ Extract an image from a video file """ logging.info( "extract_jpeg() started to %s from %s with %s s delay", src, dest, delay ) encode = [ EXEC_FFMPEG, "-ss", delay, "-i", src, "-f", "image2", "-vframes", "1", dest+".jpg" ] logging.debug(encode) execute(encode) if __name__ == "__main__": EXEC_FFMPEG = find_executable("ffmpeg") if not EXEC_FFMPEG: print('ffmpeg not found, exiting') sys.exit(2) process_arg(sys.argv[1:]) if not params["format"]: params["format"] = ["mp4", "jpg"] if not params["file_input"]: print("you must specify a file / directory input") sys.exit(2) if os.path.isdir(params["file_input"]): if os.path.isfile(params["file_output"]): print("Can't batch export to a single file! Bye Bye") sys.exit(2) logging.info('%s is a directory', params["file_input"]) video_files = list_file( params["file_input"], params["pattern"], params["recursive"] ) for f in video_files: logging.info('batch encode | file %s', f) if "mp4" in params["format"]: encode_h264(f, os.path.join( params["file_output"], get_file_name(f) )) if "jpg" in params["format"]: extract_jpg( f, os.path.join( params["file_output"], get_file_name(f) ), params["delay"] ) else: if os.path.isfile(params["file_input"]): if not params["file_output"]: params["file_output"] = get_file_name(params["file_input"]) else: if os.path.isdir(params["file_output"]): params["file_input"] = os.path.join( params["file_input"], get_file_name(params["file_input"]) ) logging.info('%s is a file', params["file_input"]) if "mp4" in params["format"]: encode_h264(params["file_input"], params["file_output"]) if "jpg" in params["format"]: extract_jpg( params["file_input"], params["file_output"], params["delay"] ) else: logging.info("input file desn't exist, bye bye") sys.exit(2) sys.exit(0)