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

307 lines
8.6 KiB
Python
Executable file

#!/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": "10"
}
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:v", "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)