This repository has been archived on 2024-09-06. You can view files and clone it, but you cannot make any changes to it's state, such as pushing and creating new issues, pull requests or comments.
SimpleVideoExporter/export-video.py
2015-12-09 00:02:47 +01:00

218 lines
6.3 KiB
Python
Executable file

#!/usr/bin/env python
# export-video.py
# ---------------
# little python script to encode vide file for the web
#
import sys
import getopt
import re
import os
import subprocess
import logging
logging.basicConfig(format='%(levelname)s:%(message)s', level=logging.DEBUG)
def 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}
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):
if not exec_name:
raise ValueError("find_executable: exec_name required")
return execute(['which', exec_name])
def listFile(directory, pattern, recursive):
logging.info('searching in directory %s', directory)
files_list = []
try:
dirs = os.listdir(directory)
except:
logging.error('error : %s not a directory?', directory)
return
for i in dirs:
if os.path.isdir(directory + "/" + i) and recursive:
logging.info('directory found : %s', i)
files_list.extend(listFile(directory + "/" + i, pattern))
else:
if re.search(pattern, i) is not None:
logging.info('file found : %s', i)
files_list.append(directory + "/" + i)
return files_list
def getFileName(path):
return os.path.splitext(os.path.basename(path))[0]
def processArg(sysarg):
try:
opts, args = getopt.getopt(
sysarg, "hi:o:dp:a:v:2",
[
"help",
"input=",
"output=",
"desinterlace",
"pattern=",
"abitrate=",
"vbitrate=",
"twopass"
]
)
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"] = "^\\w*."+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
def encode_h264(src, dest):
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"
]
subprocess.run(firstpass)
subprocess.run(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",
"-loglevel", "quiet"
]
logging.debug(encode)
subprocess.run(encode)
if __name__ == "__main__":
exec_ffmpeg = find_executable("ffmpeg")
if not exec_ffmpeg:
print('ffmpeg not found, exiting')
sys.exit(2)
processArg(sys.argv[1:])
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 = listFile(
params["file_input"],
params["pattern"],
params["recursive"]
)
for f in video_files:
logging.info('batch encode | file %s to %s', f)
encode_h264(f, params["file_output"] + getFileName(f))
else:
if os.path.isfile(params["file_input"]):
if not params["file_output"]:
params["file_output"] = getFileName(params["file_input"])
else:
if(os.path.isdir(params["file_output"])):
params["file_input"] += getFileName(params["file_input"])
logging.info('%s is a file', params["file_input"])
encode_h264(params["file_input"], params["file_output"])
else:
logging.info("input file desn't exist, bye bye")
sys.exit(2)
sys.exit(0)