Version 1.1

Switched to encoding with ffmpeg 0.10
Script now runs on python 2 and python 3
This commit is contained in:
seiichiro 2012-02-22 20:58:38 +01:00 committed by Stefan Brand
parent 34f323ee8c
commit fb4e284b9b
2 changed files with 53 additions and 39 deletions

3
README
View file

@ -6,8 +6,7 @@ PREQUISITES:
The following components are needed: The following components are needed:
* mplayer * mplayer
* mencoder * ffmpeg (tested with version 0.10, older versions may or may not work)
* MP4Box (from gpac package)
* python * python
USAGE: USAGE:

View file

@ -4,7 +4,9 @@
# n900-encode.py: Encode almost any Video to an Nokia N900-compatible format (h264,aac,mp4) # n900-encode.py: Encode almost any Video to an Nokia N900-compatible format (h264,aac,mp4)
# Disclaimer: This program is provided without any warranty, USE AT YOUR OWN RISK! # Disclaimer: This program is provided without any warranty, USE AT YOUR OWN RISK!
# #
# (C) 2010-2011 Stefan Brand <seiichiro@seiichiro0185.org> # Version 1.1 (22.02.2012)
#
# (C) 2010-2012 Stefan Brand <seiichiro@seiichiro0185.org>
# #
# This programm is licensed under the Terms of the GPL Version 3 # This programm is licensed under the Terms of the GPL Version 3
# See COPYING for more info. # See COPYING for more info.
@ -32,14 +34,22 @@ _ffbin = None # ffmpeg binary, if set to None it is searched in your $PATH
# Main Program, no changes needed below this line # Main Program, no changes needed below this line
########################################################################################### ###########################################################################################
# Global Variables
mda = None
mdv = None
afifo = None
vfifo = None
# Main Function
def main(argv): def main(argv):
"""Main Function, cli argument processing and checking""" """Main Function, cli argument processing and checking"""
# CLI Argument Processing # CLI Argument Processing
try: try:
opts, args = getopt.getopt(argv, "i:o:m:v:a:t:hf", ["input=", "output=", "mpopts=", "abitrate=", "vbitrate=", "threads=", "help", "force-overwrite"]) opts, args = getopt.getopt(argv, "i:o:m:v:a:t:hf", ["input=", "output=", "mpopts=", "abitrate=", "vbitrate=", "threads=", "help", "force-overwrite"])
except getopt.GetoptError, err: except getopt.GetoptError as err:
print str(err) printi(str(err))
usage() usage()
input = None input = None
@ -75,7 +85,7 @@ def main(argv):
else: else:
mpbin = progpath("mplayer") mpbin = progpath("mplayer")
if mpbin == None: if mpbin == None:
print "Error: mplayer not found in PATH and no binary given, Aborting!" print("Error: mplayer not found in PATH and no binary given, Aborting!")
sys.exit(1) sys.exit(1)
global ffbin global ffbin
@ -85,19 +95,19 @@ def main(argv):
else: else:
ffbin = progpath("ffmpeg") ffbin = progpath("ffmpeg")
if ffbin == None: if ffbin == None:
print "Error: ffmpeg not found in PATH and no binary given, Aborting!" print( "Error: ffmpeg not found in PATH and no binary given, Aborting!")
sys.exit(1) sys.exit(1)
# Check input and output files # Check input and output files
if not os.path.isfile(input): if not os.path.isfile(input):
print "Error: input file is not a valid File or doesn't exist" print("Error: input file is not a valid File or doesn't exist")
sys.exit(2) sys.exit(2)
if os.path.isfile(output): if os.path.isfile(output):
if overwrite: if overwrite:
os.remove(output) os.remove(output)
else: else:
print "Error: output file " + output + " already exists, force overwrite with -f" print("Error: output file " + output + " already exists, force overwrite with -f")
sys.exit(1) sys.exit(1)
# Start Processing # Start Processing
@ -115,16 +125,16 @@ def calculate(input):
try: try:
s = re.compile("^ID_VIDEO_ASPECT=(.*)$", re.M) s = re.compile("^ID_VIDEO_ASPECT=(.*)$", re.M)
m = s.search(mp[0]) m = s.search(bytes.decode(mp[0]))
orig_aspect = m.group(1) orig_aspect = m.group(1)
s = re.compile("^ID_VIDEO_WIDTH=(.*)$", re.M) s = re.compile("^ID_VIDEO_WIDTH=(.*)$", re.M)
m = s.search(mp[0]) m = s.search(bytes.decode(mp[0]))
orig_width = m.group(1) orig_width = m.group(1)
s = re.compile("^ID_VIDEO_HEIGHT=(.*)$", re.M) s = re.compile("^ID_VIDEO_HEIGHT=(.*)$", re.M)
m = s.search(mp[0]) m = s.search(bytes.decode(mp[0]))
orig_height = m.group(1) orig_height = m.group(1)
except: except:
print "Error: unable to identify source video, exiting!" print("Error: unable to identify source video, exiting!")
sys.exit(2) sys.exit(2)
# Calculate output resolution # Calculate output resolution
@ -187,13 +197,16 @@ def convert(input, output, res, abitrate, vbitrate, threads, mpopts):
"-f", "yuv4mpegpipe", "-f", "yuv4mpegpipe",
"-i", vfifo, "-i", vfifo,
"-i", afifo, "-i", afifo,
"-acodec", "libfaac", "-acodec", "aac",
"-strict", "experimental",
"-ac", "2", "-ac", "2",
"-ab", str(abitrate), "-ab", str(abitrate),
"-ar", "22500", "-ar", "44100",
"-vcodec", "libx264", "-vcodec", "libx264",
"-threads", str(threads), "-threads", str(threads),
"-b", str(vbitrate), "-vprofile", "baseline",
"-tune", "animation",
"-b:v", str(vbitrate),
"-flags", "+loop", "-cmp", "+chroma", "-flags", "+loop", "-cmp", "+chroma",
"-partitions", "+parti4x4+partp8x8+partb8x8", "-partitions", "+parti4x4+partp8x8+partb8x8",
"-subq", "5", "-trellis", "1", "-refs", "1", "-subq", "5", "-trellis", "1", "-refs", "1",
@ -203,7 +216,7 @@ def convert(input, output, res, abitrate, vbitrate, threads, mpopts):
"-bt", "640", "-bufsize", "10M", "-maxrate", "1000000", "-bt", "640", "-bufsize", "10M", "-maxrate", "1000000",
"-rc_eq", "'blurCplx^(1-qComp)'", "-rc_eq", "'blurCplx^(1-qComp)'",
"-qcomp", "0.62", "-qmin", "10", "-qmax", "51", "-qcomp", "0.62", "-qmin", "10", "-qmax", "51",
"-level", "30", "-f", "mp4", "-x264opts", "level=3.0", "-f", "mp4",
output ] output ]
# Start mplayer decoding processes in background # Start mplayer decoding processes in background
@ -211,14 +224,14 @@ def convert(input, output, res, abitrate, vbitrate, threads, mpopts):
mdv = subprocess.Popen(mpvideodec, stdout=None, stderr=None) mdv = subprocess.Popen(mpvideodec, stdout=None, stderr=None)
mda = subprocess.Popen(mpaudiodec, stdout=None, stderr=None) mda = subprocess.Popen(mpaudiodec, stdout=None, stderr=None)
except: except:
print "Error: Starting decoding threads failed!" print("Error: Starting decoding threads failed!")
sys.exit(3) sys.exit(3)
# Start ffmpeg encoding process in foreground # Start ffmpeg encoding process in foreground
try: try:
subprocess.check_call(ffmenc) subprocess.check_call(ffmenc)
except subprocess.CalledProcessError: except subprocess.CalledProcessError:
print "Error: Encoding thread failed!" print("Error: Encoding thread failed!")
sys .exit(4) sys .exit(4)
@ -238,31 +251,33 @@ def cleanup():
# Cleanup # Cleanup
try: try:
os.kill(mda.pid()) if (mda != None):
os.kill(mdv.pid()) os.kill(mda.pid())
if (mdv != None):
os.kill(mdv.pid())
finally: finally:
try: if (afifo != None):
os.remove(afifo) os.remove(afifo)
if (vfifo != None):
os.remove(vfifo) os.remove(vfifo)
finally: os._exit(0)
sys.exit(0)
def usage(): def usage():
"""Print avaiable commandline arguments""" """Print avaiable commandline arguments"""
print "This is n900-encode.py (C) 2010 Stefan Brand <seiichiro0185 AT tol DOT ch>" print("This is n900-encode.py (C) 2010 Stefan Brand <seiichiro0185 AT tol DOT ch>")
print "Usage:" print("Usage:")
print " n900-encode.py --input <file> [opts]\n" print(" n900-encode.py --input <file> [opts]\n")
print "Options:" print("Options:")
print " --input <file> [-i]: Video to Convert" print(" --input <file> [-i]: Video to Convert")
print " --output <file> [-o]: Name of the converted Video" print(" --output <file> [-o]: Name of the converted Video")
print " --mpopts \"<opts>\" [-m]: Additional options for mplayer (eg -sid 1 or -aid 1) Must be enclosed in \"\"" print(" --mpopts \"<opts>\" [-m]: Additional options for mplayer (eg -sid 1 or -aid 1) Must be enclosed in \"\"")
print " --abitrate <br> [-a]: Audio Bitrate in KBit/s" print(" --abitrate <br> [-a]: Audio Bitrate in KBit/s")
print " --vbitrate <br> [-v]: Video Bitrate in kBit/s" print(" --vbitrate <br> [-v]: Video Bitrate in kBit/s")
print " --threads <num> [-t]: Use <num> Threads to encode" print(" --threads <num> [-t]: Use <num> Threads to encode")
print " --force-overwrite [-f]: Overwrite output-file if existing" print(" --force-overwrite [-f]: Overwrite output-file if existing")
print " --help [-h]: Print this Help" print(" --help [-h]: Print this Help")
sys.exit(0) os._exit(0)
# Start the Main Function # Start the Main Function
@ -277,5 +292,5 @@ if __name__ == "__main__":
if len(sys.argv) > 1: if len(sys.argv) > 1:
main(sys.argv[1:]) main(sys.argv[1:])
else: else:
print "Error: You have to give an input file at least!" print("Error: You have to give an input file at least!")
usage() usage()