[SCM] lives packaging branch, master, updated. debian/1.1.8-1-41-g8fe173f
hrickards-guest at users.alioth.debian.org
hrickards-guest at users.alioth.debian.org
Tue Jan 12 20:18:43 UTC 2010
The following commit has been merged in the master branch:
commit 3fa65fe1dd876bc375afb1e20451664441f957bc
Author: Harry Rickards <harry at linux.com>
Date: Tue Jan 12 19:18:42 2010 +0000
Removed most of the bulk from removepy.diff and added it to debian/rules via some simple mv commands
diff --git a/debian/patches/removepy.diff b/debian/patches/removepy.diff
index 233dc89..128d8fb 100644
--- a/debian/patches/removepy.diff
+++ b/debian/patches/removepy.diff
@@ -8,24 +8,8 @@ Author: Harry Rickards <hrickards at l33tmyst.com>
---
lives-plugins/marcos-encoders/Makefile.am | 16
lives-plugins/marcos-encoders/Makefile.in | 16
- lives-plugins/marcos-encoders/avi_encoder | 825 ++++++++++++++++++++
- lives-plugins/marcos-encoders/avi_encoder.py | 825 --------------------
- lives-plugins/marcos-encoders/dirac_encoder.py | 843 --------------------
- lives-plugins/marcos-encoders/gif_encoder | 651 ++++++++++++++++
- lives-plugins/marcos-encoders/gif_encoder.py | 651 ----------------
- lives-plugins/marcos-encoders/lives_dirac_encoder | 843 ++++++++++++++++++++
- lives-plugins/marcos-encoders/mkv_encoder | 888 ++++++++++++++++++++++
- lives-plugins/marcos-encoders/mkv_encoder.py | 888 ----------------------
- lives-plugins/marcos-encoders/mng_encoder | 651 ++++++++++++++++
- lives-plugins/marcos-encoders/mng_encoder.py | 651 ----------------
- lives-plugins/marcos-encoders/mpeg_encoder | 886 +++++++++++++++++++++
- lives-plugins/marcos-encoders/mpeg_encoder.py | 886 ---------------------
- lives-plugins/marcos-encoders/ogm_encoder | 816 ++++++++++++++++++++
- lives-plugins/marcos-encoders/ogm_encoder.py | 816 --------------------
- lives-plugins/marcos-encoders/theora_encoder | 817 ++++++++++++++++++++
- lives-plugins/marcos-encoders/theora_encoder.py | 817 --------------------
lives-plugins/plugins/encoders/multi_encoder | 60 -
- 19 files changed, 6423 insertions(+), 6423 deletions(-)
+ 3 files changed, 46 insertions(+), 46 deletions(-)
--- lives.orig/lives-plugins/marcos-encoders/Makefile.am
+++ lives/lives-plugins/marcos-encoders/Makefile.am
@@ -77,12808 +61,6 @@ Author: Harry Rickards <hrickards at l33tmyst.com>
EXTRA_DIST = $(marcosencoders_DATA) README.multi_encoder
all: all-am
---- /dev/null
-+++ lives/lives-plugins/marcos-encoders/avi_encoder
-@@ -0,0 +1,825 @@
-+#!/usr/bin/env python
-+
-+
-+import locale
-+locale.setlocale(locale.LC_NUMERIC,"")
-+
-+"""
-+avi_encoder.py
-+
-+Front-end to various programs needed to create AVI
-+movies with some image-enhancing capabilities through the use of
-+ImageMagick. Meant as a companion to LiVES (to possibly call
-+from within a plugin, see http://www.xs4all.nl/~salsaman/lives/ )
-+but can also be used as a stand-alone program.
-+
-+Requires MPlayer, ImageMagick (GraphicsMagick might also
-+work), sox, lame, and Python 2.3.0 or greater. Note that
-+this program can encode a SNOW video stream (if mencoder
-+supports it), but that it is still highly experimental.
-+This is also true for h.264. Use at your own risk.
-+
-+Copyright (C) 2004-2005 Marco De la Cruz (marco at reimeika.ca)
-+It's a trivial program, but might as well GPL it, so see:
-+http://www.gnu.org/copyleft/gpl.html for license.
-+
-+See my vids at http://amv.reimeika.ca !
-+"""
-+
-+version = '0.0.10'
-+convert = 'convert'
-+mencoder = 'mencoder'
-+lameenc = 'lame'
-+sox = 'sox'
-+
-+usage = \
-+ """
-+avi_encoder.py -h
-+avi_encoder.py -V
-+avi_encoder.py -C
-+avi_encoder.py [-o out] [-p pre] [-d dir] [-a aspect] [-D delay]
-+ [-q|-v] [-t type] [-k] [-e [[-w dir] [-c geom] [-r geom]]]
-+ [-s sndfile] [-b sndrate] [-f fpscode] [-L lv1file]
-+ [firstframe lastframe]
-+ """
-+
-+help = \
-+ """
-+SUMMARY (ver. %s):
-+
-+Encodes a series of PNG or JPG images into an XviD/Snow/h.264 + MP3
-+(AVI) stream and is also capable of performing some simple image
-+enhacements using ImageMagick. The images and audio are assumed to
-+be in an uncompressed LiVES format, hence making this encoder
-+more suitable to be used within a LiVES plugin (but can also
-+be used directly on a LiVES temporary directory).
-+
-+OPTIONS:
-+
-+-h for help.
-+
-+-V shows the version number.
-+
-+-C check external program dependencies and exit.
-+
-+-o out will save the video in file "out".
-+ Default: "'type'_movie.avi". See below for 'type'.
-+
-+-p pre the encoder assumes that sound and images are named using
-+ LiVES' conventions i.e. "audio" and "00000001.ext",
-+ "00000002.ext"... where "ext" is either "jpg" or "png".
-+ However, avi_encoder.py will create temporary files
-+ which can be saved for later use (for example, after
-+ enhancing the images with "-e" , which may take a long
-+ time). These temporary files will be named
-+ "pre_00000001.ext", etc... where "pre" is either "eimg"
-+ or "rimg" and will be kept if the "-k" option is used.
-+ avi_encoder.py can then be run over the enhanced images
-+ only by selecting the appropriate prefix ("eimg" or
-+ "rimg") here. See "-e" to see what each prefix means.
-+ Default: "" (an empty string).
-+
-+-d dir "dir" is the directory containing the source image
-+ files. These must be of the form "00000001.ext" or
-+ "pre_00000001.ext" as explained above.
-+ Default: "."
-+
-+-a aspect sets the aspect ratio of the resulting MPEG-4. This can be:
-+
-+ 1 1:1 display
-+ 2 4:3 display
-+ 3 16:9 display
-+ 4 2.21:1 display
-+
-+ Default: "2"
-+
-+-D delay delay the audio stream by "delay" ms. Must be positive.
-+ Default: "0"
-+
-+-q quiet operation, only complains on error.
-+
-+-v be verbose.
-+
-+-t type type of video created. The options here are:
-+
-+ "hi": a very high quality XviD file, suitable
-+ for archiving images of 720x480.
-+
-+ "mh": medium-high quality XviD, which still allows
-+ to watch small videos (352x240 and below)
-+ fullscreen.
-+
-+ "ml": medium-low quality XviD, suitable for
-+ most videos but in particular small videos
-+ (352x240 and below) meant for online
-+ distribution.
-+
-+ "lo": a low quality XviD format. Enlarging
-+ small videos will result in noticeable
-+ artifacts. Good for distributing over slow
-+ connections.
-+
-+ "hi_x", "mh_x", "ml_x", "lo_x": same as above.
-+
-+ "hi_h", "mh_h", "ml_h", "lo_h": same as above, but
-+ using the h.264 codec.
-+
-+ "hi_s", "mh_s", "ml_s", "lo_s": same as above, but
-+ the experimental
-+ SNOW codec.
-+
-+ Default: "ml"
-+
-+-e perform some simple filtering/enhancement to improve image
-+ quality. The images created by using this option will be
-+ stored in the directory specified by the "-w" option (or
-+ "-d" if not present, see above) and each filename will be
-+ prefixed with "eimg" (see "-p" above). Using this option will
-+ take enormous amounts of disk space, and in reality does
-+ not do anything that cannot be done within LiVES itself.
-+ Using this option enables the following four:
-+
-+ -w dir "dir" is the working directory where the enhanced
-+ images will be saved. Although these can all
-+ co-exist with the original LiVES files it is
-+ recommended you use a different directory. Note
-+ that temporary files may take a huge amount of
-+ space, perhaps twice as much as the LiVES files
-+ themselves. If this directory does not exist is
-+ will be created.
-+ Default: same as "-d".
-+
-+ -k keep the temporary files, useful to experiment
-+ with different encoding types without having
-+ to repeatedly enhance the images (which can be
-+ very time-consuming). See "-p" above.
-+
-+ -c geom in addition to enhancing the images, crop them
-+ to the specified geometry e.g. "688x448+17+11".
-+ Filename prefix remains "eimg". Note that the
-+ dimensions of the images should both be multiples
-+ of "16", otherwise some players may show artifacts
-+ (such as garbage or green bars at the borders).
-+
-+ -r geom this will create a second set of images resulting
-+ from resizing the images that have already been
-+ enhanced and possibly cropped (if "-c" has been
-+ specified). The geometry here is simple a new
-+ image size e.g. "352x240!". This second set will have
-+ filenames prefixed with the string "rimg" (see "-p"
-+ above). Note that the dimensions of the images
-+ should both be multiples of "16", otherwise some
-+ players may show artifacts (such as garbage or
-+ green bars at the borders).
-+
-+-s sndfile name of the audio file. Can be either raw "audio" or
-+ "[/path/to/]soundfile.wav".
-+ Default: "audio" inside "dir" as specified by "-d".
-+
-+-b sndrate sample rate of the sound file in Hertz.
-+ Default: "44100".
-+
-+-f fpscode frame-rate code. Acceptable values are:
-+
-+ 1 - 24000.0/1001.0 (NTSC 3:2 pulldown converted FILM)
-+ 2 - 24.0 (NATIVE FILM)
-+ 3 - 25.0 (PAL/SECAM VIDEO / converted FILM)
-+ 4 - 30000.0/1001.0 (NTSC VIDEO)
-+ 5 - 30.0
-+ 6 - 50.0 (PAL FIELD RATE)
-+ 7 - 60000.0/1001.0 (NTSC FIELD RATE)
-+ 8 - 60.0
-+
-+ If the input value is a float (e.g. 5.0, 14.555, etc.)
-+ the encoder will use that as frame rate.
-+
-+ Default: "4".
-+
-+-L lv1file use the images stored in the LiVES file "lv1file" (e.g.
-+ "movie.lv1"). Files will be extracted inside "dir" as
-+ specified by "-d". Using this option allows to encode
-+ a movie without having to restore it first with LiVES.
-+ Note that the encoder will not delete the extracted
-+ files after it has finished, this must be done manually
-+ afterwards. If frame code/rate (-f) and/or sound rate (-b)
-+ are not specified the defaults will be used (30000/1001 fps
-+ and 44100 Hz). These, however, may not be correct, in which
-+ case they should be specified explicitly. Furthermore, the
-+ .lv1 audio (if present) is always assumed to have a sample
-+ data size in 16-bit words with two channels, and to be signed
-+ linear (this is usually the case, however). If any of these
-+ latter parameters are incorrect the resulting file may be
-+ corrupted and encoding will have to be done using LiVES.
-+
-+firstframe first frame number. If less than eight digits long it will
-+ be padded with zeroes e.g. 234 -> 00000234. A prefix can
-+ be added using the "-p" option.
-+ Default: "00000001"
-+
-+lastframe last frame number, padded with zeroes if necessary, prefix
-+ set by "-p".
-+ Default: the last frame of its type in the "-d" directory,
-+ where "type" is set by the prefix.
-+
-+Note that either no frames or both first and last frames must be specified.
-+
-+EXAMPLES:
-+
-+Suppose you have restored a LiVES' .lv1 file (in either JPG or PNG format),
-+and that the images are stored in the directory "/tmp/livestmp/991319584/".
-+In this example the movie is assumed to be 16:9. Then, in order to create
-+an AVI file you can simply do the following:
-+
-+ avi_encoder.py -d /tmp/livestmp/991319584 -o /movies/default.avi -a 3
-+
-+and the clip "default.avi" will be created in "/movies/" with the correct
-+aspect ratio.
-+
-+Suppose we want to make a downloadable version of the clip, small in size
-+but of good quality. The following command activates the generic enhancement
-+filter and resizes the images to "352x240". Note that these operations
-+are performed after cropping the originals a bit (using "704x464+5+6").
-+This is done because we are assuming that there is a black border around
-+the original pictures which we want to get rid of (this might distort the
-+images somewhat, so be careful about cropping/resizing, and remember to
-+use dimensions which are multiples of 16):
-+
-+ avi_encoder.py -v -d /tmp/livestmp/991319584 -w /tmp/tmpavi \\
-+ -o /movies/download.avi -a 3 -k -e -c "704x464+5+6" -r "352x240"
-+
-+Since we use the "-k" flag the enhanced images are kept (both full-size
-+crops and the resized ones) in "/tmp/tmpavi". Beware that this may consume
-+a lot of disk space (about 10x as much as the originals). The reason we
-+keep them is because the above may take quite a long time and we may want
-+to re-use the enhanced images. So, for example, creating a high-quality
-+clip at full size can be accomplished now as follows:
-+
-+ avi_encoder.py -d /tmp/tmpavi -t hi -o /movies/archive.avi \\
-+ -s /tmp/livestmp/991319584/audio -a 3 -k -p eimg
-+
-+If, for example, we only want to encode frames 100 to 150 we can run
-+the following:
-+
-+ avi_encoder.py -v -d /tmp/tmpavi -o /movies/selection.avi \\
-+ -a 3 -k -p eimg 100 150
-+
-+Note that no audio has been selected ("-s"). This is because
-+avi_encoder.py cannot trim the audio to the appropriate length.
-+You would need to use LiVES to do this.
-+
-+To delete all the enhanced images you can just remove "/tmp/tmpavi".
-+
-+If you notice that the video and audio become out of sync so that
-+near the end of the movie the video trails the audio by, say, 0.2s,
-+you can use the "-D" option as follows:
-+
-+ avi_encoder.py -d /tmp/livestmp/991319584 -o test.avi -D 200
-+
-+Suppose that you have "movie1.lv1", "movie2.lv1" and "movie3.lv1".
-+Batch-encoding can be done as follows (zsh-syntax):
-+
-+ for i in movie?.lv1
-+ do
-+ mkdir /tmp/$i:r
-+ avi_encoder.py -d /tmp/$i:r -o /tmp/$i:r.avi -L $i
-+ rm -rf /tmp/$i:r
-+ done
-+
-+This will generate the files "movie1.avi", "movie2.avi" and
-+"movie3.avi" in "/tmp". Note that is is not necessary to
-+specify whether the files are stored in JPG or PNG format,
-+and that potentially time-consuming options (e.g. "-e") may
-+be enabled. It is not necessary to have a working LiVES
-+installation to encode .lv1 files.
-+ """ % version
-+
-+def run(command):
-+ """
-+ Run a shell command
-+ """
-+
-+ if verbose:
-+ print 'Running: \n' + command + '\n=== ... ==='
-+ std = ''
-+ else:
-+ std = ' > /dev/null 2>&1'
-+
-+ os.system(command + std)
-+
-+
-+def do_enhance():
-+ """
-+ Image cleanup/crop/resize routine. Generic, but seems to work
-+ well with anime :)
-+ """
-+
-+ if not quiet:
-+ print 'Enhancing images... please wait, this might take long...'
-+
-+ enh_opts = "-enhance -sharpen '0.0x0.5' -gamma 1.2 -contrast -depth 8"
-+
-+ if cgeom:
-+ docrop = ' '.join(['-crop', "'%s!'" % cgeom])
-+ else:
-+ docrop = ''
-+
-+ iframe = first_num
-+ while True:
-+ # File names are padded with zeroes to 8 characters
-+ # (not counting the .ext).
-+ frame = str(iframe).zfill(8)
-+ fname = os.path.join(img_dir, frame + ext)
-+ if not os.path.isfile(fname) or (iframe == last_num + 1):
-+ break
-+ eimg_fname = os.path.join(work_dir, 'eimg' + frame + '.png')
-+ rimg_fname = os.path.join(work_dir, 'rimg' + frame + '.png')
-+ command = ' '.join([convert, docrop, enh_opts, fname, eimg_fname])
-+ run(command)
-+ if rgeom:
-+ if os.path.exists(rimg_fname): os.remove(rimg_fname)
-+ shrink = ' '.join([convert, '-resize', "'%s!'" % rgeom, '-depth 8'])
-+ command = ' '.join([shrink, eimg_fname, rimg_fname])
-+ run(command)
-+ else:
-+ if os.path.exists(rimg_fname): os.remove(rimg_fname)
-+ try:
-+ os.symlink(eimg_fname, rimg_fname)
-+ except (IOError, OSError):
-+ shutil.copy(eimg_fname, rimg_fname)
-+ iframe+=1
-+
-+
-+def do_encode():
-+ """
-+ Encode a series of images into an XviD/Snow or h.264 stream, multiplexing
-+ audio if necessary
-+ """
-+
-+ if not quiet:
-+ print 'Creating "%s"-quality video' % vtype
-+
-+ if verbose:
-+ std = ''
-+ lameinfo = '--verbose'
-+ meinfo = '-v'
-+ hinfo = ':log=-1'
-+ else:
-+ std = ' > /dev/null 2>&1'
-+ lameinfo = '--quiet'
-+ meinfo = '-quiet'
-+ hinfo = ''
-+
-+ common_vopts = meinfo + ' -mf type=%s:fps=%s -mc 0 -noskip ' % (ext[1:], fps) + \
-+ '-vf hqdn3d=2:1:3,pp=va:128:8/ha:128:8/dr,dsize=%s' % aspect
-+
-+ if vtype[-1] == 's':
-+ codec_vopts = '-ovc lavc -lavcopts ' + \
-+ 'vcodec=snow:vstrict=-2:mbcmp=1:subcmp=1:cmp=1:mbd=2:v4mv' + \
-+ ':qpel:pred=1:autoaspect:vqscale='
-+ cpass = ''
-+ elif vtype[-1] == 'h':
-+ codec_vopts = '-ovc x264 -x264encopts ' + \
-+ 'frameref=15:subq=5' + hinfo + \
-+ ':bitrate='
-+ cpass = 'pass='
-+ else:
-+ codec_vopts = '-ovc xvid -xvidencopts qpel:chroma_me:chroma_opt' + \
-+ ':max_bframes=1:autoaspect:hq_ac:vhq=4:bitrate='
-+ cpass = 'pass='
-+
-+ vqual = vtype[0:-2]
-+ if vqual == 'hi':
-+ if vtype[-1] == 'x': rate = '2000:'
-+ if vtype[-1] == 's': rate = '2'
-+ if vtype[-1] == 'h': rate = '2000:'
-+ mencoder_opts = ' '.join([common_vopts, codec_vopts + rate + cpass])
-+ lameenc_opts = '--vbr-new -h -V 0'
-+ elif vqual == 'mh':
-+ if vtype[-1] == 'x': rate = '1000:'
-+ if vtype[-1] == 's': rate = '3'
-+ if vtype[-1] == 'h': rate = '1000:'
-+ mencoder_opts = ' '.join([common_vopts, codec_vopts + rate + cpass])
-+ lameenc_opts = '--vbr-new -h -V 2'
-+ elif vqual == 'ml':
-+ if vtype[-1] == 'x': rate = '500:'
-+ if vtype[-1] == 's': rate = '4'
-+ if vtype[-1] == 'h': rate = '500:'
-+ mencoder_opts = ' '.join([common_vopts, codec_vopts + rate + cpass])
-+ lameenc_opts = '--vbr-new -h -V 4'
-+ elif vqual == 'lo':
-+ if vtype[-1] == 'x': rate = '200:'
-+ if vtype[-1] == 's': rate = '6'
-+ if vtype[-1] == 'h': rate = '200:'
-+ mencoder_opts = ' '.join([common_vopts, codec_vopts + rate + cpass])
-+ lameenc_opts = '--vbr-new -h -V 6'
-+
-+
-+ if img_dir != work_dir and not enhance:
-+ source_dir = img_dir
-+ else:
-+ source_dir = work_dir
-+
-+ if frame_range:
-+ frame_list = [img_pre + str(f).zfill(8) + ext \
-+ for f in range(first_num, last_num + 1)]
-+ syml = 'temporary_symlink_'
-+ for iframe in frame_list:
-+ frfile = os.path.join(source_dir, iframe)
-+ frlink = os.path.join(source_dir, syml + iframe)
-+ if os.path.islink(frlink): os.remove(frlink)
-+ os.symlink(frfile, frlink)
-+ else:
-+ syml = ''
-+
-+ aviopts = '-of avi -force-avi-aspect %s -ofps %s' % (aspect, fps)
-+
-+ all_vars = {}
-+ all_vars.update(globals())
-+ all_vars.update(locals())
-+
-+ if audio:
-+ if not quiet:
-+ print 'Creating "%s"-quality mp3 file' % vtype
-+
-+ mp3 = tempfile.mkstemp('.mp3', '', work_dir)[1]
-+ if rawsndf:
-+ wav = tempfile.mkstemp('.wav', '', work_dir)[1]
-+ sox_opts = '-t raw -r %s -w -c 2 -s' % sndr
-+ command = ' '.join([sox, sox_opts, sndf, wav])
-+ run(command)
-+ else:
-+ wav = sndf
-+ command = ' '.join([lameenc, lameinfo, lameenc_opts, wav, mp3])
-+ run(command)
-+
-+ avimp3 = '-audiofile %s -oac copy -audio-delay %s' % (mp3, delay)
-+ else:
-+ wav = 'dummy'
-+ mp3 = 'dummy'
-+ avimp3 = '-nosound'
-+
-+ all_vars.update(locals())
-+
-+ if not quiet: print 'Encoding and multiplexing...'
-+ if vtype[-1] == 's':
-+ command = """cd %(source_dir)s ; \\
-+%(mencoder)s %(aviopts)s %(avimp3)s "mf://%(syml)s%(img_pre)s*%(ext)s" %(mencoder_opts)s -o "%(vidname)s" %(std)s""" % all_vars
-+ run(command)
-+ else:
-+ command = """cd %(source_dir)s ; \\
-+%(mencoder)s %(aviopts)s -nosound "mf://%(syml)s%(img_pre)s*%(ext)s" %(mencoder_opts)s1 -o /dev/null %(std)s ; \\
-+%(mencoder)s %(aviopts)s %(avimp3)s "mf://%(syml)s%(img_pre)s*%(ext)s" %(mencoder_opts)s2 -o "%(vidname)s" %(std)s
-+""" % all_vars
-+ run(command)
-+
-+ if os.path.exists(os.path.join(source_dir, 'divx2pass.log')):
-+ os.remove(os.path.join(source_dir, 'divx2pass.log'))
-+ if os.path.exists(os.path.join(source_dir, 'xvid-twopass.stats')):
-+ os.remove(os.path.join(source_dir, 'xvid-twopass.stats'))
-+ if rawsndf and os.path.exists(wav): os.remove(wav)
-+ if os.path.exists(mp3): os.remove(mp3)
-+
-+ if frame_range:
-+ lframes = os.path.join(source_dir, syml)
-+ for frame in glob.glob(lframes + '*'):
-+ os.remove(frame)
-+
-+
-+def do_clean():
-+ """
-+ Delete enhanced files
-+ """
-+
-+ if not quiet:
-+ print 'Deleting all enhanced images (if any)'
-+
-+ eframes = os.path.join(work_dir, 'eimg')
-+ rframes = os.path.join(work_dir, 'rimg')
-+ for frame in glob.glob(eframes + '*'):
-+ os.remove(frame)
-+ for frame in glob.glob(rframes + '*'):
-+ os.remove(frame)
-+
-+
-+def which(command):
-+ """
-+ Finds (or not) a command a la "which"
-+ """
-+
-+ command_found = False
-+
-+ if command[0] == '/':
-+ if os.path.isfile(command) and \
-+ os.access(command, os.X_OK):
-+ command_found = True
-+ abs_command = command
-+ else:
-+ path = os.environ.get('PATH', '').split(os.pathsep)
-+ for dir in path:
-+ abs_command = os.path.join(dir, command)
-+ if os.path.isfile(abs_command) and \
-+ os.access(abs_command, os.X_OK):
-+ command_found = True
-+ break
-+
-+ if not command_found:
-+ abs_command = ''
-+
-+ return abs_command
-+
-+
-+def is_installed(prog):
-+ """
-+ See whether "prog" is installed
-+ """
-+
-+ wprog = which(prog)
-+
-+ if wprog == '':
-+ print prog + ': command not found'
-+ raise SystemExit
-+ else:
-+ if verbose:
-+ print wprog + ': found'
-+
-+
-+if __name__ == '__main__':
-+
-+ import os
-+ import sys
-+ import getopt
-+ import shutil
-+ import tempfile
-+ import glob
-+ import tarfile
-+
-+ try:
-+ if sys.version_info[0:3] < (2, 3, 0):
-+ raise SystemExit
-+ except:
-+ print 'You need Python 2.3.0 or greater to run me!'
-+ raise SystemExit
-+
-+ try:
-+ (opts, args) = getopt.getopt(sys.argv[1:], \
-+ 'ho:p:d:w:a:qvt:ekc:r:s:b:f:VCD:L:')
-+ except:
-+ print "Something's wrong. Try the '-h' flag."
-+ raise SystemExit
-+
-+ opts = dict(opts)
-+
-+ if not opts and not args:
-+ print usage
-+ raise SystemExit
-+
-+ if '-h' in opts:
-+ print usage + help
-+ raise SystemExit
-+
-+ if '-V' in opts:
-+ print 'avi_encoder.py version ' + version
-+ raise SystemExit
-+
-+ if ('-v' in opts) or ('-C' in opts):
-+ verbose = True
-+ else:
-+ verbose = False
-+
-+ if '-q' in opts:
-+ quiet = True
-+ verbose = False
-+ else:
-+ quiet = False
-+
-+ for i in [convert, mencoder, lameenc, sox]:
-+ is_installed(i)
-+ if '-C' in opts: raise SystemExit
-+
-+ img_pre = opts.get('-p', '')
-+
-+ if img_pre not in ['', 'eimg', 'rimg']:
-+ print 'Improper image name prefix.'
-+ raise SystemExit
-+
-+ temp_dir = ''
-+ img_dir = opts.get('-d', '.')
-+ img_dir = os.path.abspath(img_dir)
-+ if ' ' in img_dir:
-+ temp_dir = tempfile.mkdtemp('', '.lives-', '/tmp/')
-+ os.symlink(img_dir, temp_dir + '/img_dir')
-+ img_dir = temp_dir + '/img_dir'
-+
-+ if not os.path.isdir(img_dir):
-+ print 'The image source directory: ' + img_dir + \
-+ ' does not exist!'
-+ raise SystemExit
-+
-+ if len(args) not in [0, 2]:
-+ print 'If frames are specified both first and last ' + \
-+ 'image numbers must be chosen.'
-+ raise SystemExit
-+ elif len(args) == 0:
-+ args = [None, None]
-+
-+ frame_range = False
-+ if not args[0]:
-+ first_frame_num = '1'
-+ else:
-+ frame_range = True
-+ first_frame_num = args[0]
-+ first_frame_num = first_frame_num.zfill(8)
-+ first_num = int(first_frame_num)
-+
-+ if not args[1]:
-+ last_frame_num = '99999999'
-+ else:
-+ last_frame_num = args[1]
-+ last_frame_num = last_frame_num.zfill(8)
-+ last_num = int(last_frame_num)
-+
-+ aspectc = opts.get('-a', '2')
-+
-+ if aspectc not in [str(i) for i in xrange(1,5)]:
-+ print 'Invalid aspect ratio.'
-+ raise SystemExit
-+ else:
-+ if aspectc == '1': aspect = 1.0/1.0
-+ elif aspectc == '2': aspect = 4.0/3.0
-+ elif aspectc == '3': aspect = 16.0/9.0
-+ elif aspectc == '4': aspect = 2.21/1.0
-+
-+ vtype = opts.get('-t', 'ml')
-+
-+ out_avi = opts.get('-o', vtype + '_movie.avi')
-+
-+ if '_' not in vtype:
-+ vtype = vtype + '_x'
-+
-+ if vtype not in ['hi_s', 'mh_s', 'ml_s', 'lo_s', \
-+ 'hi_h', 'mh_h', 'ml_h', 'lo_h', \
-+ 'hi_x', 'mh_x', 'ml_x', 'lo_x']:
-+ print 'Invalid video type.'
-+ raise SystemExit
-+
-+ fpsc = opts.get('-f', '4')
-+
-+ if fpsc not in [str(i) for i in xrange(1,9)]:
-+ if not quiet: print 'Invalid fps code, attempting float fps.'
-+ foundfps = False
-+ else:
-+ if fpsc == '1': fps = 24000.0/1001.0
-+ elif fpsc == '2': fps = 24.0
-+ elif fpsc == '3': fps = 25.0
-+ elif fpsc == '4': fps = 30000.0/1001.0
-+ elif fpsc == '5': fps = 30.0
-+ elif fpsc == '6': fps = 50.0
-+ elif fpsc == '7': fps = 60000.0/1001.0
-+ elif fpsc == '8': fps = 60.0
-+ foundfps = True
-+
-+ if not foundfps:
-+ try:
-+ fps = locale.atof(fpsc)
-+ if not quiet: print 'Using fps = %s' % fps
-+ if fps > 0: foundfps = True
-+ except:
-+ pass
-+
-+ if not foundfps:
-+ print 'Invalid fps code or rate.'
-+ raise SystemExit
-+
-+ if '-e' not in opts:
-+ enhance = False
-+ else:
-+ enhance = True
-+
-+ if enhance and img_pre:
-+ print 'Sorry, you cannot enhance already-enhanced images'
-+ raise SystemExit
-+
-+ if '-k' not in opts:
-+ keep = False
-+ else:
-+ keep = True
-+
-+ cgeom = opts.get('-c', '')
-+ rgeom = opts.get('-r', '')
-+
-+ if (cgeom or rgeom) and not enhance:
-+ print 'Missing "-e" option.'
-+ raise SystemExit
-+
-+ lv1file = opts.get('-L', None)
-+ if lv1file:
-+ if not quiet: print 'Opening lv1 file...'
-+ try:
-+ lv1 = tarfile.open(os.path.abspath(lv1file))
-+ except:
-+ print 'This does not appear to be a valid LiVES file!'
-+ raise SystemExit
-+ if 'header.tar' not in lv1.getnames():
-+ print 'This does not appear to be a valid LiVES file!'
-+ raise SystemExit
-+ for tfile in lv1.getmembers():
-+ lv1.extract(tfile, img_dir)
-+ for tfile in glob.glob(os.path.join(img_dir, '*.tar')):
-+ imgtar = tarfile.open(tfile)
-+ for img in imgtar.getmembers():
-+ imgtar.extract(img, img_dir)
-+ os.remove(tfile)
-+
-+ test_file = os.path.join(img_dir, img_pre + first_frame_num)
-+ if os.path.isfile(test_file + '.jpg'):
-+ ext = '.jpg'
-+ elif os.path.isfile(test_file + '.png'):
-+ ext = '.png'
-+ else:
-+ print 'Cannot find any appropriate %s or %s files!' % ('.jpg','.png')
-+ raise SystemExit
-+ first_frame = test_file + ext
-+ last_frame = os.path.join(img_dir, img_pre + last_frame_num + ext)
-+
-+ if not quiet: print 'Found: ' + first_frame
-+
-+ work_dir = opts.get('-w', img_dir)
-+ work_dir = os.path.abspath(work_dir)
-+ if not os.path.isdir(work_dir):
-+ if not quiet: print 'Creating ' + work_dir
-+ try:
-+ os.makedirs(work_dir)
-+ os.chmod(work_dir, 0755)
-+ except:
-+ print 'Could not create the work directory ' + \
-+ work_dir
-+ raise SystemExit
-+ if ' ' in work_dir:
-+ if temp_dir == '':
-+ temp_dir = tempfile.mkdtemp('', '.lives-', '/tmp/')
-+ os.symlink(work_dir, temp_dir + '/work_dir')
-+ work_dir = temp_dir + '/work_dir'
-+
-+ sndf = opts.get('-s', os.path.join(img_dir, 'audio'))
-+# sndf = os.path.abspath(sndf)
-+ rawsndf = True
-+ if not os.path.isfile(sndf):
-+ audio = False
-+ rawsndf = False
-+ else:
-+ audio = True
-+ if sndf[-4:] == '.wav':
-+ rawsndf = False
-+ if not quiet: print 'Found audio file: ' + sndf
-+
-+ sndr = opts.get('-b', '44100')
-+
-+ # We use here mencoder's -audio-delay which is not really
-+ # the true linear delay of the other plugins. See the mencoder
-+ # man page. Negative values do not work. Must be in seconds.
-+ delay = opts.get('-D', '0')
-+ try:
-+ delay = '%s' % (locale.atof(delay)/1000.0,)
-+ except:
-+ print 'Invalid audio delay: ' + delay
-+ if verbose and audio: print 'Audio delay (ms): ' + delay
-+
-+ if enhance:
-+ do_enhance()
-+ # Note that do_enhance() always creates images prefixed
-+ # with 'rimg'. What's important to note if that if the
-+ # images are resized the 'rimg' are indeed resized, but
-+ # if not the 'rimg' are simply symlinks to the 'eimg'
-+ # (enhanced) images.
-+ img_pre = 'rimg'
-+ ext = '.png'
-+ vidname = os.path.join(work_dir, out_avi)
-+ # do_encode() acts on images prefixed by img_pre.
-+ do_encode()
-+ if not keep:
-+ do_clean()
-+ if temp_dir != '':
-+ shutil.rmtree(temp_dir)
-+ if not quiet: print "Done!"
-+
-+
-+"""
-+CHANGELOG:
-+
-+03 Jan 2005 : 0.0.1 : first release, based on mkv_encoder.py.
-+04 Jan 2005 : 0.0.2 : added support for h.264.
-+10 Mar 2005 : 0.0.3 : fixed snow quality settings.
-+26 Mar 2005 : 0.0.4 : use env python (hopefully >= 2.3).
-+ replace denoise3d with hqdn3d.
-+24 Aug 2005 : 0.0.5 : fixed 2.21:1 aspect ratio.
-+ fine-tune mplayer filters.
-+ expanded h.264 bit rates.
-+09 Mar 2006 : 0.0.6 : added '-depth 8' to resize, as ImageMagick
-+ keeps changing its damn behaviour.
-+ Fixed snow encoding (still highly experimental).
-+ Fixed bitrate levels.
-+13 Mar 2006 : 0.0.7 : tweaked bitrate levels.
-+28 Jun 2007 : 0.0.8 : handles paths with spaces appropriately
-+ (thanks Gabriel).
-+08 Dec 2007 : 0.0.9 : added "-mc 0" and "-noskip" options.
-+"""
---- lives.orig/lives-plugins/marcos-encoders/avi_encoder.py
-+++ /dev/null
-@@ -1,825 +0,0 @@
--#!/usr/bin/env python
--
--
--import locale
--locale.setlocale(locale.LC_NUMERIC,"")
--
--"""
--avi_encoder.py
--
--Front-end to various programs needed to create AVI
--movies with some image-enhancing capabilities through the use of
--ImageMagick. Meant as a companion to LiVES (to possibly call
--from within a plugin, see http://www.xs4all.nl/~salsaman/lives/ )
--but can also be used as a stand-alone program.
--
--Requires MPlayer, ImageMagick (GraphicsMagick might also
--work), sox, lame, and Python 2.3.0 or greater. Note that
--this program can encode a SNOW video stream (if mencoder
--supports it), but that it is still highly experimental.
--This is also true for h.264. Use at your own risk.
--
--Copyright (C) 2004-2005 Marco De la Cruz (marco at reimeika.ca)
--It's a trivial program, but might as well GPL it, so see:
--http://www.gnu.org/copyleft/gpl.html for license.
--
--See my vids at http://amv.reimeika.ca !
--"""
--
--version = '0.0.10'
--convert = 'convert'
--mencoder = 'mencoder'
--lameenc = 'lame'
--sox = 'sox'
--
--usage = \
-- """
--avi_encoder.py -h
--avi_encoder.py -V
--avi_encoder.py -C
--avi_encoder.py [-o out] [-p pre] [-d dir] [-a aspect] [-D delay]
-- [-q|-v] [-t type] [-k] [-e [[-w dir] [-c geom] [-r geom]]]
-- [-s sndfile] [-b sndrate] [-f fpscode] [-L lv1file]
-- [firstframe lastframe]
-- """
--
--help = \
-- """
--SUMMARY (ver. %s):
--
--Encodes a series of PNG or JPG images into an XviD/Snow/h.264 + MP3
--(AVI) stream and is also capable of performing some simple image
--enhacements using ImageMagick. The images and audio are assumed to
--be in an uncompressed LiVES format, hence making this encoder
--more suitable to be used within a LiVES plugin (but can also
--be used directly on a LiVES temporary directory).
--
--OPTIONS:
--
---h for help.
--
---V shows the version number.
--
---C check external program dependencies and exit.
--
---o out will save the video in file "out".
-- Default: "'type'_movie.avi". See below for 'type'.
--
---p pre the encoder assumes that sound and images are named using
-- LiVES' conventions i.e. "audio" and "00000001.ext",
-- "00000002.ext"... where "ext" is either "jpg" or "png".
-- However, avi_encoder.py will create temporary files
-- which can be saved for later use (for example, after
-- enhancing the images with "-e" , which may take a long
-- time). These temporary files will be named
-- "pre_00000001.ext", etc... where "pre" is either "eimg"
-- or "rimg" and will be kept if the "-k" option is used.
-- avi_encoder.py can then be run over the enhanced images
-- only by selecting the appropriate prefix ("eimg" or
-- "rimg") here. See "-e" to see what each prefix means.
-- Default: "" (an empty string).
--
---d dir "dir" is the directory containing the source image
-- files. These must be of the form "00000001.ext" or
-- "pre_00000001.ext" as explained above.
-- Default: "."
--
---a aspect sets the aspect ratio of the resulting MPEG-4. This can be:
--
-- 1 1:1 display
-- 2 4:3 display
-- 3 16:9 display
-- 4 2.21:1 display
--
-- Default: "2"
--
---D delay delay the audio stream by "delay" ms. Must be positive.
-- Default: "0"
--
---q quiet operation, only complains on error.
--
---v be verbose.
--
---t type type of video created. The options here are:
--
-- "hi": a very high quality XviD file, suitable
-- for archiving images of 720x480.
--
-- "mh": medium-high quality XviD, which still allows
-- to watch small videos (352x240 and below)
-- fullscreen.
--
-- "ml": medium-low quality XviD, suitable for
-- most videos but in particular small videos
-- (352x240 and below) meant for online
-- distribution.
--
-- "lo": a low quality XviD format. Enlarging
-- small videos will result in noticeable
-- artifacts. Good for distributing over slow
-- connections.
--
-- "hi_x", "mh_x", "ml_x", "lo_x": same as above.
--
-- "hi_h", "mh_h", "ml_h", "lo_h": same as above, but
-- using the h.264 codec.
--
-- "hi_s", "mh_s", "ml_s", "lo_s": same as above, but
-- the experimental
-- SNOW codec.
--
-- Default: "ml"
--
---e perform some simple filtering/enhancement to improve image
-- quality. The images created by using this option will be
-- stored in the directory specified by the "-w" option (or
-- "-d" if not present, see above) and each filename will be
-- prefixed with "eimg" (see "-p" above). Using this option will
-- take enormous amounts of disk space, and in reality does
-- not do anything that cannot be done within LiVES itself.
-- Using this option enables the following four:
--
-- -w dir "dir" is the working directory where the enhanced
-- images will be saved. Although these can all
-- co-exist with the original LiVES files it is
-- recommended you use a different directory. Note
-- that temporary files may take a huge amount of
-- space, perhaps twice as much as the LiVES files
-- themselves. If this directory does not exist is
-- will be created.
-- Default: same as "-d".
--
-- -k keep the temporary files, useful to experiment
-- with different encoding types without having
-- to repeatedly enhance the images (which can be
-- very time-consuming). See "-p" above.
--
-- -c geom in addition to enhancing the images, crop them
-- to the specified geometry e.g. "688x448+17+11".
-- Filename prefix remains "eimg". Note that the
-- dimensions of the images should both be multiples
-- of "16", otherwise some players may show artifacts
-- (such as garbage or green bars at the borders).
--
-- -r geom this will create a second set of images resulting
-- from resizing the images that have already been
-- enhanced and possibly cropped (if "-c" has been
-- specified). The geometry here is simple a new
-- image size e.g. "352x240!". This second set will have
-- filenames prefixed with the string "rimg" (see "-p"
-- above). Note that the dimensions of the images
-- should both be multiples of "16", otherwise some
-- players may show artifacts (such as garbage or
-- green bars at the borders).
--
---s sndfile name of the audio file. Can be either raw "audio" or
-- "[/path/to/]soundfile.wav".
-- Default: "audio" inside "dir" as specified by "-d".
--
---b sndrate sample rate of the sound file in Hertz.
-- Default: "44100".
--
---f fpscode frame-rate code. Acceptable values are:
--
-- 1 - 24000.0/1001.0 (NTSC 3:2 pulldown converted FILM)
-- 2 - 24.0 (NATIVE FILM)
-- 3 - 25.0 (PAL/SECAM VIDEO / converted FILM)
-- 4 - 30000.0/1001.0 (NTSC VIDEO)
-- 5 - 30.0
-- 6 - 50.0 (PAL FIELD RATE)
-- 7 - 60000.0/1001.0 (NTSC FIELD RATE)
-- 8 - 60.0
--
-- If the input value is a float (e.g. 5.0, 14.555, etc.)
-- the encoder will use that as frame rate.
--
-- Default: "4".
--
---L lv1file use the images stored in the LiVES file "lv1file" (e.g.
-- "movie.lv1"). Files will be extracted inside "dir" as
-- specified by "-d". Using this option allows to encode
-- a movie without having to restore it first with LiVES.
-- Note that the encoder will not delete the extracted
-- files after it has finished, this must be done manually
-- afterwards. If frame code/rate (-f) and/or sound rate (-b)
-- are not specified the defaults will be used (30000/1001 fps
-- and 44100 Hz). These, however, may not be correct, in which
-- case they should be specified explicitly. Furthermore, the
-- .lv1 audio (if present) is always assumed to have a sample
-- data size in 16-bit words with two channels, and to be signed
-- linear (this is usually the case, however). If any of these
-- latter parameters are incorrect the resulting file may be
-- corrupted and encoding will have to be done using LiVES.
--
--firstframe first frame number. If less than eight digits long it will
-- be padded with zeroes e.g. 234 -> 00000234. A prefix can
-- be added using the "-p" option.
-- Default: "00000001"
--
--lastframe last frame number, padded with zeroes if necessary, prefix
-- set by "-p".
-- Default: the last frame of its type in the "-d" directory,
-- where "type" is set by the prefix.
--
--Note that either no frames or both first and last frames must be specified.
--
--EXAMPLES:
--
--Suppose you have restored a LiVES' .lv1 file (in either JPG or PNG format),
--and that the images are stored in the directory "/tmp/livestmp/991319584/".
--In this example the movie is assumed to be 16:9. Then, in order to create
--an AVI file you can simply do the following:
--
-- avi_encoder.py -d /tmp/livestmp/991319584 -o /movies/default.avi -a 3
--
--and the clip "default.avi" will be created in "/movies/" with the correct
--aspect ratio.
--
--Suppose we want to make a downloadable version of the clip, small in size
--but of good quality. The following command activates the generic enhancement
--filter and resizes the images to "352x240". Note that these operations
--are performed after cropping the originals a bit (using "704x464+5+6").
--This is done because we are assuming that there is a black border around
--the original pictures which we want to get rid of (this might distort the
--images somewhat, so be careful about cropping/resizing, and remember to
--use dimensions which are multiples of 16):
--
-- avi_encoder.py -v -d /tmp/livestmp/991319584 -w /tmp/tmpavi \\
-- -o /movies/download.avi -a 3 -k -e -c "704x464+5+6" -r "352x240"
--
--Since we use the "-k" flag the enhanced images are kept (both full-size
--crops and the resized ones) in "/tmp/tmpavi". Beware that this may consume
--a lot of disk space (about 10x as much as the originals). The reason we
--keep them is because the above may take quite a long time and we may want
--to re-use the enhanced images. So, for example, creating a high-quality
--clip at full size can be accomplished now as follows:
--
-- avi_encoder.py -d /tmp/tmpavi -t hi -o /movies/archive.avi \\
-- -s /tmp/livestmp/991319584/audio -a 3 -k -p eimg
--
--If, for example, we only want to encode frames 100 to 150 we can run
--the following:
--
-- avi_encoder.py -v -d /tmp/tmpavi -o /movies/selection.avi \\
-- -a 3 -k -p eimg 100 150
--
--Note that no audio has been selected ("-s"). This is because
--avi_encoder.py cannot trim the audio to the appropriate length.
--You would need to use LiVES to do this.
--
--To delete all the enhanced images you can just remove "/tmp/tmpavi".
--
--If you notice that the video and audio become out of sync so that
--near the end of the movie the video trails the audio by, say, 0.2s,
--you can use the "-D" option as follows:
--
-- avi_encoder.py -d /tmp/livestmp/991319584 -o test.avi -D 200
--
--Suppose that you have "movie1.lv1", "movie2.lv1" and "movie3.lv1".
--Batch-encoding can be done as follows (zsh-syntax):
--
-- for i in movie?.lv1
-- do
-- mkdir /tmp/$i:r
-- avi_encoder.py -d /tmp/$i:r -o /tmp/$i:r.avi -L $i
-- rm -rf /tmp/$i:r
-- done
--
--This will generate the files "movie1.avi", "movie2.avi" and
--"movie3.avi" in "/tmp". Note that is is not necessary to
--specify whether the files are stored in JPG or PNG format,
--and that potentially time-consuming options (e.g. "-e") may
--be enabled. It is not necessary to have a working LiVES
--installation to encode .lv1 files.
-- """ % version
--
--def run(command):
-- """
-- Run a shell command
-- """
--
-- if verbose:
-- print 'Running: \n' + command + '\n=== ... ==='
-- std = ''
-- else:
-- std = ' > /dev/null 2>&1'
--
-- os.system(command + std)
--
--
--def do_enhance():
-- """
-- Image cleanup/crop/resize routine. Generic, but seems to work
-- well with anime :)
-- """
--
-- if not quiet:
-- print 'Enhancing images... please wait, this might take long...'
--
-- enh_opts = "-enhance -sharpen '0.0x0.5' -gamma 1.2 -contrast -depth 8"
--
-- if cgeom:
-- docrop = ' '.join(['-crop', "'%s!'" % cgeom])
-- else:
-- docrop = ''
--
-- iframe = first_num
-- while True:
-- # File names are padded with zeroes to 8 characters
-- # (not counting the .ext).
-- frame = str(iframe).zfill(8)
-- fname = os.path.join(img_dir, frame + ext)
-- if not os.path.isfile(fname) or (iframe == last_num + 1):
-- break
-- eimg_fname = os.path.join(work_dir, 'eimg' + frame + '.png')
-- rimg_fname = os.path.join(work_dir, 'rimg' + frame + '.png')
-- command = ' '.join([convert, docrop, enh_opts, fname, eimg_fname])
-- run(command)
-- if rgeom:
-- if os.path.exists(rimg_fname): os.remove(rimg_fname)
-- shrink = ' '.join([convert, '-resize', "'%s!'" % rgeom, '-depth 8'])
-- command = ' '.join([shrink, eimg_fname, rimg_fname])
-- run(command)
-- else:
-- if os.path.exists(rimg_fname): os.remove(rimg_fname)
-- try:
-- os.symlink(eimg_fname, rimg_fname)
-- except (IOError, OSError):
-- shutil.copy(eimg_fname, rimg_fname)
-- iframe+=1
--
--
--def do_encode():
-- """
-- Encode a series of images into an XviD/Snow or h.264 stream, multiplexing
-- audio if necessary
-- """
--
-- if not quiet:
-- print 'Creating "%s"-quality video' % vtype
--
-- if verbose:
-- std = ''
-- lameinfo = '--verbose'
-- meinfo = '-v'
-- hinfo = ':log=-1'
-- else:
-- std = ' > /dev/null 2>&1'
-- lameinfo = '--quiet'
-- meinfo = '-quiet'
-- hinfo = ''
--
-- common_vopts = meinfo + ' -mf type=%s:fps=%s -mc 0 -noskip ' % (ext[1:], fps) + \
-- '-vf hqdn3d=2:1:3,pp=va:128:8/ha:128:8/dr,dsize=%s' % aspect
--
-- if vtype[-1] == 's':
-- codec_vopts = '-ovc lavc -lavcopts ' + \
-- 'vcodec=snow:vstrict=-2:mbcmp=1:subcmp=1:cmp=1:mbd=2:v4mv' + \
-- ':qpel:pred=1:autoaspect:vqscale='
-- cpass = ''
-- elif vtype[-1] == 'h':
-- codec_vopts = '-ovc x264 -x264encopts ' + \
-- 'frameref=15:subq=5' + hinfo + \
-- ':bitrate='
-- cpass = 'pass='
-- else:
-- codec_vopts = '-ovc xvid -xvidencopts qpel:chroma_me:chroma_opt' + \
-- ':max_bframes=1:autoaspect:hq_ac:vhq=4:bitrate='
-- cpass = 'pass='
--
-- vqual = vtype[0:-2]
-- if vqual == 'hi':
-- if vtype[-1] == 'x': rate = '2000:'
-- if vtype[-1] == 's': rate = '2'
-- if vtype[-1] == 'h': rate = '2000:'
-- mencoder_opts = ' '.join([common_vopts, codec_vopts + rate + cpass])
-- lameenc_opts = '--vbr-new -h -V 0'
-- elif vqual == 'mh':
-- if vtype[-1] == 'x': rate = '1000:'
-- if vtype[-1] == 's': rate = '3'
-- if vtype[-1] == 'h': rate = '1000:'
-- mencoder_opts = ' '.join([common_vopts, codec_vopts + rate + cpass])
-- lameenc_opts = '--vbr-new -h -V 2'
-- elif vqual == 'ml':
-- if vtype[-1] == 'x': rate = '500:'
-- if vtype[-1] == 's': rate = '4'
-- if vtype[-1] == 'h': rate = '500:'
-- mencoder_opts = ' '.join([common_vopts, codec_vopts + rate + cpass])
-- lameenc_opts = '--vbr-new -h -V 4'
-- elif vqual == 'lo':
-- if vtype[-1] == 'x': rate = '200:'
-- if vtype[-1] == 's': rate = '6'
-- if vtype[-1] == 'h': rate = '200:'
-- mencoder_opts = ' '.join([common_vopts, codec_vopts + rate + cpass])
-- lameenc_opts = '--vbr-new -h -V 6'
--
--
-- if img_dir != work_dir and not enhance:
-- source_dir = img_dir
-- else:
-- source_dir = work_dir
--
-- if frame_range:
-- frame_list = [img_pre + str(f).zfill(8) + ext \
-- for f in range(first_num, last_num + 1)]
-- syml = 'temporary_symlink_'
-- for iframe in frame_list:
-- frfile = os.path.join(source_dir, iframe)
-- frlink = os.path.join(source_dir, syml + iframe)
-- if os.path.islink(frlink): os.remove(frlink)
-- os.symlink(frfile, frlink)
-- else:
-- syml = ''
--
-- aviopts = '-of avi -force-avi-aspect %s -ofps %s' % (aspect, fps)
--
-- all_vars = {}
-- all_vars.update(globals())
-- all_vars.update(locals())
--
-- if audio:
-- if not quiet:
-- print 'Creating "%s"-quality mp3 file' % vtype
--
-- mp3 = tempfile.mkstemp('.mp3', '', work_dir)[1]
-- if rawsndf:
-- wav = tempfile.mkstemp('.wav', '', work_dir)[1]
-- sox_opts = '-t raw -r %s -w -c 2 -s' % sndr
-- command = ' '.join([sox, sox_opts, sndf, wav])
-- run(command)
-- else:
-- wav = sndf
-- command = ' '.join([lameenc, lameinfo, lameenc_opts, wav, mp3])
-- run(command)
--
-- avimp3 = '-audiofile %s -oac copy -audio-delay %s' % (mp3, delay)
-- else:
-- wav = 'dummy'
-- mp3 = 'dummy'
-- avimp3 = '-nosound'
--
-- all_vars.update(locals())
--
-- if not quiet: print 'Encoding and multiplexing...'
-- if vtype[-1] == 's':
-- command = """cd %(source_dir)s ; \\
--%(mencoder)s %(aviopts)s %(avimp3)s "mf://%(syml)s%(img_pre)s*%(ext)s" %(mencoder_opts)s -o "%(vidname)s" %(std)s""" % all_vars
-- run(command)
-- else:
-- command = """cd %(source_dir)s ; \\
--%(mencoder)s %(aviopts)s -nosound "mf://%(syml)s%(img_pre)s*%(ext)s" %(mencoder_opts)s1 -o /dev/null %(std)s ; \\
--%(mencoder)s %(aviopts)s %(avimp3)s "mf://%(syml)s%(img_pre)s*%(ext)s" %(mencoder_opts)s2 -o "%(vidname)s" %(std)s
--""" % all_vars
-- run(command)
--
-- if os.path.exists(os.path.join(source_dir, 'divx2pass.log')):
-- os.remove(os.path.join(source_dir, 'divx2pass.log'))
-- if os.path.exists(os.path.join(source_dir, 'xvid-twopass.stats')):
-- os.remove(os.path.join(source_dir, 'xvid-twopass.stats'))
-- if rawsndf and os.path.exists(wav): os.remove(wav)
-- if os.path.exists(mp3): os.remove(mp3)
--
-- if frame_range:
-- lframes = os.path.join(source_dir, syml)
-- for frame in glob.glob(lframes + '*'):
-- os.remove(frame)
--
--
--def do_clean():
-- """
-- Delete enhanced files
-- """
--
-- if not quiet:
-- print 'Deleting all enhanced images (if any)'
--
-- eframes = os.path.join(work_dir, 'eimg')
-- rframes = os.path.join(work_dir, 'rimg')
-- for frame in glob.glob(eframes + '*'):
-- os.remove(frame)
-- for frame in glob.glob(rframes + '*'):
-- os.remove(frame)
--
--
--def which(command):
-- """
-- Finds (or not) a command a la "which"
-- """
--
-- command_found = False
--
-- if command[0] == '/':
-- if os.path.isfile(command) and \
-- os.access(command, os.X_OK):
-- command_found = True
-- abs_command = command
-- else:
-- path = os.environ.get('PATH', '').split(os.pathsep)
-- for dir in path:
-- abs_command = os.path.join(dir, command)
-- if os.path.isfile(abs_command) and \
-- os.access(abs_command, os.X_OK):
-- command_found = True
-- break
--
-- if not command_found:
-- abs_command = ''
--
-- return abs_command
--
--
--def is_installed(prog):
-- """
-- See whether "prog" is installed
-- """
--
-- wprog = which(prog)
--
-- if wprog == '':
-- print prog + ': command not found'
-- raise SystemExit
-- else:
-- if verbose:
-- print wprog + ': found'
--
--
--if __name__ == '__main__':
--
-- import os
-- import sys
-- import getopt
-- import shutil
-- import tempfile
-- import glob
-- import tarfile
--
-- try:
-- if sys.version_info[0:3] < (2, 3, 0):
-- raise SystemExit
-- except:
-- print 'You need Python 2.3.0 or greater to run me!'
-- raise SystemExit
--
-- try:
-- (opts, args) = getopt.getopt(sys.argv[1:], \
-- 'ho:p:d:w:a:qvt:ekc:r:s:b:f:VCD:L:')
-- except:
-- print "Something's wrong. Try the '-h' flag."
-- raise SystemExit
--
-- opts = dict(opts)
--
-- if not opts and not args:
-- print usage
-- raise SystemExit
--
-- if '-h' in opts:
-- print usage + help
-- raise SystemExit
--
-- if '-V' in opts:
-- print 'avi_encoder.py version ' + version
-- raise SystemExit
--
-- if ('-v' in opts) or ('-C' in opts):
-- verbose = True
-- else:
-- verbose = False
--
-- if '-q' in opts:
-- quiet = True
-- verbose = False
-- else:
-- quiet = False
--
-- for i in [convert, mencoder, lameenc, sox]:
-- is_installed(i)
-- if '-C' in opts: raise SystemExit
--
-- img_pre = opts.get('-p', '')
--
-- if img_pre not in ['', 'eimg', 'rimg']:
-- print 'Improper image name prefix.'
-- raise SystemExit
--
-- temp_dir = ''
-- img_dir = opts.get('-d', '.')
-- img_dir = os.path.abspath(img_dir)
-- if ' ' in img_dir:
-- temp_dir = tempfile.mkdtemp('', '.lives-', '/tmp/')
-- os.symlink(img_dir, temp_dir + '/img_dir')
-- img_dir = temp_dir + '/img_dir'
--
-- if not os.path.isdir(img_dir):
-- print 'The image source directory: ' + img_dir + \
-- ' does not exist!'
-- raise SystemExit
--
-- if len(args) not in [0, 2]:
-- print 'If frames are specified both first and last ' + \
-- 'image numbers must be chosen.'
-- raise SystemExit
-- elif len(args) == 0:
-- args = [None, None]
--
-- frame_range = False
-- if not args[0]:
-- first_frame_num = '1'
-- else:
-- frame_range = True
-- first_frame_num = args[0]
-- first_frame_num = first_frame_num.zfill(8)
-- first_num = int(first_frame_num)
--
-- if not args[1]:
-- last_frame_num = '99999999'
-- else:
-- last_frame_num = args[1]
-- last_frame_num = last_frame_num.zfill(8)
-- last_num = int(last_frame_num)
--
-- aspectc = opts.get('-a', '2')
--
-- if aspectc not in [str(i) for i in xrange(1,5)]:
-- print 'Invalid aspect ratio.'
-- raise SystemExit
-- else:
-- if aspectc == '1': aspect = 1.0/1.0
-- elif aspectc == '2': aspect = 4.0/3.0
-- elif aspectc == '3': aspect = 16.0/9.0
-- elif aspectc == '4': aspect = 2.21/1.0
--
-- vtype = opts.get('-t', 'ml')
--
-- out_avi = opts.get('-o', vtype + '_movie.avi')
--
-- if '_' not in vtype:
-- vtype = vtype + '_x'
--
-- if vtype not in ['hi_s', 'mh_s', 'ml_s', 'lo_s', \
-- 'hi_h', 'mh_h', 'ml_h', 'lo_h', \
-- 'hi_x', 'mh_x', 'ml_x', 'lo_x']:
-- print 'Invalid video type.'
-- raise SystemExit
--
-- fpsc = opts.get('-f', '4')
--
-- if fpsc not in [str(i) for i in xrange(1,9)]:
-- if not quiet: print 'Invalid fps code, attempting float fps.'
-- foundfps = False
-- else:
-- if fpsc == '1': fps = 24000.0/1001.0
-- elif fpsc == '2': fps = 24.0
-- elif fpsc == '3': fps = 25.0
-- elif fpsc == '4': fps = 30000.0/1001.0
-- elif fpsc == '5': fps = 30.0
-- elif fpsc == '6': fps = 50.0
-- elif fpsc == '7': fps = 60000.0/1001.0
-- elif fpsc == '8': fps = 60.0
-- foundfps = True
--
-- if not foundfps:
-- try:
-- fps = locale.atof(fpsc)
-- if not quiet: print 'Using fps = %s' % fps
-- if fps > 0: foundfps = True
-- except:
-- pass
--
-- if not foundfps:
-- print 'Invalid fps code or rate.'
-- raise SystemExit
--
-- if '-e' not in opts:
-- enhance = False
-- else:
-- enhance = True
--
-- if enhance and img_pre:
-- print 'Sorry, you cannot enhance already-enhanced images'
-- raise SystemExit
--
-- if '-k' not in opts:
-- keep = False
-- else:
-- keep = True
--
-- cgeom = opts.get('-c', '')
-- rgeom = opts.get('-r', '')
--
-- if (cgeom or rgeom) and not enhance:
-- print 'Missing "-e" option.'
-- raise SystemExit
--
-- lv1file = opts.get('-L', None)
-- if lv1file:
-- if not quiet: print 'Opening lv1 file...'
-- try:
-- lv1 = tarfile.open(os.path.abspath(lv1file))
-- except:
-- print 'This does not appear to be a valid LiVES file!'
-- raise SystemExit
-- if 'header.tar' not in lv1.getnames():
-- print 'This does not appear to be a valid LiVES file!'
-- raise SystemExit
-- for tfile in lv1.getmembers():
-- lv1.extract(tfile, img_dir)
-- for tfile in glob.glob(os.path.join(img_dir, '*.tar')):
-- imgtar = tarfile.open(tfile)
-- for img in imgtar.getmembers():
-- imgtar.extract(img, img_dir)
-- os.remove(tfile)
--
-- test_file = os.path.join(img_dir, img_pre + first_frame_num)
-- if os.path.isfile(test_file + '.jpg'):
-- ext = '.jpg'
-- elif os.path.isfile(test_file + '.png'):
-- ext = '.png'
-- else:
-- print 'Cannot find any appropriate %s or %s files!' % ('.jpg','.png')
-- raise SystemExit
-- first_frame = test_file + ext
-- last_frame = os.path.join(img_dir, img_pre + last_frame_num + ext)
--
-- if not quiet: print 'Found: ' + first_frame
--
-- work_dir = opts.get('-w', img_dir)
-- work_dir = os.path.abspath(work_dir)
-- if not os.path.isdir(work_dir):
-- if not quiet: print 'Creating ' + work_dir
-- try:
-- os.makedirs(work_dir)
-- os.chmod(work_dir, 0755)
-- except:
-- print 'Could not create the work directory ' + \
-- work_dir
-- raise SystemExit
-- if ' ' in work_dir:
-- if temp_dir == '':
-- temp_dir = tempfile.mkdtemp('', '.lives-', '/tmp/')
-- os.symlink(work_dir, temp_dir + '/work_dir')
-- work_dir = temp_dir + '/work_dir'
--
-- sndf = opts.get('-s', os.path.join(img_dir, 'audio'))
--# sndf = os.path.abspath(sndf)
-- rawsndf = True
-- if not os.path.isfile(sndf):
-- audio = False
-- rawsndf = False
-- else:
-- audio = True
-- if sndf[-4:] == '.wav':
-- rawsndf = False
-- if not quiet: print 'Found audio file: ' + sndf
--
-- sndr = opts.get('-b', '44100')
--
-- # We use here mencoder's -audio-delay which is not really
-- # the true linear delay of the other plugins. See the mencoder
-- # man page. Negative values do not work. Must be in seconds.
-- delay = opts.get('-D', '0')
-- try:
-- delay = '%s' % (locale.atof(delay)/1000.0,)
-- except:
-- print 'Invalid audio delay: ' + delay
-- if verbose and audio: print 'Audio delay (ms): ' + delay
--
-- if enhance:
-- do_enhance()
-- # Note that do_enhance() always creates images prefixed
-- # with 'rimg'. What's important to note if that if the
-- # images are resized the 'rimg' are indeed resized, but
-- # if not the 'rimg' are simply symlinks to the 'eimg'
-- # (enhanced) images.
-- img_pre = 'rimg'
-- ext = '.png'
-- vidname = os.path.join(work_dir, out_avi)
-- # do_encode() acts on images prefixed by img_pre.
-- do_encode()
-- if not keep:
-- do_clean()
-- if temp_dir != '':
-- shutil.rmtree(temp_dir)
-- if not quiet: print "Done!"
--
--
--"""
--CHANGELOG:
--
--03 Jan 2005 : 0.0.1 : first release, based on mkv_encoder.py.
--04 Jan 2005 : 0.0.2 : added support for h.264.
--10 Mar 2005 : 0.0.3 : fixed snow quality settings.
--26 Mar 2005 : 0.0.4 : use env python (hopefully >= 2.3).
-- replace denoise3d with hqdn3d.
--24 Aug 2005 : 0.0.5 : fixed 2.21:1 aspect ratio.
-- fine-tune mplayer filters.
-- expanded h.264 bit rates.
--09 Mar 2006 : 0.0.6 : added '-depth 8' to resize, as ImageMagick
-- keeps changing its damn behaviour.
-- Fixed snow encoding (still highly experimental).
-- Fixed bitrate levels.
--13 Mar 2006 : 0.0.7 : tweaked bitrate levels.
--28 Jun 2007 : 0.0.8 : handles paths with spaces appropriately
-- (thanks Gabriel).
--08 Dec 2007 : 0.0.9 : added "-mc 0" and "-noskip" options.
--"""
---- lives.orig/lives-plugins/marcos-encoders/dirac_encoder.py
-+++ /dev/null
-@@ -1,843 +0,0 @@
--#!/usr/bin/env python
--
--
--import locale
--locale.setlocale(locale.LC_NUMERIC,"")
--
--
--"""
--dirac_encoder.py
--
--Front-end to various programs needed to create Dirac
--movies with some image-enhancing capabilities through the use of
--ImageMagick. Meant as a companion to LiVES (to possibly call
--from within a plugin, see http://www.xs4all.nl/~salsaman/lives/ )
--but can also be used as a stand-alone program.
--
--Requires MPlayer, ImageMagick (GraphicsMagick might also
--work), Dirac, and Python 2.3.0 or greater. Note that audio
--support is not yet implemented, only video encoding. Also
--note that Dirac is still at a very early stage of development,
--and hence this code is highly experimental. Use at your
--own risk.
--
--Dirac's encoder API changed between versions 0.5.1 and 0.5.2.
--This encoder will not work with 0.5.1 but has been tested with
--0.5.2.
--
--Copyright (C) 2004-2005 Marco De la Cruz (marco at reimeika.ca)
--It's a trivial program, but might as well GPL it, so see:
--http://www.gnu.org/copyleft/gpl.html for license.
--
--See my vids at http://amv.reimeika.ca !
--"""
--
--version = '0.0.a15'
--convert = 'convert'
--mencoder = 'mencoder'
--dirac_encoder = 'dirac_encoder'
--identify = 'identify'
--
--usage = \
-- """
--dirac_encoder.py -h
--dirac_encoder.py -V
--dirac_encoder.py -C
--dirac_encoder.py [-o out] [-p pre] [-d dir] [-a aspect] [-D delay*]
-- [-q|-v] [-t type] [-k] [-e [[-w dir] [-c geom] [-r geom]]]
-- [-s sndfile*] [-b sndrate*] [-f fpscode] [-L lv1file]
-- [firstframe lastframe]
-- """
--
--help = \
-- """
--SUMMARY (ver. %s):
--
--Encodes a series of PNG or JPG images into a Dirac
--(.drc) stream and is also capable of performing some simple image
--enhacements using ImageMagick. The images and audio are assumed to
--be in an uncompressed LiVES format, hence making this encoder
--more suitable to be used within a LiVES plugin (but can also
--be used directly on a LiVES temporary directory).
--
--OPTIONS:
--
---h for help.
--
---V shows the version number.
--
---C check external program dependencies and exit.
--
---o out will save the video in file "out".
-- Default: "'type'_movie.drc". See below for 'type'.
--
---p pre the encoder assumes that sound and images are named using
-- LiVES' conventions i.e. "audio" and "00000001.ext",
-- "00000002.ext"... where "ext" is either "jpg" or "png".
-- However, dirac_encoder.py will create temporary files
-- which can be saved for later use (for example, after
-- enhancing the images with "-e" , which may take a long
-- time). These temporary files will be named
-- "pre_00000001.ext", etc... where "pre" is either "eimg"
-- or "rimg" and will be kept if the "-k" option is used.
-- dirac_encoder.py can then be run over the enhanced images
-- only by selecting the appropriate prefix ("eimg" or
-- "rimg") here. See "-e" to see what each prefix means.
-- Default: "" (an empty string).
--
---d dir "dir" is the directory containing the source image
-- files. These must be of the form "00000001.ext" or
-- "pre_00000001.ext" as explained above.
-- Default: "."
--
---a aspect sets the aspect ratio of the resulting Dirac file. This can be:
--
-- 1 1:1 display
-- 2 4:3 display
-- 3 16:9 display
-- 4 2.21:1 display
--
-- Default: "2"
--
---D delay* linearly delay the audio stream by "delay" ms.
-- Default: "0"
-- * = NOT IMPLEMENTED (YET?)
--
---q quiet operation, only complains on error.
--
---v be verbose.
--
---t type type of video created. The options here are:
--
-- "hi": a very high quality MPEG-4 file, suitable
-- for archiving images of 720x480.
--
-- "mh": medium-high quality MPEG-4, which still allows
-- to watch small videos (352x240 and below)
-- fullscreen.
--
-- "ml": medium-low quality MPEG-4, suitable for
-- most videos but in particular small videos
-- (352x240 and below) meant for online
-- distribution.
--
-- "lo": a low quality MPEG-4 format. Enlarging
-- small videos will result in noticeable
-- artifacts. Good for distributing over slow
-- connections.
--
-- Default: "ml"
--
---e perform some simple filtering/enhancement to improve image
-- quality. The images created by using this option will be
-- stored in the directory specified by the "-w" option (or
-- "-d" if not present, see above) and each filename will be
-- prefixed with "eimg" (see "-p" above). Using this option will
-- take enormous amounts of disk space, and in reality does
-- not do anything that cannot be done within LiVES itself.
-- Using this option enables the following four:
--
-- -w dir "dir" is the working directory where the enhanced
-- images will be saved. Although these can all
-- co-exist with the original LiVES files it is
-- recommended you use a different directory. Note
-- that temporary files may take a huge amount of
-- space, perhaps twice as much as the LiVES files
-- themselves. If this directory does not exist is
-- will be created.
-- Default: same as "-d".
--
-- -k keep the temporary files, useful to experiment
-- with different encoding types without having
-- to repeatedly enhance the images (which can be
-- very time-consuming). See "-p" above.
--
-- -c geom in addition to enhancing the images, crop them
-- to the specified geometry e.g. "688x448+17+11".
-- Filename prefix remains "eimg". Note that the
-- dimensions of the images should both be multiples
-- of "16", otherwise some players may show artifacts
-- (such as garbage or green bars at the borders).
--
-- -r geom this will create a second set of images resulting
-- from resizing the images that have already been
-- enhanced and possibly cropped (if "-c" has been
-- specified). The geometry here is simple a new
-- image size e.g. "352x240!". This second set will have
-- filenames prefixed with the string "rimg" (see "-p"
-- above). Note that the dimensions of the images
-- should both be multiples of "16", otherwise some
-- players may show artifacts (such as garbage or
-- green bars at the borders).
--
---s sndfile* name of the audio file. Can be either raw "audio" or
-- "[/path/to/]soundfile.wav".
-- Default: "audio" inside "dir" as specified by "-d".
-- * = NOT IMPLEMENTED (YET?)
--
---b sndrate* sample rate of the sound file in Hertz.
-- * = NOT IMPLEMENTED (YET?)
--
---f fpscode frame-rate code. Acceptable values are:
--
-- 1 - 24000.0/1001.0 (NTSC 3:2 pulldown converted FILM)
-- 2 - 24.0 (NATIVE FILM)
-- 3 - 25.0 (PAL/SECAM VIDEO / converted FILM)
-- 4 - 30000.0/1001.0 (NTSC VIDEO)
-- 5 - 30.0
-- 6 - 50.0 (PAL FIELD RATE)
-- 7 - 60000.0/1001.0 (NTSC FIELD RATE)
-- 8 - 60.0
--
-- Default: "4".
--
---L lv1file use the images stored in the LiVES file "lv1file" (e.g.
-- "movie.lv1"). Files will be extracted inside "dir" as
-- specified by "-d". Using this option allows to encode
-- a movie without having to restore it first with LiVES.
-- Note that the encoder will not delete the extracted
-- files after it has finished, this must be done manually
-- afterwards. If frame code/rate (-f) and/or sound rate (-b)
-- are not specified the defaults will be used (30000/1001 fps
-- and 44100 Hz). These, however, may not be correct, in which
-- case they should be specified explicitly. Furthermore, the
-- .lv1 audio (if present) is always assumed to have a sample
-- data size in 16-bit words with two channels, and to be signed
-- linear (this is usually the case, however). If any of these
-- latter parameters are incorrect the resulting file may be
-- corrupted and encoding will have to be done using LiVES.
--
--firstframe first frame number. If less than eight digits long it will
-- be padded with zeroes e.g. 234 -> 00000234. A prefix can
-- be added using the "-p" option.
-- Default: "00000001"
--
--lastframe last frame number, padded with zeroes if necessary, prefix
-- set by "-p".
-- Default: the last frame of its type in the "-d" directory,
-- where "type" is set by the prefix.
--
--Note that either no frames or both first and last frames must be specified.
--
--EXAMPLES:
--
--Suppose you have restored a LiVES' .lv1 file (in either JPG or PNG format),
--and that the images are stored in the directory "/tmp/livestmp/991319584/".
--In this example the movie is assumed to be 16:9. Then, in order to create
--an drc file you can simply do the following:
--
-- dirac_encoder.py -d /tmp/livestmp/991319584 -o /movies/default.drc -a 3
--
--and the clip "default.drc" will be created in "/movies/" with the correct
--aspect ratio.
--
--Suppose we want to make a downloadable version of the clip, small in size
--but of good quality. The following command activates the generic enhancement
--filter and resizes the images to "352x240". Note that these operations
--are performed after cropping the originals a bit (using "704x464+5+6").
--This is done because we are assuming that there is a black border around
--the original pictures which we want to get rid of (this might distort the
--images somewhat, so be careful about cropping/resizing, and remember to
--use dimensions which are multiples of 16):
--
-- dirac_encoder.py -v -d /tmp/livestmp/991319584 -w /tmp/tmpdrc \\
-- -o /movies/download.drc -a 3 -k -e -c "704x464+5+6" -r "352x240"
--
--Since we use the "-k" flag the enhanced images are kept (both full-size
--crops and the resized ones) in "/tmp/tmpdrc". Beware that this may consume
--a lot of disk space (about 10x as much as the originals). The reason we
--keep them is because the above may take quite a long time and we may want
--to re-use the enhanced images. So, for example, creating a high-quality
--clip at full size can be accomplished now as follows:
--
-- dirac_encoder.py -d /tmp/tmpdrc -t hi -o /movies/archive.drc \\
-- -s /tmp/livestmp/991319584/audio -a 3 -k -p eimg
--
--If, for example, we only want to encode frames 100 to 150 we can run
--the following:
--
-- dirac_encoder.py -v -d /tmp/tmpdrc -o /movies/selection.drc \\
-- -a 3 -k -p eimg 100 150
--
--Note that no audio has been selected ("-s"). This is because
--dirac_encoder.py cannot trim the audio to the appropriate length.
--You would need to use LiVES to do this.
--
--To delete all the enhanced images you can just remove "/tmp/tmpdrc".
--
--If you notice that the video and audio become out of sync so that
--near the end of the movie the video trails the audio by, say, 0.2s,
--you can use the "-D" option as follows:
--
-- dirac_encoder.py -d /tmp/livestmp/991319584 -o test.drc -D 200
--
--Note that negative time values are also allowed.
--
--Suppose that you have "movie1.lv1", "movie2.lv1" and "movie3.lv1".
--Batch-encoding can be done as follows (zsh-syntax):
--
-- for i in movie?.lv1
-- do
-- mkdir /tmp/$i:r
-- dirac_encoder.py -d /tmp/$i:r -o /tmp/$i:r.drc -L $i
-- rm -rf /tmp/$i:r
-- done
--
--This will generate the files "movie1.drc", "movie2.drc" and
--"movie3.drc" in "/tmp". Note that is is not necessary to
--specify whether the files are stored in JPG or PNG format,
--and that potentially time-consuming options (e.g. "-e") may
--be enabled. It is not necessary to have a working LiVES
--installation to encode .lv1 files.
-- """ % version
--
--def gcd(a, b):
-- """
-- gcd(a, b) (a,b are integers)
-- Returns the greatest common divisor of two integers.
-- """
-- if b == 0: return a
-- else: return gcd(b, a%b)
--
--
--def run(command):
-- """
-- Run a shell command
-- """
--
-- if verbose:
-- print 'Running: \n' + command + '\n=== ... ==='
-- std = ''
-- else:
-- std = ' > /dev/null 2>&1'
--
-- os.system(command + std)
--
--
--def do_enhance():
-- """
-- Image cleanup/crop/resize routine. Generic, but seems to work
-- well with anime :)
-- """
--
-- if not quiet:
-- print 'Enhancing images... please wait, this might take long...'
--
-- enh_opts = "-enhance -sharpen '0.0x0.5' -gamma 1.2 -contrast -depth 8"
--
-- if cgeom:
-- docrop = ' '.join(['-crop', "'%s!'" % cgeom])
-- else:
-- docrop = ''
--
-- iframe = first_num
-- while True:
-- # File names are padded with zeroes to 8 characters
-- # (not counting the .ext).
-- frame = str(iframe).zfill(8)
-- fname = os.path.join(img_dir, frame + ext)
-- if not os.path.isfile(fname) or (iframe == last_num + 1):
-- break
-- eimg_fname = os.path.join(work_dir, 'eimg' + frame + '.png')
-- rimg_fname = os.path.join(work_dir, 'rimg' + frame + '.png')
-- command = ' '.join([convert, docrop, enh_opts, fname, eimg_fname])
-- run(command)
-- if rgeom:
-- if os.path.exists(rimg_fname): os.remove(rimg_fname)
-- shrink = ' '.join([convert, '-resize', "'%s!'" % rgeom, '-depth 8'])
-- command = ' '.join([shrink, eimg_fname, rimg_fname])
-- run(command)
-- else:
-- if os.path.exists(rimg_fname): os.remove(rimg_fname)
-- try:
-- os.symlink(eimg_fname, rimg_fname)
-- except (IOError, OSError):
-- shutil.copy(eimg_fname, rimg_fname)
-- iframe+=1
--
--
--def do_encode():
-- """
-- Encode a series of images into a Dirac stream.
-- """
--
-- if verbose:
-- std = ''
-- be_verbose = '-verbose'
-- else:
-- std = ' > /dev/null 2>&1'
-- be_verbose = ''
--
-- fpsnum = fps.split('/')[0]
-- fpsden = fps.split('/')[1]
-- ffps = eval('float('+fpsnum+')/'+fpsden)
-- mencoder_opts = '-mf type=%s:fps=%s ' % (ext[1:], ffps) + \
-- '-nosound -vf hqdn3d=2:1:3,pp=va:128:8/ha:128:8/dr,' + \
-- 'dsize=%s,format=i420 -ovc raw -of rawvideo -o ' % aspect
-- dirac_opts = '-HD1080'
-- if vtype == 'hi':
-- dirac_opts = ' '.join([dirac_opts, '-qf 10'])
-- oggenc_opts = '-q 9'
-- elif vtype == 'mh':
-- dirac_opts = ' '.join([dirac_opts, '-qf 8'])
-- oggenc_opts = '-q 8'
-- elif vtype == 'ml':
-- dirac_opts = ' '.join([dirac_opts, '-qf 6'])
-- oggenc_opts = '-q 6'
-- elif vtype == 'lo':
-- dirac_opts = ' '.join([dirac_opts, '-qf 4'])
-- oggenc_opts = '-q 4'
--
--
-- if img_dir != work_dir and not enhance:
-- source_dir = img_dir
-- else:
-- source_dir = work_dir
-- yuvv = os.path.join(source_dir, 'TMP_YUVstream.yuv')
-- yuvvne = yuvv[:-4]
-- dyuvv = tempfile.mkstemp('', '', work_dir)[1]
--
-- if frame_range:
-- numframes = str(last_num - first_num + 1)
-- frame_list = [img_pre + str(f).zfill(8) + ext \
-- for f in range(first_num, last_num + 1)]
-- syml = 'temporary_symlink_'
-- for iframe in frame_list:
-- frfile = os.path.join(source_dir, iframe)
-- frlink = os.path.join(source_dir, syml + iframe)
-- if os.path.islink(frlink): os.remove(frlink)
-- os.symlink(frfile, frlink)
-- else:
-- syml = ''
-- numframes = len(glob.glob(os.path.join(source_dir, \
-- img_pre + '*' + ext)))
--
-- fgeom = os.popen(' '.join([identify, '-format "%w %h"', \
-- os.path.join(source_dir, \
-- img_pre + first_frame_num + ext)])).read().strip().split()
-- fx = int(fgeom[0])
-- fy = int(fgeom[1])
-- # Why 1.5? See http://sourceforge.net/forum/forum.php?thread_id=1143416&forum_id=353618
-- fbytes = int(fx*fy*1.5)
--
-- all_vars = {}
-- all_vars.update(globals())
-- all_vars.update(locals())
--
-- if not quiet:
-- print 'Creating "%s"-quality Dirac file' % vtype
--
-- yuvcommand = """cd %(source_dir)s ; \\
--%(mencoder)s mf://%(syml)s%(img_pre)s*%(ext)s %(mencoder_opts)s%(yuvv)s %(std)s
-- """ % all_vars
-- run(yuvcommand)
-- command = """cd %(source_dir)s ; \\
--%(dirac_encoder)s -width %(fx)s -height %(fy)s -fr %(ffps)s %(be_verbose)s %(dirac_opts)s %(yuvvne)s %(dyuvv)s %(std)s
--""" % all_vars
-- run(command)
-- os.remove(yuvv)
--
-- for tfile in [dyuvv, dyuvv + '.yuv', dyuvv + '.imt']:
-- if os.path.exists(tfile):
-- if verbose:
-- print 'Removing ' + tfile
-- os.remove(tfile)
--
--# Audio not supported yet. Planned to use Matroska container but
--# Dirac developers are thinking of MXF.
-- audio = False
-- if audio:
-- if not quiet:
-- print 'Creating "%s"-quality ogg vorbis file' % vtype
--
-- ogg = tempfile.mkstemp('.ogg', '', work_dir)[1]
-- if rawsndf:
-- wav = tempfile.mkstemp('.wav', '', work_dir)[1]
-- sox_opts = '-t raw -r %s -w -c 2 -s' % sndr
-- command = ' '.join([sox, sox_opts, sndf, wav])
-- run(command)
-- else:
-- wav = sndf
-- command = ' '.join([oggenc, oggenc_opts, wav, '-o', ogg, std])
-- run(command)
--
-- if delay != '0':
-- totfr = len(glob.glob(os.path.join(source_dir, syml + img_pre + '*' + ext)))
-- # "delay" is in ms, transform into s
-- totfrshift = int(totfr + round((locale.atof(delay)/1000.0)*locale.atof(ffps)))
-- delaysh = ',%s/%s' % (totfrshift, totfr)
-- else:
-- delaysh = ''
--
-- all_vars.update(locals())
--
-- if not quiet:
-- print 'Multiplexing...'
-- command = """
--%(mkvplex)s --aspect-ratio '1:%(aspect)s' -o "%(vidname)s" %(vidv)s -y '0:0%(delaysh)s' %(ogg)s %(std)s""" % all_vars
-- run(command)
-- if rawsndf and os.path.exists(wav): os.remove(wav)
-- if os.path.exists(ogg): os.remove(ogg)
-- if os.path.exists(dyuvv + '.drc'): os.remove(dyuvv + '.drc')
-- else:
-- shutil.move(dyuvv + '.drc', vidname)
-- note = """
--You can play the Dirac file %(vidname)s by running:
--
--dirac_decoder -v %(vidname)s %(vidname)s
--mplayer -demuxer rawvideo -rawvideo fps=%(ffps)s:size=%(fbytes)s:w=%(fx)s:h=%(fy)s %(vidname)s.yuv
--
--If %(vidname)s has an extension do not include it in the above
--commands e.g. if it's "test.drc" then do:
--
--dirac_decoder -v test test
--mplayer -demuxer rawvideo -rawvideo fps=%(ffps)s:size=%(fbytes)s:w=%(fx)s:h=%(fy)s test.yuv
--""" % all_vars
-- if not quiet: print note
--
-- if frame_range:
-- lframes = os.path.join(source_dir, syml)
-- for frame in glob.glob(lframes + '*'):
-- os.remove(frame)
--
--
--def do_clean():
-- """
-- Delete enhanced files
-- """
--
-- if not quiet:
-- print 'Deleting all enhanced images (if any)'
--
-- eframes = os.path.join(work_dir, 'eimg')
-- rframes = os.path.join(work_dir, 'rimg')
-- for frame in glob.glob(eframes + '*'):
-- os.remove(frame)
-- for frame in glob.glob(rframes + '*'):
-- os.remove(frame)
--
--
--def which(command):
-- """
-- Finds (or not) a command a la "which"
-- """
--
-- command_found = False
--
-- if command[0] == '/':
-- if os.path.isfile(command) and \
-- os.access(command, os.X_OK):
-- command_found = True
-- abs_command = command
-- else:
-- path = os.environ.get('PATH', '').split(os.pathsep)
-- for dir in path:
-- abs_command = os.path.join(dir, command)
-- if os.path.isfile(abs_command) and \
-- os.access(abs_command, os.X_OK):
-- command_found = True
-- break
--
-- if not command_found:
-- abs_command = ''
--
-- return abs_command
--
--
--def is_installed(prog):
-- """
-- See whether "prog" is installed
-- """
--
-- wprog = which(prog)
--
-- if wprog == '':
-- print prog + ': command not found'
-- raise SystemExit
-- else:
-- if verbose:
-- print wprog + ': found'
--
--
--if __name__ == '__main__':
--
-- import os
-- import sys
-- import getopt
-- import shutil
-- import tempfile
-- import glob
-- import tarfile
--
-- try:
-- if sys.version_info[0:3] < (2, 3, 0):
-- raise SystemExit
-- except:
-- print 'You need Python 2.3.0 or greater to run me!'
-- raise SystemExit
--
-- try:
-- (opts, args) = getopt.getopt(sys.argv[1:], \
-- 'ho:p:d:w:a:qvt:ekc:r:s:b:f:VCD:L:')
-- except:
-- print "Something's wrong. Try the '-h' flag."
-- raise SystemExit
--
-- opts = dict(opts)
--
-- if not opts and not args:
-- print usage
-- raise SystemExit
--
-- if '-h' in opts:
-- print usage + help
-- raise SystemExit
--
-- if '-V' in opts:
-- print 'dirac_encoder.py version ' + version
-- raise SystemExit
--
-- if ('-v' in opts) or ('-C' in opts):
-- verbose = True
-- else:
-- verbose = False
--
-- if '-q' in opts:
-- quiet = True
-- verbose = False
-- else:
-- quiet = False
--
-- for i in [convert, mencoder, dirac_encoder, identify]:
-- is_installed(i)
-- if '-C' in opts: raise SystemExit
--
-- img_pre = opts.get('-p', '')
--
-- if img_pre not in ['', 'eimg', 'rimg']:
-- print 'Improper image name prefix.'
-- raise SystemExit
--
-- temp_dir = ''
-- img_dir = opts.get('-d', '.')
-- img_dir = os.path.abspath(img_dir)
-- if ' ' in img_dir:
-- temp_dir = tempfile.mkdtemp('', '.lives-', '/tmp/')
-- os.symlink(img_dir, temp_dir + '/img_dir')
-- img_dir = temp_dir + '/img_dir'
--
-- if not os.path.isdir(img_dir):
-- print 'The image source directory: ' + img_dir + \
-- ' does not exist!'
-- raise SystemExit
--
-- if len(args) not in [0, 2]:
-- print 'If frames are specified both first and last ' + \
-- 'image numbers must be chosen.'
-- raise SystemExit
-- elif len(args) == 0:
-- args = [None, None]
--
-- frame_range = False
-- if not args[0]:
-- first_frame_num = '1'
-- else:
-- frame_range = True
-- first_frame_num = args[0]
-- first_frame_num = first_frame_num.zfill(8)
-- first_num = int(first_frame_num)
--
-- if not args[1]:
-- last_frame_num = '99999999'
-- else:
-- last_frame_num = args[1]
-- last_frame_num = last_frame_num.zfill(8)
-- last_num = int(last_frame_num)
--
-- aspectc = opts.get('-a', '2')
--
-- if aspectc not in [str(i) for i in xrange(1,5)]:
-- print 'Invalid aspect ratio.'
-- raise SystemExit
-- else:
-- if aspectc == '1': aspect = '1:1'
-- elif aspectc == '2': aspect = '4:3'
-- elif aspectc == '3': aspect = '16:9'
-- elif aspectc == '4': aspect = '2.21:1'
--
-- vtype = opts.get('-t', 'ml')
--
-- if vtype not in ['hi', 'mh', 'ml', 'lo']:
-- print 'Invalid video type.'
-- raise SystemExit
--
-- out_drc = opts.get('-o', vtype + '_movie.drc')
--
-- fpsc = opts.get('-f', '4')
--
-- if fpsc not in [str(i) for i in xrange(1,9)]:
-- if not quiet: print 'Invalid fps code, attempting float fps.'
-- foundfps = False
-- else:
-- if fpsc == '1': fps = '24000/1001'
-- elif fpsc == '2': fps = '24/1'
-- elif fpsc == '3': fps = '25/1'
-- elif fpsc == '4': fps = '30000/1001'
-- elif fpsc == '5': fps = '30/1'
-- elif fpsc == '6': fps = '50/1'
-- elif fpsc == '7': fps = '60000/1001'
-- elif fpsc == '8': fps = '60/1'
-- foundfps = True
--
-- if not foundfps:
-- try:
-- fpsnum = int(locale.atof(fpsc)*10**15)
-- fpsden = 10**15
-- divisor = gcd(fpsnum, fpsden)
-- if divisor > 1:
-- fpsnum = fpsnum/divisor
-- fpsden = fpsden/divisor
-- fps = '%s/%s' % (fpsnum, fpsden)
-- if not quiet: print 'Using fps = ' + fps
-- if fpsnum > 0: foundfps = True
-- except:
-- pass
--
-- if not foundfps:
-- print 'Invalid fps code or rate.'
-- raise SystemExit
--
-- if '-e' not in opts:
-- enhance = False
-- else:
-- enhance = True
--
-- if enhance and img_pre:
-- print 'Sorry, you cannot enhance already-enhanced images'
-- raise SystemExit
--
-- if '-k' not in opts:
-- keep = False
-- else:
-- keep = True
--
-- cgeom = opts.get('-c', '')
-- rgeom = opts.get('-r', '')
--
-- if (cgeom or rgeom) and not enhance:
-- print 'Missing "-e" option.'
-- raise SystemExit
--
-- delay = opts.get('-D', '0')
-- if verbose: print 'Linear audio delay (ms): ' + delay
--
-- lv1file = opts.get('-L', None)
-- if lv1file:
-- if not quiet: print 'Opening lv1 file...'
-- try:
-- lv1 = tarfile.open(os.path.abspath(lv1file))
-- except:
-- print 'This does not appear to be a valid LiVES file!'
-- raise SystemExit
-- if 'header.tar' not in lv1.getnames():
-- print 'This does not appear to be a valid LiVES file!'
-- raise SystemExit
-- for tfile in lv1.getmembers():
-- lv1.extract(tfile, img_dir)
-- for tfile in glob.glob(os.path.join(img_dir, '*.tar')):
-- imgtar = tarfile.open(tfile)
-- for img in imgtar.getmembers():
-- imgtar.extract(img, img_dir)
-- os.remove(tfile)
--
-- test_file = os.path.join(img_dir, img_pre + first_frame_num)
-- if os.path.isfile(test_file + '.jpg'):
-- ext = '.jpg'
-- elif os.path.isfile(test_file + '.png'):
-- ext = '.png'
-- else:
-- print 'Cannot find any appropriate %s or %s files!' % ('.jpg','.png')
-- raise SystemExit
-- first_frame = test_file + ext
-- last_frame = os.path.join(img_dir, img_pre + last_frame_num + ext)
--
-- if not quiet: print 'Found: ' + first_frame
--
-- work_dir = opts.get('-w', img_dir)
-- work_dir = os.path.abspath(work_dir)
-- if not os.path.isdir(work_dir):
-- if not quiet: print 'Creating ' + work_dir
-- try:
-- os.makedirs(work_dir)
-- os.chmod(work_dir, 0755)
-- except:
-- print 'Could not create the work directory ' + \
-- work_dir
-- raise SystemExit
-- if ' ' in work_dir:
-- if temp_dir == '':
-- temp_dir = tempfile.mkdtemp('', '.lives-', '/tmp/')
-- os.symlink(work_dir, temp_dir + '/work_dir')
-- work_dir = temp_dir + '/work_dir'
--
-- sndf = opts.get('-s', os.path.join(img_dir, 'audio'))
--# sndf = os.path.abspath(sndf)
-- rawsndf = True
-- if not os.path.isfile(sndf):
-- audio = False
-- rawsndf = False
-- else:
-- audio = True
-- if sndf[-4:] == '.wav':
-- rawsndf = False
-- if not quiet: print 'Found audio file: ' + sndf
--
-- sndr = opts.get('-b', '44100')
--
-- if enhance:
-- do_enhance()
-- # Note that do_enhance() always creates images prefixed
-- # with 'rimg'. What's important to note if that if the
-- # images are resized the 'rimg' are indeed resized, but
-- # if not the 'rimg' are simply symlinks to (or copies of) the 'eimg'
-- # (enhanced) images.
-- img_pre = 'rimg'
-- ext = '.png'
-- vidname = os.path.join(work_dir, out_drc)
-- # do_encode() acts on images prefixed by img_pre.
-- do_encode()
-- if not keep:
-- do_clean()
-- if temp_dir != '':
-- shutil.rmtree(temp_dir)
-- if not quiet: print "Done!"
--
--
--"""
--CHANGELOG:
--
--18 Sep 2004 : 0.0.a1 : first alpha release.
--23 Sep 2004 : 0.0.a2 : renamed from "mkvd_encoder" ro
-- "dirac_encoder".
-- use mplayer to create yuv.
--25 Sep 2004 : 0.0.a3 : updated docs.
--27 Sep 2004 : 0.0.a5 : switched back to RGBtoYUV420.
-- YUV generation now reliable but
-- still very inefficient.
--27 Sep 2004 : 0.0.a6 : can handle arbitrary fps values.
--08 Nov 2004 : 0.0.a7 : make sure that the enhanced
-- color depth is 8-bits/channel.
--02 Jan 2005 : 0.0.a8 : updated docs.
-- added sound rate (-b) option (unused for now).
--24 Feb 2005 : 0.0.a9 : fixed frame rate calculation.
--26 Mar 2005 : 0.0.a10 : use env python (hopefully >= 2.3).
-- replace denoise3d with hqdn3d.
--12 Jun 2005 : 0.0.a11 : updated to use Dirac version 0.5.2.
--24 Aug 2005 : 0.0.a12 : Fixed 2.21:1 aspect ratio.
--09 Mar 2006 : 0.0.a13 : added '-depth 8' to resize, as ImageMagick
-- keeps changing its damn behaviour.
--13 Mar 2006 : 0.0.a14 : more efficient YUV generation.
-- updated playback explanation.
--28 Jun 2007 : 0.1.a15 : handles paths with spaces appropriately
-- (thanks Gabriel).
--"""
---- /dev/null
-+++ lives/lives-plugins/marcos-encoders/gif_encoder
-@@ -0,0 +1,651 @@
-+#!/usr/bin/env python
-+
-+"""
-+gif_encoder.py
-+
-+Front-end to various programs needed to create GIF
-+movies with some image-enhancing capabilities through the use of
-+ImageMagick. Meant as a companion to LiVES (to possibly call
-+from within a plugin, see http://www.xs4all.nl/~salsaman/lives/ )
-+but can also be used as a stand-alone program.
-+
-+Requires ImageMagick (GraphicsMagick might also
-+work) and Python 2.3.0 or greater. Note that audio
-+support is not implemented, only video encoding.
-+Note that encoding and decoding requires huge amounts
-+of memory, and so it's mostly meant for very short
-+clips (e.g. animated web graphics). The resulting
-+clips can be viewed using the "animate" command which is
-+part of ImageMagick, or a graphical web browser.
-+
-+Copyright (C) 2004-2005 Marco De la Cruz (marco at reimeika.ca)
-+It's a trivial program, but might as well GPL it, so see:
-+http://www.gnu.org/copyleft/gpl.html for license.
-+
-+See my vids at http://amv.reimeika.ca !
-+"""
-+
-+version = '0.0.6'
-+convert = 'convert'
-+
-+usage = \
-+ """
-+gif_encoder.py -h
-+gif_encoder.py -V
-+gif_encoder.py -C
-+gif_encoder.py [-o out] [-p pre] [-d dir] [-a aspect*] [-D delay*]
-+ [-q|-v] [-t type*] [-k] [-e [[-w dir] [-c geom] [-r geom]]]
-+ [-s sndfile*] [-b sndrate*] [-f fpscode] [-L lv1file]
-+ [firstframe lastframe]
-+ """
-+
-+help = \
-+ """
-+SUMMARY (ver. %s):
-+
-+Encodes a series of PNG or JPG images into an animated GIF
-+(.gif) and is also capable of performing some simple image
-+enhacements using ImageMagick. The images and audio are assumed to
-+be in an uncompressed LiVES format, hence making this encoder
-+more suitable to be used within a LiVES plugin (but can also
-+be used directly on a LiVES temporary directory).
-+
-+OPTIONS:
-+
-+-h for help.
-+
-+-V shows the version number.
-+
-+-C check external program dependencies and exit.
-+
-+-o out will save the video in file "out".
-+ Default: "gif_movie.gif".
-+
-+-p pre the encoder assumes that sound and images are named using
-+ LiVES' conventions i.e. "audio" and "00000001.ext",
-+ "00000002.ext"... where "ext" is either "jpg" or "png".
-+ However, gif_encoder.py will create temporary files
-+ which can be saved for later use (for example, after
-+ enhancing the images with "-e" , which may take a long
-+ time). These temporary files will be named
-+ "pre_00000001.ext", etc... where "pre" is either "eimg"
-+ or "rimg" and will be kept if the "-k" option is used.
-+ gif_encoder.py can then be run over the enhanced images
-+ only by selecting the appropriate prefix ("eimg" or
-+ "rimg") here. See "-e" to see what each prefix means.
-+ Default: "" (an empty string).
-+
-+-d dir "dir" is the directory containing the source image
-+ files. These must be of the form "00000001.ext" or
-+ "pre_00000001.ext" as explained above.
-+ Default: "."
-+
-+-a aspect* sets the aspect ratio of the resulting movie.
-+ * = NOT IMPLEMENTED
-+
-+-D delay* linearly delay the audio stream by "delay" ms.
-+ * = NOT IMPLEMENTED
-+
-+-q quiet operation, only complains on error.
-+
-+-v be verbose.
-+
-+-t type* type of video created.
-+ * = NOT IMPLEMENTED
-+
-+-e perform some simple filtering/enhancement to improve image
-+ quality. The images created by using this option will be
-+ stored in the directory specified by the "-w" option (or
-+ "-d" if not present, see above) and each filename will be
-+ prefixed with "eimg" (see "-p" above). Using this option will
-+ take enormous amounts of disk space, and in reality does
-+ not do anything that cannot be done within LiVES itself.
-+ Using this option enables the following four:
-+
-+ -w dir "dir" is the working directory where the enhanced
-+ images will be saved. Although these can all
-+ co-exist with the original LiVES files it is
-+ recommended you use a different directory. Note
-+ that temporary files may take a huge amount of
-+ space, perhaps twice as much as the LiVES files
-+ themselves. If this directory does not exist is
-+ will be created.
-+ Default: same as "-d".
-+
-+ -k keep the temporary files, useful to experiment
-+ with different encoding types without having
-+ to repeatedly enhance the images (which can be
-+ very time-consuming). See "-p" above.
-+
-+ -c geom in addition to enhancing the images, crop them
-+ to the specified geometry e.g. "688x448+17+11".
-+ Filename prefix remains "eimg".
-+
-+ -r geom this will create a second set of images resulting
-+ from resizing the images that have already been
-+ enhanced and possibly cropped (if "-c" has been
-+ specified). The geometry here is simple a new
-+ image size e.g. "352x240!". This second set will have
-+ filenames prefixed with the string "rimg" (see "-p"
-+ above).
-+
-+-s sndfile* name of the audio file.
-+ * = NOT IMPLEMENTED
-+
-+-b sndrate* sample rate of the sound file in Hertz.
-+ * = NOT IMPLEMENTED
-+
-+-f fpscode frame-rate code. Acceptable values are:
-+
-+ 1 - 24000.0/1001.0 (NTSC 3:2 pulldown converted FILM)
-+ 2 - 24.0 (NATIVE FILM)
-+ 3 - 25.0 (PAL/SECAM VIDEO / converted FILM)
-+ 4 - 30000.0/1001.0 (NTSC VIDEO)
-+ 5 - 30.0
-+ 6 - 50.0 (PAL FIELD RATE)
-+ 7 - 60000.0/1001.0 (NTSC FIELD RATE)
-+ 8 - 60.0
-+
-+ If the input value is a float (e.g. 5.0, 14.555, etc.)
-+ the encoder will use that as frame rate.
-+
-+ Default: "4".
-+
-+-L lv1file use the images stored in the LiVES file "lv1file" (e.g.
-+ "movie.lv1"). Files will be extracted inside "dir" as
-+ specified by "-d". Using this option allows to encode
-+ a movie without having to restore it first with LiVES.
-+ Note that the encoder will not delete the extracted
-+ files after it has finished, this must be done manually
-+ afterwards. If frame code/rate (-f) and/or sound rate (-b)
-+ are not specified the defaults will be used (30000/1001 fps
-+ and 44100 Hz). These, however, may not be correct, in which
-+ case they should be specified explicitly. Furthermore, the
-+ .lv1 audio (if present) is always assumed to have a sample
-+ data size in 16-bit words with two channels, and to be signed
-+ linear (this is usually the case, however). If any of these
-+ latter parameters are incorrect the resulting file may be
-+ corrupted and encoding will have to be done using LiVES.
-+
-+firstframe first frame number. If less than eight digits long it will
-+ be padded with zeroes e.g. 234 -> 00000234. A prefix can
-+ be added using the "-p" option.
-+ Default: "00000001"
-+
-+lastframe last frame number, padded with zeroes if necessary, prefix
-+ set by "-p".
-+ Default: the last frame of its type in the "-d" directory,
-+ where "type" is set by the prefix.
-+
-+Note that either no frames or both first and last frames must be specified.
-+
-+EXAMPLES:
-+
-+Suppose you have restored a LiVES' .lv1 file (in either JPG or PNG format),
-+and that the images are stored in the directory "/tmp/livestmp/991319584/".
-+Then, in order to create an gif file you can simply do the following:
-+
-+ gif_encoder.py -d /tmp/livestmp/991319584 -o /movies/default.gif
-+
-+and the clip "default.gif" will be created in "/movies/".
-+
-+Suppose we want to make a downloadable version of the clip, small in size
-+but of good quality. The following command activates the generic enhancement
-+filter and resizes the images to "352x240". Note that these operations
-+are performed after cropping the originals a bit (using "704x464+5+6").
-+This is done because we are assuming that there is a black border around
-+the original pictures which we want to get rid of (this might distort the
-+images somewhat, so be careful about cropping/resizing):
-+
-+ gif_encoder.py -v -d /tmp/livestmp/991319584 -w /tmp/tmpgif \\
-+ -o /movies/download.gif -k -e -c "704x464+5+6" -r "352x240"
-+
-+Since we use the "-k" flag the enhanced images are kept (both full-size
-+crops and the resized ones) in "/tmp/tmpgif". Beware that this may consume
-+a lot of disk space (about 10x as much as the originals). The reason we
-+keep them is because the above may take quite a long time and we may want
-+to re-use the enhanced images. So, for example, creating a
-+clip at full size can be accomplished now as follows:
-+
-+ gif_encoder.py -d /tmp/tmpgif -o /movies/archive.gif \\
-+ -s /tmp/livestmp/991319584/audio -k -p eimg
-+
-+If, for example, we only want to encode frames 100 to 150 we can run
-+the following:
-+
-+ gif_encoder.py -v -d /tmp/tmpgif -o /movies/selection.gif \\
-+ -k -p eimg 100 150
-+
-+To delete all the enhanced images you can just remove "/tmp/tmpgif".
-+
-+Suppose that you have "movie1.lv1", "movie2.lv1" and "movie3.lv1".
-+Batch-encoding can be done as follows (zsh-syntax):
-+
-+ for i in movie?.lv1
-+ do
-+ mkdir /tmp/$i:r
-+ gif_encoder.py -d /tmp/$i:r -o /tmp/$i:r.gif -L $i
-+ rm -rf /tmp/$i:r
-+ done
-+
-+This will generate the files "movie1.gif", "movie2.gif" and
-+"movie3.gif" in "/tmp". Note that is is not necessary to
-+specify whether the files are stored in JPG or PNG format,
-+and that potentially time-consuming options (e.g. "-e") may
-+be enabled. It is not necessary to have a working LiVES
-+installation to encode .lv1 files.
-+ """ % version
-+
-+def run(command):
-+ """
-+ Run a shell command
-+ """
-+
-+ if verbose:
-+ print 'Running: \n' + command + '\n=== ... ==='
-+ std = ''
-+ else:
-+ std = ' > /dev/null 2>&1'
-+
-+ os.system(command + std)
-+
-+
-+def do_enhance():
-+ """
-+ Image cleanup/crop/resize routine. Generic, but seems to work
-+ well with anime :)
-+ """
-+
-+ if not quiet:
-+ print 'Enhancing images... please wait, this might take long...'
-+
-+ enh_opts = "-enhance -sharpen '0.0x0.5' -gamma 1.2 -contrast -depth 8"
-+
-+ if cgeom:
-+ docrop = ' '.join(['-crop', "'%s!'" % cgeom])
-+ else:
-+ docrop = ''
-+
-+ iframe = first_num
-+ while True:
-+ # File names are padded with zeroes to 8 characters
-+ # (not counting the .ext).
-+ frame = str(iframe).zfill(8)
-+ fname = os.path.join(img_dir, frame + ext)
-+ if not os.path.isfile(fname) or (iframe == last_num + 1):
-+ break
-+ eimg_fname = os.path.join(work_dir, 'eimg' + frame + '.png')
-+ rimg_fname = os.path.join(work_dir, 'rimg' + frame + '.png')
-+ command = ' '.join([convert, docrop, enh_opts, fname, eimg_fname])
-+ run(command)
-+ if rgeom:
-+ if os.path.exists(rimg_fname): os.remove(rimg_fname)
-+ shrink = ' '.join([convert, '-resize', "'%s!'" % rgeom, '-depth 8'])
-+ command = ' '.join([shrink, eimg_fname, rimg_fname])
-+ run(command)
-+ else:
-+ if os.path.exists(rimg_fname): os.remove(rimg_fname)
-+ try:
-+ os.symlink(eimg_fname, rimg_fname)
-+ except (IOError, OSError):
-+ shutil.copy(eimg_fname, rimg_fname)
-+ iframe+=1
-+
-+
-+def do_encode():
-+ """
-+ Encode a series of images as an GIF file.
-+ """
-+
-+ if verbose:
-+ std = ''
-+ std2 = ''
-+ be_verbose = '-verbose'
-+ else:
-+ std = ' > /dev/null 2>&1'
-+ std2 = ' 2> /dev/null'
-+ be_verbose = ''
-+
-+ if img_dir != work_dir and not enhance:
-+ source_dir = img_dir
-+ else:
-+ source_dir = work_dir
-+
-+ if frame_range:
-+ numframes = str(last_num - first_num + 1)
-+ frame_list = [img_pre + str(f).zfill(8) + ext \
-+ for f in range(first_num, last_num + 1)]
-+ syml = 'temporary_symlink_'
-+ for iframe in frame_list:
-+ frfile = os.path.join(source_dir, iframe)
-+ frlink = os.path.join(source_dir, syml + iframe)
-+ if os.path.islink(frlink): os.remove(frlink)
-+ os.symlink(frfile, frlink)
-+ else:
-+ syml = ''
-+ numframes = len(glob.glob(os.path.join(source_dir, \
-+ img_pre + '*' + ext)))
-+
-+ # Delay between frames is in 100ths of a second
-+ spf = 100*(1/fps)
-+
-+ gifv = tempfile.mkstemp('.gif', '', work_dir)[1]
-+
-+ all_vars = {}
-+ all_vars.update(globals())
-+ all_vars.update(locals())
-+
-+ if not quiet:
-+ print 'Creating GIF file'
-+
-+ command = """cd %(source_dir)s ; \\
-+%(convert)s -delay %(spf)s %(syml)s%(img_pre)s*%(ext)s %(gifv)s
-+""" % all_vars
-+ run(command)
-+
-+ shutil.move(gifv, vidname)
-+
-+ if frame_range:
-+ lframes = os.path.join(source_dir, syml)
-+ for frame in glob.glob(lframes + '*'):
-+ os.remove(frame)
-+
-+
-+def do_clean():
-+ """
-+ Delete enhanced files
-+ """
-+
-+ if not quiet:
-+ print 'Deleting all enhanced images (if any)'
-+
-+ eframes = os.path.join(work_dir, 'eimg')
-+ rframes = os.path.join(work_dir, 'rimg')
-+ for frame in glob.glob(eframes + '*'):
-+ os.remove(frame)
-+ for frame in glob.glob(rframes + '*'):
-+ os.remove(frame)
-+
-+
-+def which(command):
-+ """
-+ Finds (or not) a command a la "which"
-+ """
-+
-+ command_found = False
-+
-+ if command[0] == '/':
-+ if os.path.isfile(command) and \
-+ os.access(command, os.X_OK):
-+ command_found = True
-+ abs_command = command
-+ else:
-+ path = os.environ.get('PATH', '').split(os.pathsep)
-+ for dir in path:
-+ abs_command = os.path.join(dir, command)
-+ if os.path.isfile(abs_command) and \
-+ os.access(abs_command, os.X_OK):
-+ command_found = True
-+ break
-+
-+ if not command_found:
-+ abs_command = ''
-+
-+ return abs_command
-+
-+
-+def is_installed(prog):
-+ """
-+ See whether "prog" is installed
-+ """
-+
-+ wprog = which(prog)
-+
-+ if wprog == '':
-+ print prog + ': command not found'
-+ raise SystemExit
-+ else:
-+ if verbose:
-+ print wprog + ': found'
-+
-+
-+if __name__ == '__main__':
-+
-+ import os
-+ import sys
-+ import getopt
-+ import shutil
-+ import tempfile
-+ import glob
-+ import tarfile
-+
-+ try:
-+ if sys.version_info[0:3] < (2, 3, 0):
-+ raise SystemExit
-+ except:
-+ print 'You need Python 2.3.0 or greater to run me!'
-+ raise SystemExit
-+
-+ try:
-+ (opts, args) = getopt.getopt(sys.argv[1:], \
-+ 'ho:p:d:w:a:qvt:ekc:r:s:b:f:VCD:L:')
-+ except:
-+ print "Something's wrong. Try the '-h' flag."
-+ raise SystemExit
-+
-+ opts = dict(opts)
-+
-+ if not opts and not args:
-+ print usage
-+ raise SystemExit
-+
-+ if '-h' in opts:
-+ print usage + help
-+ raise SystemExit
-+
-+ if '-V' in opts:
-+ print 'gif_encoder.py version ' + version
-+ raise SystemExit
-+
-+ if ('-v' in opts) or ('-C' in opts):
-+ verbose = True
-+ else:
-+ verbose = False
-+
-+ if '-q' in opts:
-+ quiet = True
-+ verbose = False
-+ else:
-+ quiet = False
-+
-+ for i in [convert]:
-+ is_installed(i)
-+ if '-C' in opts: raise SystemExit
-+
-+ img_pre = opts.get('-p', '')
-+
-+ if img_pre not in ['', 'eimg', 'rimg']:
-+ print 'Improper image name prefix.'
-+ raise SystemExit
-+
-+ temp_dir = ''
-+ img_dir = opts.get('-d', '.')
-+ img_dir = os.path.abspath(img_dir)
-+ if ' ' in img_dir:
-+ temp_dir = tempfile.mkdtemp('', '.lives-', '/tmp/')
-+ os.symlink(img_dir, temp_dir + '/img_dir')
-+ img_dir = temp_dir + '/img_dir'
-+
-+ if not os.path.isdir(img_dir):
-+ print 'The image source directory: ' + img_dir + \
-+ ' does not exist!'
-+ raise SystemExit
-+
-+ if len(args) not in [0, 2]:
-+ print 'If frames are specified both first and last ' + \
-+ 'image numbers must be chosen.'
-+ raise SystemExit
-+ elif len(args) == 0:
-+ args = [None, None]
-+
-+ frame_range = False
-+ if not args[0]:
-+ first_frame_num = '1'
-+ else:
-+ frame_range = True
-+ first_frame_num = args[0]
-+ first_frame_num = first_frame_num.zfill(8)
-+ first_num = int(first_frame_num)
-+
-+ if not args[1]:
-+ last_frame_num = '99999999'
-+ else:
-+ last_frame_num = args[1]
-+ last_frame_num = last_frame_num.zfill(8)
-+ last_num = int(last_frame_num)
-+
-+ # Aspect ratio is not used
-+ aspectc = opts.get('-a', '2')
-+
-+ # Video type is not used
-+ vtype = opts.get('-t', 'gif')
-+
-+ out_gif = opts.get('-o', vtype + '_movie.gif')
-+
-+ fpsc = opts.get('-f', '4')
-+
-+ if fpsc not in [str(i) for i in xrange(1,9)]:
-+ if not quiet: print 'Invalid fps code, attempting float fps.'
-+ foundfps = False
-+ else:
-+ if fpsc == '1': fps = 24000.0/1001.0
-+ elif fpsc == '2': fps = 24.0
-+ elif fpsc == '3': fps = 25.0
-+ elif fpsc == '4': fps = 30000.0/1001.0
-+ elif fpsc == '5': fps = 30.0
-+ elif fpsc == '6': fps = 50.0
-+ elif fpsc == '7': fps = 60000.0/1001.0
-+ elif fpsc == '8': fps = 60.0
-+ foundfps = True
-+
-+ if not foundfps:
-+ try:
-+ fps = locale.atof(fpsc)
-+ if not quiet: print 'Using fps = %s' % fps
-+ if fps > 0: foundfps = True
-+ except:
-+ pass
-+
-+ if not foundfps:
-+ print 'Invalid fps code or rate.'
-+ raise SystemExit
-+
-+ if '-e' not in opts:
-+ enhance = False
-+ else:
-+ enhance = True
-+
-+ if enhance and img_pre:
-+ print 'Sorry, you cannot enhance already-enhanced images'
-+ raise SystemExit
-+
-+ if '-k' not in opts:
-+ keep = False
-+ else:
-+ keep = True
-+
-+ cgeom = opts.get('-c', '')
-+ rgeom = opts.get('-r', '')
-+
-+ if (cgeom or rgeom) and not enhance:
-+ print 'Missing "-e" option.'
-+ raise SystemExit
-+
-+ delay = opts.get('-D', '0')
-+ if verbose: print 'Linear audio delay (ms): ' + delay
-+
-+ lv1file = opts.get('-L', None)
-+ if lv1file:
-+ if not quiet: print 'Opening lv1 file...'
-+ try:
-+ lv1 = tarfile.open(os.path.abspath(lv1file))
-+ except:
-+ print 'This does not appear to be a valid LiVES file!'
-+ raise SystemExit
-+ if 'header.tar' not in lv1.getnames():
-+ print 'This does not appear to be a valid LiVES file!'
-+ raise SystemExit
-+ for tfile in lv1.getmembers():
-+ lv1.extract(tfile, img_dir)
-+ for tfile in glob.glob(os.path.join(img_dir, '*.tar')):
-+ imgtar = tarfile.open(tfile)
-+ for img in imgtar.getmembers():
-+ imgtar.extract(img, img_dir)
-+ os.remove(tfile)
-+
-+ test_file = os.path.join(img_dir, img_pre + first_frame_num)
-+ if os.path.isfile(test_file + '.jpg'):
-+ ext = '.jpg'
-+ elif os.path.isfile(test_file + '.png'):
-+ ext = '.png'
-+ else:
-+ print 'Cannot find any appropriate %s or %s files!' % ('.jpg','.png')
-+ raise SystemExit
-+ first_frame = test_file + ext
-+ last_frame = os.path.join(img_dir, img_pre + last_frame_num + ext)
-+
-+ if not quiet: print 'Found: ' + first_frame
-+
-+ work_dir = opts.get('-w', img_dir)
-+ work_dir = os.path.abspath(work_dir)
-+ if not os.path.isdir(work_dir):
-+ if not quiet: print 'Creating ' + work_dir
-+ try:
-+ os.makedirs(work_dir)
-+ os.chmod(work_dir, 0755)
-+ except:
-+ print 'Could not create the work directory ' + \
-+ work_dir
-+ raise SystemExit
-+ if ' ' in work_dir:
-+ if temp_dir == '':
-+ temp_dir = tempfile.mkdtemp('', '.lives-', '/tmp/')
-+ os.symlink(work_dir, temp_dir + '/work_dir')
-+ work_dir = temp_dir + '/work_dir'
-+
-+ # Audio is not used
-+ sndf = opts.get('-s', os.path.join(img_dir, 'audio'))
-+
-+ if enhance:
-+ do_enhance()
-+ # Note that do_enhance() always creates images prefixed
-+ # with 'rimg'. What's important to note if that if the
-+ # images are resized the 'rimg' are indeed resized, but
-+ # if not the 'rimg' are simply symlinks to the 'eimg'
-+ # (enhanced) images.
-+ img_pre = 'rimg'
-+ ext = '.png'
-+ vidname = os.path.join(work_dir, out_gif)
-+ # do_encode() acts on images prefixed by img_pre.
-+ do_encode()
-+ if not keep:
-+ do_clean()
-+ if temp_dir != '':
-+ shutil.rmtree(temp_dir)
-+ if not quiet: print "Done!"
-+
-+
-+"""
-+CHANGELOG:
-+
-+29 Oct 2004 : 0.0.1 : first release.
-+08 Nov 2004 : 0.0.2 : make sure that the enhanced
-+ color depth is 8-bits/channel.
-+02 Jan 2005 : 0.0.3 : updated docs.
-+ added sound rate (-b) option (unused).
-+21 Mar 2005 : 0.0.4 : use env python (hopefully >= 2.3)
-+09 Mar 2006 : 0.0.5 : added '-depth 8' to resize, as ImageMagick
-+ keeps changing its damn behaviour.
-+28 Jun 2007 : 0.0.6 : handles paths with spaces appropriately
-+ (thanks Gabriel).
-+"""
---- lives.orig/lives-plugins/marcos-encoders/gif_encoder.py
-+++ /dev/null
-@@ -1,651 +0,0 @@
--#!/usr/bin/env python
--
--"""
--gif_encoder.py
--
--Front-end to various programs needed to create GIF
--movies with some image-enhancing capabilities through the use of
--ImageMagick. Meant as a companion to LiVES (to possibly call
--from within a plugin, see http://www.xs4all.nl/~salsaman/lives/ )
--but can also be used as a stand-alone program.
--
--Requires ImageMagick (GraphicsMagick might also
--work) and Python 2.3.0 or greater. Note that audio
--support is not implemented, only video encoding.
--Note that encoding and decoding requires huge amounts
--of memory, and so it's mostly meant for very short
--clips (e.g. animated web graphics). The resulting
--clips can be viewed using the "animate" command which is
--part of ImageMagick, or a graphical web browser.
--
--Copyright (C) 2004-2005 Marco De la Cruz (marco at reimeika.ca)
--It's a trivial program, but might as well GPL it, so see:
--http://www.gnu.org/copyleft/gpl.html for license.
--
--See my vids at http://amv.reimeika.ca !
--"""
--
--version = '0.0.6'
--convert = 'convert'
--
--usage = \
-- """
--gif_encoder.py -h
--gif_encoder.py -V
--gif_encoder.py -C
--gif_encoder.py [-o out] [-p pre] [-d dir] [-a aspect*] [-D delay*]
-- [-q|-v] [-t type*] [-k] [-e [[-w dir] [-c geom] [-r geom]]]
-- [-s sndfile*] [-b sndrate*] [-f fpscode] [-L lv1file]
-- [firstframe lastframe]
-- """
--
--help = \
-- """
--SUMMARY (ver. %s):
--
--Encodes a series of PNG or JPG images into an animated GIF
--(.gif) and is also capable of performing some simple image
--enhacements using ImageMagick. The images and audio are assumed to
--be in an uncompressed LiVES format, hence making this encoder
--more suitable to be used within a LiVES plugin (but can also
--be used directly on a LiVES temporary directory).
--
--OPTIONS:
--
---h for help.
--
---V shows the version number.
--
---C check external program dependencies and exit.
--
---o out will save the video in file "out".
-- Default: "gif_movie.gif".
--
---p pre the encoder assumes that sound and images are named using
-- LiVES' conventions i.e. "audio" and "00000001.ext",
-- "00000002.ext"... where "ext" is either "jpg" or "png".
-- However, gif_encoder.py will create temporary files
-- which can be saved for later use (for example, after
-- enhancing the images with "-e" , which may take a long
-- time). These temporary files will be named
-- "pre_00000001.ext", etc... where "pre" is either "eimg"
-- or "rimg" and will be kept if the "-k" option is used.
-- gif_encoder.py can then be run over the enhanced images
-- only by selecting the appropriate prefix ("eimg" or
-- "rimg") here. See "-e" to see what each prefix means.
-- Default: "" (an empty string).
--
---d dir "dir" is the directory containing the source image
-- files. These must be of the form "00000001.ext" or
-- "pre_00000001.ext" as explained above.
-- Default: "."
--
---a aspect* sets the aspect ratio of the resulting movie.
-- * = NOT IMPLEMENTED
--
---D delay* linearly delay the audio stream by "delay" ms.
-- * = NOT IMPLEMENTED
--
---q quiet operation, only complains on error.
--
---v be verbose.
--
---t type* type of video created.
-- * = NOT IMPLEMENTED
--
---e perform some simple filtering/enhancement to improve image
-- quality. The images created by using this option will be
-- stored in the directory specified by the "-w" option (or
-- "-d" if not present, see above) and each filename will be
-- prefixed with "eimg" (see "-p" above). Using this option will
-- take enormous amounts of disk space, and in reality does
-- not do anything that cannot be done within LiVES itself.
-- Using this option enables the following four:
--
-- -w dir "dir" is the working directory where the enhanced
-- images will be saved. Although these can all
-- co-exist with the original LiVES files it is
-- recommended you use a different directory. Note
-- that temporary files may take a huge amount of
-- space, perhaps twice as much as the LiVES files
-- themselves. If this directory does not exist is
-- will be created.
-- Default: same as "-d".
--
-- -k keep the temporary files, useful to experiment
-- with different encoding types without having
-- to repeatedly enhance the images (which can be
-- very time-consuming). See "-p" above.
--
-- -c geom in addition to enhancing the images, crop them
-- to the specified geometry e.g. "688x448+17+11".
-- Filename prefix remains "eimg".
--
-- -r geom this will create a second set of images resulting
-- from resizing the images that have already been
-- enhanced and possibly cropped (if "-c" has been
-- specified). The geometry here is simple a new
-- image size e.g. "352x240!". This second set will have
-- filenames prefixed with the string "rimg" (see "-p"
-- above).
--
---s sndfile* name of the audio file.
-- * = NOT IMPLEMENTED
--
---b sndrate* sample rate of the sound file in Hertz.
-- * = NOT IMPLEMENTED
--
---f fpscode frame-rate code. Acceptable values are:
--
-- 1 - 24000.0/1001.0 (NTSC 3:2 pulldown converted FILM)
-- 2 - 24.0 (NATIVE FILM)
-- 3 - 25.0 (PAL/SECAM VIDEO / converted FILM)
-- 4 - 30000.0/1001.0 (NTSC VIDEO)
-- 5 - 30.0
-- 6 - 50.0 (PAL FIELD RATE)
-- 7 - 60000.0/1001.0 (NTSC FIELD RATE)
-- 8 - 60.0
--
-- If the input value is a float (e.g. 5.0, 14.555, etc.)
-- the encoder will use that as frame rate.
--
-- Default: "4".
--
---L lv1file use the images stored in the LiVES file "lv1file" (e.g.
-- "movie.lv1"). Files will be extracted inside "dir" as
-- specified by "-d". Using this option allows to encode
-- a movie without having to restore it first with LiVES.
-- Note that the encoder will not delete the extracted
-- files after it has finished, this must be done manually
-- afterwards. If frame code/rate (-f) and/or sound rate (-b)
-- are not specified the defaults will be used (30000/1001 fps
-- and 44100 Hz). These, however, may not be correct, in which
-- case they should be specified explicitly. Furthermore, the
-- .lv1 audio (if present) is always assumed to have a sample
-- data size in 16-bit words with two channels, and to be signed
-- linear (this is usually the case, however). If any of these
-- latter parameters are incorrect the resulting file may be
-- corrupted and encoding will have to be done using LiVES.
--
--firstframe first frame number. If less than eight digits long it will
-- be padded with zeroes e.g. 234 -> 00000234. A prefix can
-- be added using the "-p" option.
-- Default: "00000001"
--
--lastframe last frame number, padded with zeroes if necessary, prefix
-- set by "-p".
-- Default: the last frame of its type in the "-d" directory,
-- where "type" is set by the prefix.
--
--Note that either no frames or both first and last frames must be specified.
--
--EXAMPLES:
--
--Suppose you have restored a LiVES' .lv1 file (in either JPG or PNG format),
--and that the images are stored in the directory "/tmp/livestmp/991319584/".
--Then, in order to create an gif file you can simply do the following:
--
-- gif_encoder.py -d /tmp/livestmp/991319584 -o /movies/default.gif
--
--and the clip "default.gif" will be created in "/movies/".
--
--Suppose we want to make a downloadable version of the clip, small in size
--but of good quality. The following command activates the generic enhancement
--filter and resizes the images to "352x240". Note that these operations
--are performed after cropping the originals a bit (using "704x464+5+6").
--This is done because we are assuming that there is a black border around
--the original pictures which we want to get rid of (this might distort the
--images somewhat, so be careful about cropping/resizing):
--
-- gif_encoder.py -v -d /tmp/livestmp/991319584 -w /tmp/tmpgif \\
-- -o /movies/download.gif -k -e -c "704x464+5+6" -r "352x240"
--
--Since we use the "-k" flag the enhanced images are kept (both full-size
--crops and the resized ones) in "/tmp/tmpgif". Beware that this may consume
--a lot of disk space (about 10x as much as the originals). The reason we
--keep them is because the above may take quite a long time and we may want
--to re-use the enhanced images. So, for example, creating a
--clip at full size can be accomplished now as follows:
--
-- gif_encoder.py -d /tmp/tmpgif -o /movies/archive.gif \\
-- -s /tmp/livestmp/991319584/audio -k -p eimg
--
--If, for example, we only want to encode frames 100 to 150 we can run
--the following:
--
-- gif_encoder.py -v -d /tmp/tmpgif -o /movies/selection.gif \\
-- -k -p eimg 100 150
--
--To delete all the enhanced images you can just remove "/tmp/tmpgif".
--
--Suppose that you have "movie1.lv1", "movie2.lv1" and "movie3.lv1".
--Batch-encoding can be done as follows (zsh-syntax):
--
-- for i in movie?.lv1
-- do
-- mkdir /tmp/$i:r
-- gif_encoder.py -d /tmp/$i:r -o /tmp/$i:r.gif -L $i
-- rm -rf /tmp/$i:r
-- done
--
--This will generate the files "movie1.gif", "movie2.gif" and
--"movie3.gif" in "/tmp". Note that is is not necessary to
--specify whether the files are stored in JPG or PNG format,
--and that potentially time-consuming options (e.g. "-e") may
--be enabled. It is not necessary to have a working LiVES
--installation to encode .lv1 files.
-- """ % version
--
--def run(command):
-- """
-- Run a shell command
-- """
--
-- if verbose:
-- print 'Running: \n' + command + '\n=== ... ==='
-- std = ''
-- else:
-- std = ' > /dev/null 2>&1'
--
-- os.system(command + std)
--
--
--def do_enhance():
-- """
-- Image cleanup/crop/resize routine. Generic, but seems to work
-- well with anime :)
-- """
--
-- if not quiet:
-- print 'Enhancing images... please wait, this might take long...'
--
-- enh_opts = "-enhance -sharpen '0.0x0.5' -gamma 1.2 -contrast -depth 8"
--
-- if cgeom:
-- docrop = ' '.join(['-crop', "'%s!'" % cgeom])
-- else:
-- docrop = ''
--
-- iframe = first_num
-- while True:
-- # File names are padded with zeroes to 8 characters
-- # (not counting the .ext).
-- frame = str(iframe).zfill(8)
-- fname = os.path.join(img_dir, frame + ext)
-- if not os.path.isfile(fname) or (iframe == last_num + 1):
-- break
-- eimg_fname = os.path.join(work_dir, 'eimg' + frame + '.png')
-- rimg_fname = os.path.join(work_dir, 'rimg' + frame + '.png')
-- command = ' '.join([convert, docrop, enh_opts, fname, eimg_fname])
-- run(command)
-- if rgeom:
-- if os.path.exists(rimg_fname): os.remove(rimg_fname)
-- shrink = ' '.join([convert, '-resize', "'%s!'" % rgeom, '-depth 8'])
-- command = ' '.join([shrink, eimg_fname, rimg_fname])
-- run(command)
-- else:
-- if os.path.exists(rimg_fname): os.remove(rimg_fname)
-- try:
-- os.symlink(eimg_fname, rimg_fname)
-- except (IOError, OSError):
-- shutil.copy(eimg_fname, rimg_fname)
-- iframe+=1
--
--
--def do_encode():
-- """
-- Encode a series of images as an GIF file.
-- """
--
-- if verbose:
-- std = ''
-- std2 = ''
-- be_verbose = '-verbose'
-- else:
-- std = ' > /dev/null 2>&1'
-- std2 = ' 2> /dev/null'
-- be_verbose = ''
--
-- if img_dir != work_dir and not enhance:
-- source_dir = img_dir
-- else:
-- source_dir = work_dir
--
-- if frame_range:
-- numframes = str(last_num - first_num + 1)
-- frame_list = [img_pre + str(f).zfill(8) + ext \
-- for f in range(first_num, last_num + 1)]
-- syml = 'temporary_symlink_'
-- for iframe in frame_list:
-- frfile = os.path.join(source_dir, iframe)
-- frlink = os.path.join(source_dir, syml + iframe)
-- if os.path.islink(frlink): os.remove(frlink)
-- os.symlink(frfile, frlink)
-- else:
-- syml = ''
-- numframes = len(glob.glob(os.path.join(source_dir, \
-- img_pre + '*' + ext)))
--
-- # Delay between frames is in 100ths of a second
-- spf = 100*(1/fps)
--
-- gifv = tempfile.mkstemp('.gif', '', work_dir)[1]
--
-- all_vars = {}
-- all_vars.update(globals())
-- all_vars.update(locals())
--
-- if not quiet:
-- print 'Creating GIF file'
--
-- command = """cd %(source_dir)s ; \\
--%(convert)s -delay %(spf)s %(syml)s%(img_pre)s*%(ext)s %(gifv)s
--""" % all_vars
-- run(command)
--
-- shutil.move(gifv, vidname)
--
-- if frame_range:
-- lframes = os.path.join(source_dir, syml)
-- for frame in glob.glob(lframes + '*'):
-- os.remove(frame)
--
--
--def do_clean():
-- """
-- Delete enhanced files
-- """
--
-- if not quiet:
-- print 'Deleting all enhanced images (if any)'
--
-- eframes = os.path.join(work_dir, 'eimg')
-- rframes = os.path.join(work_dir, 'rimg')
-- for frame in glob.glob(eframes + '*'):
-- os.remove(frame)
-- for frame in glob.glob(rframes + '*'):
-- os.remove(frame)
--
--
--def which(command):
-- """
-- Finds (or not) a command a la "which"
-- """
--
-- command_found = False
--
-- if command[0] == '/':
-- if os.path.isfile(command) and \
-- os.access(command, os.X_OK):
-- command_found = True
-- abs_command = command
-- else:
-- path = os.environ.get('PATH', '').split(os.pathsep)
-- for dir in path:
-- abs_command = os.path.join(dir, command)
-- if os.path.isfile(abs_command) and \
-- os.access(abs_command, os.X_OK):
-- command_found = True
-- break
--
-- if not command_found:
-- abs_command = ''
--
-- return abs_command
--
--
--def is_installed(prog):
-- """
-- See whether "prog" is installed
-- """
--
-- wprog = which(prog)
--
-- if wprog == '':
-- print prog + ': command not found'
-- raise SystemExit
-- else:
-- if verbose:
-- print wprog + ': found'
--
--
--if __name__ == '__main__':
--
-- import os
-- import sys
-- import getopt
-- import shutil
-- import tempfile
-- import glob
-- import tarfile
--
-- try:
-- if sys.version_info[0:3] < (2, 3, 0):
-- raise SystemExit
-- except:
-- print 'You need Python 2.3.0 or greater to run me!'
-- raise SystemExit
--
-- try:
-- (opts, args) = getopt.getopt(sys.argv[1:], \
-- 'ho:p:d:w:a:qvt:ekc:r:s:b:f:VCD:L:')
-- except:
-- print "Something's wrong. Try the '-h' flag."
-- raise SystemExit
--
-- opts = dict(opts)
--
-- if not opts and not args:
-- print usage
-- raise SystemExit
--
-- if '-h' in opts:
-- print usage + help
-- raise SystemExit
--
-- if '-V' in opts:
-- print 'gif_encoder.py version ' + version
-- raise SystemExit
--
-- if ('-v' in opts) or ('-C' in opts):
-- verbose = True
-- else:
-- verbose = False
--
-- if '-q' in opts:
-- quiet = True
-- verbose = False
-- else:
-- quiet = False
--
-- for i in [convert]:
-- is_installed(i)
-- if '-C' in opts: raise SystemExit
--
-- img_pre = opts.get('-p', '')
--
-- if img_pre not in ['', 'eimg', 'rimg']:
-- print 'Improper image name prefix.'
-- raise SystemExit
--
-- temp_dir = ''
-- img_dir = opts.get('-d', '.')
-- img_dir = os.path.abspath(img_dir)
-- if ' ' in img_dir:
-- temp_dir = tempfile.mkdtemp('', '.lives-', '/tmp/')
-- os.symlink(img_dir, temp_dir + '/img_dir')
-- img_dir = temp_dir + '/img_dir'
--
-- if not os.path.isdir(img_dir):
-- print 'The image source directory: ' + img_dir + \
-- ' does not exist!'
-- raise SystemExit
--
-- if len(args) not in [0, 2]:
-- print 'If frames are specified both first and last ' + \
-- 'image numbers must be chosen.'
-- raise SystemExit
-- elif len(args) == 0:
-- args = [None, None]
--
-- frame_range = False
-- if not args[0]:
-- first_frame_num = '1'
-- else:
-- frame_range = True
-- first_frame_num = args[0]
-- first_frame_num = first_frame_num.zfill(8)
-- first_num = int(first_frame_num)
--
-- if not args[1]:
-- last_frame_num = '99999999'
-- else:
-- last_frame_num = args[1]
-- last_frame_num = last_frame_num.zfill(8)
-- last_num = int(last_frame_num)
--
-- # Aspect ratio is not used
-- aspectc = opts.get('-a', '2')
--
-- # Video type is not used
-- vtype = opts.get('-t', 'gif')
--
-- out_gif = opts.get('-o', vtype + '_movie.gif')
--
-- fpsc = opts.get('-f', '4')
--
-- if fpsc not in [str(i) for i in xrange(1,9)]:
-- if not quiet: print 'Invalid fps code, attempting float fps.'
-- foundfps = False
-- else:
-- if fpsc == '1': fps = 24000.0/1001.0
-- elif fpsc == '2': fps = 24.0
-- elif fpsc == '3': fps = 25.0
-- elif fpsc == '4': fps = 30000.0/1001.0
-- elif fpsc == '5': fps = 30.0
-- elif fpsc == '6': fps = 50.0
-- elif fpsc == '7': fps = 60000.0/1001.0
-- elif fpsc == '8': fps = 60.0
-- foundfps = True
--
-- if not foundfps:
-- try:
-- fps = locale.atof(fpsc)
-- if not quiet: print 'Using fps = %s' % fps
-- if fps > 0: foundfps = True
-- except:
-- pass
--
-- if not foundfps:
-- print 'Invalid fps code or rate.'
-- raise SystemExit
--
-- if '-e' not in opts:
-- enhance = False
-- else:
-- enhance = True
--
-- if enhance and img_pre:
-- print 'Sorry, you cannot enhance already-enhanced images'
-- raise SystemExit
--
-- if '-k' not in opts:
-- keep = False
-- else:
-- keep = True
--
-- cgeom = opts.get('-c', '')
-- rgeom = opts.get('-r', '')
--
-- if (cgeom or rgeom) and not enhance:
-- print 'Missing "-e" option.'
-- raise SystemExit
--
-- delay = opts.get('-D', '0')
-- if verbose: print 'Linear audio delay (ms): ' + delay
--
-- lv1file = opts.get('-L', None)
-- if lv1file:
-- if not quiet: print 'Opening lv1 file...'
-- try:
-- lv1 = tarfile.open(os.path.abspath(lv1file))
-- except:
-- print 'This does not appear to be a valid LiVES file!'
-- raise SystemExit
-- if 'header.tar' not in lv1.getnames():
-- print 'This does not appear to be a valid LiVES file!'
-- raise SystemExit
-- for tfile in lv1.getmembers():
-- lv1.extract(tfile, img_dir)
-- for tfile in glob.glob(os.path.join(img_dir, '*.tar')):
-- imgtar = tarfile.open(tfile)
-- for img in imgtar.getmembers():
-- imgtar.extract(img, img_dir)
-- os.remove(tfile)
--
-- test_file = os.path.join(img_dir, img_pre + first_frame_num)
-- if os.path.isfile(test_file + '.jpg'):
-- ext = '.jpg'
-- elif os.path.isfile(test_file + '.png'):
-- ext = '.png'
-- else:
-- print 'Cannot find any appropriate %s or %s files!' % ('.jpg','.png')
-- raise SystemExit
-- first_frame = test_file + ext
-- last_frame = os.path.join(img_dir, img_pre + last_frame_num + ext)
--
-- if not quiet: print 'Found: ' + first_frame
--
-- work_dir = opts.get('-w', img_dir)
-- work_dir = os.path.abspath(work_dir)
-- if not os.path.isdir(work_dir):
-- if not quiet: print 'Creating ' + work_dir
-- try:
-- os.makedirs(work_dir)
-- os.chmod(work_dir, 0755)
-- except:
-- print 'Could not create the work directory ' + \
-- work_dir
-- raise SystemExit
-- if ' ' in work_dir:
-- if temp_dir == '':
-- temp_dir = tempfile.mkdtemp('', '.lives-', '/tmp/')
-- os.symlink(work_dir, temp_dir + '/work_dir')
-- work_dir = temp_dir + '/work_dir'
--
-- # Audio is not used
-- sndf = opts.get('-s', os.path.join(img_dir, 'audio'))
--
-- if enhance:
-- do_enhance()
-- # Note that do_enhance() always creates images prefixed
-- # with 'rimg'. What's important to note if that if the
-- # images are resized the 'rimg' are indeed resized, but
-- # if not the 'rimg' are simply symlinks to the 'eimg'
-- # (enhanced) images.
-- img_pre = 'rimg'
-- ext = '.png'
-- vidname = os.path.join(work_dir, out_gif)
-- # do_encode() acts on images prefixed by img_pre.
-- do_encode()
-- if not keep:
-- do_clean()
-- if temp_dir != '':
-- shutil.rmtree(temp_dir)
-- if not quiet: print "Done!"
--
--
--"""
--CHANGELOG:
--
--29 Oct 2004 : 0.0.1 : first release.
--08 Nov 2004 : 0.0.2 : make sure that the enhanced
-- color depth is 8-bits/channel.
--02 Jan 2005 : 0.0.3 : updated docs.
-- added sound rate (-b) option (unused).
--21 Mar 2005 : 0.0.4 : use env python (hopefully >= 2.3)
--09 Mar 2006 : 0.0.5 : added '-depth 8' to resize, as ImageMagick
-- keeps changing its damn behaviour.
--28 Jun 2007 : 0.0.6 : handles paths with spaces appropriately
-- (thanks Gabriel).
--"""
---- /dev/null
-+++ lives/lives-plugins/marcos-encoders/lives_dirac_encoder
-@@ -0,0 +1,843 @@
-+#!/usr/bin/env python
-+
-+
-+import locale
-+locale.setlocale(locale.LC_NUMERIC,"")
-+
-+
-+"""
-+dirac_encoder.py
-+
-+Front-end to various programs needed to create Dirac
-+movies with some image-enhancing capabilities through the use of
-+ImageMagick. Meant as a companion to LiVES (to possibly call
-+from within a plugin, see http://www.xs4all.nl/~salsaman/lives/ )
-+but can also be used as a stand-alone program.
-+
-+Requires MPlayer, ImageMagick (GraphicsMagick might also
-+work), Dirac, and Python 2.3.0 or greater. Note that audio
-+support is not yet implemented, only video encoding. Also
-+note that Dirac is still at a very early stage of development,
-+and hence this code is highly experimental. Use at your
-+own risk.
-+
-+Dirac's encoder API changed between versions 0.5.1 and 0.5.2.
-+This encoder will not work with 0.5.1 but has been tested with
-+0.5.2.
-+
-+Copyright (C) 2004-2005 Marco De la Cruz (marco at reimeika.ca)
-+It's a trivial program, but might as well GPL it, so see:
-+http://www.gnu.org/copyleft/gpl.html for license.
-+
-+See my vids at http://amv.reimeika.ca !
-+"""
-+
-+version = '0.0.a15'
-+convert = 'convert'
-+mencoder = 'mencoder'
-+dirac_encoder = 'dirac_encoder'
-+identify = 'identify'
-+
-+usage = \
-+ """
-+dirac_encoder.py -h
-+dirac_encoder.py -V
-+dirac_encoder.py -C
-+dirac_encoder.py [-o out] [-p pre] [-d dir] [-a aspect] [-D delay*]
-+ [-q|-v] [-t type] [-k] [-e [[-w dir] [-c geom] [-r geom]]]
-+ [-s sndfile*] [-b sndrate*] [-f fpscode] [-L lv1file]
-+ [firstframe lastframe]
-+ """
-+
-+help = \
-+ """
-+SUMMARY (ver. %s):
-+
-+Encodes a series of PNG or JPG images into a Dirac
-+(.drc) stream and is also capable of performing some simple image
-+enhacements using ImageMagick. The images and audio are assumed to
-+be in an uncompressed LiVES format, hence making this encoder
-+more suitable to be used within a LiVES plugin (but can also
-+be used directly on a LiVES temporary directory).
-+
-+OPTIONS:
-+
-+-h for help.
-+
-+-V shows the version number.
-+
-+-C check external program dependencies and exit.
-+
-+-o out will save the video in file "out".
-+ Default: "'type'_movie.drc". See below for 'type'.
-+
-+-p pre the encoder assumes that sound and images are named using
-+ LiVES' conventions i.e. "audio" and "00000001.ext",
-+ "00000002.ext"... where "ext" is either "jpg" or "png".
-+ However, dirac_encoder.py will create temporary files
-+ which can be saved for later use (for example, after
-+ enhancing the images with "-e" , which may take a long
-+ time). These temporary files will be named
-+ "pre_00000001.ext", etc... where "pre" is either "eimg"
-+ or "rimg" and will be kept if the "-k" option is used.
-+ dirac_encoder.py can then be run over the enhanced images
-+ only by selecting the appropriate prefix ("eimg" or
-+ "rimg") here. See "-e" to see what each prefix means.
-+ Default: "" (an empty string).
-+
-+-d dir "dir" is the directory containing the source image
-+ files. These must be of the form "00000001.ext" or
-+ "pre_00000001.ext" as explained above.
-+ Default: "."
-+
-+-a aspect sets the aspect ratio of the resulting Dirac file. This can be:
-+
-+ 1 1:1 display
-+ 2 4:3 display
-+ 3 16:9 display
-+ 4 2.21:1 display
-+
-+ Default: "2"
-+
-+-D delay* linearly delay the audio stream by "delay" ms.
-+ Default: "0"
-+ * = NOT IMPLEMENTED (YET?)
-+
-+-q quiet operation, only complains on error.
-+
-+-v be verbose.
-+
-+-t type type of video created. The options here are:
-+
-+ "hi": a very high quality MPEG-4 file, suitable
-+ for archiving images of 720x480.
-+
-+ "mh": medium-high quality MPEG-4, which still allows
-+ to watch small videos (352x240 and below)
-+ fullscreen.
-+
-+ "ml": medium-low quality MPEG-4, suitable for
-+ most videos but in particular small videos
-+ (352x240 and below) meant for online
-+ distribution.
-+
-+ "lo": a low quality MPEG-4 format. Enlarging
-+ small videos will result in noticeable
-+ artifacts. Good for distributing over slow
-+ connections.
-+
-+ Default: "ml"
-+
-+-e perform some simple filtering/enhancement to improve image
-+ quality. The images created by using this option will be
-+ stored in the directory specified by the "-w" option (or
-+ "-d" if not present, see above) and each filename will be
-+ prefixed with "eimg" (see "-p" above). Using this option will
-+ take enormous amounts of disk space, and in reality does
-+ not do anything that cannot be done within LiVES itself.
-+ Using this option enables the following four:
-+
-+ -w dir "dir" is the working directory where the enhanced
-+ images will be saved. Although these can all
-+ co-exist with the original LiVES files it is
-+ recommended you use a different directory. Note
-+ that temporary files may take a huge amount of
-+ space, perhaps twice as much as the LiVES files
-+ themselves. If this directory does not exist is
-+ will be created.
-+ Default: same as "-d".
-+
-+ -k keep the temporary files, useful to experiment
-+ with different encoding types without having
-+ to repeatedly enhance the images (which can be
-+ very time-consuming). See "-p" above.
-+
-+ -c geom in addition to enhancing the images, crop them
-+ to the specified geometry e.g. "688x448+17+11".
-+ Filename prefix remains "eimg". Note that the
-+ dimensions of the images should both be multiples
-+ of "16", otherwise some players may show artifacts
-+ (such as garbage or green bars at the borders).
-+
-+ -r geom this will create a second set of images resulting
-+ from resizing the images that have already been
-+ enhanced and possibly cropped (if "-c" has been
-+ specified). The geometry here is simple a new
-+ image size e.g. "352x240!". This second set will have
-+ filenames prefixed with the string "rimg" (see "-p"
-+ above). Note that the dimensions of the images
-+ should both be multiples of "16", otherwise some
-+ players may show artifacts (such as garbage or
-+ green bars at the borders).
-+
-+-s sndfile* name of the audio file. Can be either raw "audio" or
-+ "[/path/to/]soundfile.wav".
-+ Default: "audio" inside "dir" as specified by "-d".
-+ * = NOT IMPLEMENTED (YET?)
-+
-+-b sndrate* sample rate of the sound file in Hertz.
-+ * = NOT IMPLEMENTED (YET?)
-+
-+-f fpscode frame-rate code. Acceptable values are:
-+
-+ 1 - 24000.0/1001.0 (NTSC 3:2 pulldown converted FILM)
-+ 2 - 24.0 (NATIVE FILM)
-+ 3 - 25.0 (PAL/SECAM VIDEO / converted FILM)
-+ 4 - 30000.0/1001.0 (NTSC VIDEO)
-+ 5 - 30.0
-+ 6 - 50.0 (PAL FIELD RATE)
-+ 7 - 60000.0/1001.0 (NTSC FIELD RATE)
-+ 8 - 60.0
-+
-+ Default: "4".
-+
-+-L lv1file use the images stored in the LiVES file "lv1file" (e.g.
-+ "movie.lv1"). Files will be extracted inside "dir" as
-+ specified by "-d". Using this option allows to encode
-+ a movie without having to restore it first with LiVES.
-+ Note that the encoder will not delete the extracted
-+ files after it has finished, this must be done manually
-+ afterwards. If frame code/rate (-f) and/or sound rate (-b)
-+ are not specified the defaults will be used (30000/1001 fps
-+ and 44100 Hz). These, however, may not be correct, in which
-+ case they should be specified explicitly. Furthermore, the
-+ .lv1 audio (if present) is always assumed to have a sample
-+ data size in 16-bit words with two channels, and to be signed
-+ linear (this is usually the case, however). If any of these
-+ latter parameters are incorrect the resulting file may be
-+ corrupted and encoding will have to be done using LiVES.
-+
-+firstframe first frame number. If less than eight digits long it will
-+ be padded with zeroes e.g. 234 -> 00000234. A prefix can
-+ be added using the "-p" option.
-+ Default: "00000001"
-+
-+lastframe last frame number, padded with zeroes if necessary, prefix
-+ set by "-p".
-+ Default: the last frame of its type in the "-d" directory,
-+ where "type" is set by the prefix.
-+
-+Note that either no frames or both first and last frames must be specified.
-+
-+EXAMPLES:
-+
-+Suppose you have restored a LiVES' .lv1 file (in either JPG or PNG format),
-+and that the images are stored in the directory "/tmp/livestmp/991319584/".
-+In this example the movie is assumed to be 16:9. Then, in order to create
-+an drc file you can simply do the following:
-+
-+ dirac_encoder.py -d /tmp/livestmp/991319584 -o /movies/default.drc -a 3
-+
-+and the clip "default.drc" will be created in "/movies/" with the correct
-+aspect ratio.
-+
-+Suppose we want to make a downloadable version of the clip, small in size
-+but of good quality. The following command activates the generic enhancement
-+filter and resizes the images to "352x240". Note that these operations
-+are performed after cropping the originals a bit (using "704x464+5+6").
-+This is done because we are assuming that there is a black border around
-+the original pictures which we want to get rid of (this might distort the
-+images somewhat, so be careful about cropping/resizing, and remember to
-+use dimensions which are multiples of 16):
-+
-+ dirac_encoder.py -v -d /tmp/livestmp/991319584 -w /tmp/tmpdrc \\
-+ -o /movies/download.drc -a 3 -k -e -c "704x464+5+6" -r "352x240"
-+
-+Since we use the "-k" flag the enhanced images are kept (both full-size
-+crops and the resized ones) in "/tmp/tmpdrc". Beware that this may consume
-+a lot of disk space (about 10x as much as the originals). The reason we
-+keep them is because the above may take quite a long time and we may want
-+to re-use the enhanced images. So, for example, creating a high-quality
-+clip at full size can be accomplished now as follows:
-+
-+ dirac_encoder.py -d /tmp/tmpdrc -t hi -o /movies/archive.drc \\
-+ -s /tmp/livestmp/991319584/audio -a 3 -k -p eimg
-+
-+If, for example, we only want to encode frames 100 to 150 we can run
-+the following:
-+
-+ dirac_encoder.py -v -d /tmp/tmpdrc -o /movies/selection.drc \\
-+ -a 3 -k -p eimg 100 150
-+
-+Note that no audio has been selected ("-s"). This is because
-+dirac_encoder.py cannot trim the audio to the appropriate length.
-+You would need to use LiVES to do this.
-+
-+To delete all the enhanced images you can just remove "/tmp/tmpdrc".
-+
-+If you notice that the video and audio become out of sync so that
-+near the end of the movie the video trails the audio by, say, 0.2s,
-+you can use the "-D" option as follows:
-+
-+ dirac_encoder.py -d /tmp/livestmp/991319584 -o test.drc -D 200
-+
-+Note that negative time values are also allowed.
-+
-+Suppose that you have "movie1.lv1", "movie2.lv1" and "movie3.lv1".
-+Batch-encoding can be done as follows (zsh-syntax):
-+
-+ for i in movie?.lv1
-+ do
-+ mkdir /tmp/$i:r
-+ dirac_encoder.py -d /tmp/$i:r -o /tmp/$i:r.drc -L $i
-+ rm -rf /tmp/$i:r
-+ done
-+
-+This will generate the files "movie1.drc", "movie2.drc" and
-+"movie3.drc" in "/tmp". Note that is is not necessary to
-+specify whether the files are stored in JPG or PNG format,
-+and that potentially time-consuming options (e.g. "-e") may
-+be enabled. It is not necessary to have a working LiVES
-+installation to encode .lv1 files.
-+ """ % version
-+
-+def gcd(a, b):
-+ """
-+ gcd(a, b) (a,b are integers)
-+ Returns the greatest common divisor of two integers.
-+ """
-+ if b == 0: return a
-+ else: return gcd(b, a%b)
-+
-+
-+def run(command):
-+ """
-+ Run a shell command
-+ """
-+
-+ if verbose:
-+ print 'Running: \n' + command + '\n=== ... ==='
-+ std = ''
-+ else:
-+ std = ' > /dev/null 2>&1'
-+
-+ os.system(command + std)
-+
-+
-+def do_enhance():
-+ """
-+ Image cleanup/crop/resize routine. Generic, but seems to work
-+ well with anime :)
-+ """
-+
-+ if not quiet:
-+ print 'Enhancing images... please wait, this might take long...'
-+
-+ enh_opts = "-enhance -sharpen '0.0x0.5' -gamma 1.2 -contrast -depth 8"
-+
-+ if cgeom:
-+ docrop = ' '.join(['-crop', "'%s!'" % cgeom])
-+ else:
-+ docrop = ''
-+
-+ iframe = first_num
-+ while True:
-+ # File names are padded with zeroes to 8 characters
-+ # (not counting the .ext).
-+ frame = str(iframe).zfill(8)
-+ fname = os.path.join(img_dir, frame + ext)
-+ if not os.path.isfile(fname) or (iframe == last_num + 1):
-+ break
-+ eimg_fname = os.path.join(work_dir, 'eimg' + frame + '.png')
-+ rimg_fname = os.path.join(work_dir, 'rimg' + frame + '.png')
-+ command = ' '.join([convert, docrop, enh_opts, fname, eimg_fname])
-+ run(command)
-+ if rgeom:
-+ if os.path.exists(rimg_fname): os.remove(rimg_fname)
-+ shrink = ' '.join([convert, '-resize', "'%s!'" % rgeom, '-depth 8'])
-+ command = ' '.join([shrink, eimg_fname, rimg_fname])
-+ run(command)
-+ else:
-+ if os.path.exists(rimg_fname): os.remove(rimg_fname)
-+ try:
-+ os.symlink(eimg_fname, rimg_fname)
-+ except (IOError, OSError):
-+ shutil.copy(eimg_fname, rimg_fname)
-+ iframe+=1
-+
-+
-+def do_encode():
-+ """
-+ Encode a series of images into a Dirac stream.
-+ """
-+
-+ if verbose:
-+ std = ''
-+ be_verbose = '-verbose'
-+ else:
-+ std = ' > /dev/null 2>&1'
-+ be_verbose = ''
-+
-+ fpsnum = fps.split('/')[0]
-+ fpsden = fps.split('/')[1]
-+ ffps = eval('float('+fpsnum+')/'+fpsden)
-+ mencoder_opts = '-mf type=%s:fps=%s ' % (ext[1:], ffps) + \
-+ '-nosound -vf hqdn3d=2:1:3,pp=va:128:8/ha:128:8/dr,' + \
-+ 'dsize=%s,format=i420 -ovc raw -of rawvideo -o ' % aspect
-+ dirac_opts = '-HD1080'
-+ if vtype == 'hi':
-+ dirac_opts = ' '.join([dirac_opts, '-qf 10'])
-+ oggenc_opts = '-q 9'
-+ elif vtype == 'mh':
-+ dirac_opts = ' '.join([dirac_opts, '-qf 8'])
-+ oggenc_opts = '-q 8'
-+ elif vtype == 'ml':
-+ dirac_opts = ' '.join([dirac_opts, '-qf 6'])
-+ oggenc_opts = '-q 6'
-+ elif vtype == 'lo':
-+ dirac_opts = ' '.join([dirac_opts, '-qf 4'])
-+ oggenc_opts = '-q 4'
-+
-+
-+ if img_dir != work_dir and not enhance:
-+ source_dir = img_dir
-+ else:
-+ source_dir = work_dir
-+ yuvv = os.path.join(source_dir, 'TMP_YUVstream.yuv')
-+ yuvvne = yuvv[:-4]
-+ dyuvv = tempfile.mkstemp('', '', work_dir)[1]
-+
-+ if frame_range:
-+ numframes = str(last_num - first_num + 1)
-+ frame_list = [img_pre + str(f).zfill(8) + ext \
-+ for f in range(first_num, last_num + 1)]
-+ syml = 'temporary_symlink_'
-+ for iframe in frame_list:
-+ frfile = os.path.join(source_dir, iframe)
-+ frlink = os.path.join(source_dir, syml + iframe)
-+ if os.path.islink(frlink): os.remove(frlink)
-+ os.symlink(frfile, frlink)
-+ else:
-+ syml = ''
-+ numframes = len(glob.glob(os.path.join(source_dir, \
-+ img_pre + '*' + ext)))
-+
-+ fgeom = os.popen(' '.join([identify, '-format "%w %h"', \
-+ os.path.join(source_dir, \
-+ img_pre + first_frame_num + ext)])).read().strip().split()
-+ fx = int(fgeom[0])
-+ fy = int(fgeom[1])
-+ # Why 1.5? See http://sourceforge.net/forum/forum.php?thread_id=1143416&forum_id=353618
-+ fbytes = int(fx*fy*1.5)
-+
-+ all_vars = {}
-+ all_vars.update(globals())
-+ all_vars.update(locals())
-+
-+ if not quiet:
-+ print 'Creating "%s"-quality Dirac file' % vtype
-+
-+ yuvcommand = """cd %(source_dir)s ; \\
-+%(mencoder)s mf://%(syml)s%(img_pre)s*%(ext)s %(mencoder_opts)s%(yuvv)s %(std)s
-+ """ % all_vars
-+ run(yuvcommand)
-+ command = """cd %(source_dir)s ; \\
-+%(dirac_encoder)s -width %(fx)s -height %(fy)s -fr %(ffps)s %(be_verbose)s %(dirac_opts)s %(yuvvne)s %(dyuvv)s %(std)s
-+""" % all_vars
-+ run(command)
-+ os.remove(yuvv)
-+
-+ for tfile in [dyuvv, dyuvv + '.yuv', dyuvv + '.imt']:
-+ if os.path.exists(tfile):
-+ if verbose:
-+ print 'Removing ' + tfile
-+ os.remove(tfile)
-+
-+# Audio not supported yet. Planned to use Matroska container but
-+# Dirac developers are thinking of MXF.
-+ audio = False
-+ if audio:
-+ if not quiet:
-+ print 'Creating "%s"-quality ogg vorbis file' % vtype
-+
-+ ogg = tempfile.mkstemp('.ogg', '', work_dir)[1]
-+ if rawsndf:
-+ wav = tempfile.mkstemp('.wav', '', work_dir)[1]
-+ sox_opts = '-t raw -r %s -w -c 2 -s' % sndr
-+ command = ' '.join([sox, sox_opts, sndf, wav])
-+ run(command)
-+ else:
-+ wav = sndf
-+ command = ' '.join([oggenc, oggenc_opts, wav, '-o', ogg, std])
-+ run(command)
-+
-+ if delay != '0':
-+ totfr = len(glob.glob(os.path.join(source_dir, syml + img_pre + '*' + ext)))
-+ # "delay" is in ms, transform into s
-+ totfrshift = int(totfr + round((locale.atof(delay)/1000.0)*locale.atof(ffps)))
-+ delaysh = ',%s/%s' % (totfrshift, totfr)
-+ else:
-+ delaysh = ''
-+
-+ all_vars.update(locals())
-+
-+ if not quiet:
-+ print 'Multiplexing...'
-+ command = """
-+%(mkvplex)s --aspect-ratio '1:%(aspect)s' -o "%(vidname)s" %(vidv)s -y '0:0%(delaysh)s' %(ogg)s %(std)s""" % all_vars
-+ run(command)
-+ if rawsndf and os.path.exists(wav): os.remove(wav)
-+ if os.path.exists(ogg): os.remove(ogg)
-+ if os.path.exists(dyuvv + '.drc'): os.remove(dyuvv + '.drc')
-+ else:
-+ shutil.move(dyuvv + '.drc', vidname)
-+ note = """
-+You can play the Dirac file %(vidname)s by running:
-+
-+dirac_decoder -v %(vidname)s %(vidname)s
-+mplayer -demuxer rawvideo -rawvideo fps=%(ffps)s:size=%(fbytes)s:w=%(fx)s:h=%(fy)s %(vidname)s.yuv
-+
-+If %(vidname)s has an extension do not include it in the above
-+commands e.g. if it's "test.drc" then do:
-+
-+dirac_decoder -v test test
-+mplayer -demuxer rawvideo -rawvideo fps=%(ffps)s:size=%(fbytes)s:w=%(fx)s:h=%(fy)s test.yuv
-+""" % all_vars
-+ if not quiet: print note
-+
-+ if frame_range:
-+ lframes = os.path.join(source_dir, syml)
-+ for frame in glob.glob(lframes + '*'):
-+ os.remove(frame)
-+
-+
-+def do_clean():
-+ """
-+ Delete enhanced files
-+ """
-+
-+ if not quiet:
-+ print 'Deleting all enhanced images (if any)'
-+
-+ eframes = os.path.join(work_dir, 'eimg')
-+ rframes = os.path.join(work_dir, 'rimg')
-+ for frame in glob.glob(eframes + '*'):
-+ os.remove(frame)
-+ for frame in glob.glob(rframes + '*'):
-+ os.remove(frame)
-+
-+
-+def which(command):
-+ """
-+ Finds (or not) a command a la "which"
-+ """
-+
-+ command_found = False
-+
-+ if command[0] == '/':
-+ if os.path.isfile(command) and \
-+ os.access(command, os.X_OK):
-+ command_found = True
-+ abs_command = command
-+ else:
-+ path = os.environ.get('PATH', '').split(os.pathsep)
-+ for dir in path:
-+ abs_command = os.path.join(dir, command)
-+ if os.path.isfile(abs_command) and \
-+ os.access(abs_command, os.X_OK):
-+ command_found = True
-+ break
-+
-+ if not command_found:
-+ abs_command = ''
-+
-+ return abs_command
-+
-+
-+def is_installed(prog):
-+ """
-+ See whether "prog" is installed
-+ """
-+
-+ wprog = which(prog)
-+
-+ if wprog == '':
-+ print prog + ': command not found'
-+ raise SystemExit
-+ else:
-+ if verbose:
-+ print wprog + ': found'
-+
-+
-+if __name__ == '__main__':
-+
-+ import os
-+ import sys
-+ import getopt
-+ import shutil
-+ import tempfile
-+ import glob
-+ import tarfile
-+
-+ try:
-+ if sys.version_info[0:3] < (2, 3, 0):
-+ raise SystemExit
-+ except:
-+ print 'You need Python 2.3.0 or greater to run me!'
-+ raise SystemExit
-+
-+ try:
-+ (opts, args) = getopt.getopt(sys.argv[1:], \
-+ 'ho:p:d:w:a:qvt:ekc:r:s:b:f:VCD:L:')
-+ except:
-+ print "Something's wrong. Try the '-h' flag."
-+ raise SystemExit
-+
-+ opts = dict(opts)
-+
-+ if not opts and not args:
-+ print usage
-+ raise SystemExit
-+
-+ if '-h' in opts:
-+ print usage + help
-+ raise SystemExit
-+
-+ if '-V' in opts:
-+ print 'dirac_encoder.py version ' + version
-+ raise SystemExit
-+
-+ if ('-v' in opts) or ('-C' in opts):
-+ verbose = True
-+ else:
-+ verbose = False
-+
-+ if '-q' in opts:
-+ quiet = True
-+ verbose = False
-+ else:
-+ quiet = False
-+
-+ for i in [convert, mencoder, dirac_encoder, identify]:
-+ is_installed(i)
-+ if '-C' in opts: raise SystemExit
-+
-+ img_pre = opts.get('-p', '')
-+
-+ if img_pre not in ['', 'eimg', 'rimg']:
-+ print 'Improper image name prefix.'
-+ raise SystemExit
-+
-+ temp_dir = ''
-+ img_dir = opts.get('-d', '.')
-+ img_dir = os.path.abspath(img_dir)
-+ if ' ' in img_dir:
-+ temp_dir = tempfile.mkdtemp('', '.lives-', '/tmp/')
-+ os.symlink(img_dir, temp_dir + '/img_dir')
-+ img_dir = temp_dir + '/img_dir'
-+
-+ if not os.path.isdir(img_dir):
-+ print 'The image source directory: ' + img_dir + \
-+ ' does not exist!'
-+ raise SystemExit
-+
-+ if len(args) not in [0, 2]:
-+ print 'If frames are specified both first and last ' + \
-+ 'image numbers must be chosen.'
-+ raise SystemExit
-+ elif len(args) == 0:
-+ args = [None, None]
-+
-+ frame_range = False
-+ if not args[0]:
-+ first_frame_num = '1'
-+ else:
-+ frame_range = True
-+ first_frame_num = args[0]
-+ first_frame_num = first_frame_num.zfill(8)
-+ first_num = int(first_frame_num)
-+
-+ if not args[1]:
-+ last_frame_num = '99999999'
-+ else:
-+ last_frame_num = args[1]
-+ last_frame_num = last_frame_num.zfill(8)
-+ last_num = int(last_frame_num)
-+
-+ aspectc = opts.get('-a', '2')
-+
-+ if aspectc not in [str(i) for i in xrange(1,5)]:
-+ print 'Invalid aspect ratio.'
-+ raise SystemExit
-+ else:
-+ if aspectc == '1': aspect = '1:1'
-+ elif aspectc == '2': aspect = '4:3'
-+ elif aspectc == '3': aspect = '16:9'
-+ elif aspectc == '4': aspect = '2.21:1'
-+
-+ vtype = opts.get('-t', 'ml')
-+
-+ if vtype not in ['hi', 'mh', 'ml', 'lo']:
-+ print 'Invalid video type.'
-+ raise SystemExit
-+
-+ out_drc = opts.get('-o', vtype + '_movie.drc')
-+
-+ fpsc = opts.get('-f', '4')
-+
-+ if fpsc not in [str(i) for i in xrange(1,9)]:
-+ if not quiet: print 'Invalid fps code, attempting float fps.'
-+ foundfps = False
-+ else:
-+ if fpsc == '1': fps = '24000/1001'
-+ elif fpsc == '2': fps = '24/1'
-+ elif fpsc == '3': fps = '25/1'
-+ elif fpsc == '4': fps = '30000/1001'
-+ elif fpsc == '5': fps = '30/1'
-+ elif fpsc == '6': fps = '50/1'
-+ elif fpsc == '7': fps = '60000/1001'
-+ elif fpsc == '8': fps = '60/1'
-+ foundfps = True
-+
-+ if not foundfps:
-+ try:
-+ fpsnum = int(locale.atof(fpsc)*10**15)
-+ fpsden = 10**15
-+ divisor = gcd(fpsnum, fpsden)
-+ if divisor > 1:
-+ fpsnum = fpsnum/divisor
-+ fpsden = fpsden/divisor
-+ fps = '%s/%s' % (fpsnum, fpsden)
-+ if not quiet: print 'Using fps = ' + fps
-+ if fpsnum > 0: foundfps = True
-+ except:
-+ pass
-+
-+ if not foundfps:
-+ print 'Invalid fps code or rate.'
-+ raise SystemExit
-+
-+ if '-e' not in opts:
-+ enhance = False
-+ else:
-+ enhance = True
-+
-+ if enhance and img_pre:
-+ print 'Sorry, you cannot enhance already-enhanced images'
-+ raise SystemExit
-+
-+ if '-k' not in opts:
-+ keep = False
-+ else:
-+ keep = True
-+
-+ cgeom = opts.get('-c', '')
-+ rgeom = opts.get('-r', '')
-+
-+ if (cgeom or rgeom) and not enhance:
-+ print 'Missing "-e" option.'
-+ raise SystemExit
-+
-+ delay = opts.get('-D', '0')
-+ if verbose: print 'Linear audio delay (ms): ' + delay
-+
-+ lv1file = opts.get('-L', None)
-+ if lv1file:
-+ if not quiet: print 'Opening lv1 file...'
-+ try:
-+ lv1 = tarfile.open(os.path.abspath(lv1file))
-+ except:
-+ print 'This does not appear to be a valid LiVES file!'
-+ raise SystemExit
-+ if 'header.tar' not in lv1.getnames():
-+ print 'This does not appear to be a valid LiVES file!'
-+ raise SystemExit
-+ for tfile in lv1.getmembers():
-+ lv1.extract(tfile, img_dir)
-+ for tfile in glob.glob(os.path.join(img_dir, '*.tar')):
-+ imgtar = tarfile.open(tfile)
-+ for img in imgtar.getmembers():
-+ imgtar.extract(img, img_dir)
-+ os.remove(tfile)
-+
-+ test_file = os.path.join(img_dir, img_pre + first_frame_num)
-+ if os.path.isfile(test_file + '.jpg'):
-+ ext = '.jpg'
-+ elif os.path.isfile(test_file + '.png'):
-+ ext = '.png'
-+ else:
-+ print 'Cannot find any appropriate %s or %s files!' % ('.jpg','.png')
-+ raise SystemExit
-+ first_frame = test_file + ext
-+ last_frame = os.path.join(img_dir, img_pre + last_frame_num + ext)
-+
-+ if not quiet: print 'Found: ' + first_frame
-+
-+ work_dir = opts.get('-w', img_dir)
-+ work_dir = os.path.abspath(work_dir)
-+ if not os.path.isdir(work_dir):
-+ if not quiet: print 'Creating ' + work_dir
-+ try:
-+ os.makedirs(work_dir)
-+ os.chmod(work_dir, 0755)
-+ except:
-+ print 'Could not create the work directory ' + \
-+ work_dir
-+ raise SystemExit
-+ if ' ' in work_dir:
-+ if temp_dir == '':
-+ temp_dir = tempfile.mkdtemp('', '.lives-', '/tmp/')
-+ os.symlink(work_dir, temp_dir + '/work_dir')
-+ work_dir = temp_dir + '/work_dir'
-+
-+ sndf = opts.get('-s', os.path.join(img_dir, 'audio'))
-+# sndf = os.path.abspath(sndf)
-+ rawsndf = True
-+ if not os.path.isfile(sndf):
-+ audio = False
-+ rawsndf = False
-+ else:
-+ audio = True
-+ if sndf[-4:] == '.wav':
-+ rawsndf = False
-+ if not quiet: print 'Found audio file: ' + sndf
-+
-+ sndr = opts.get('-b', '44100')
-+
-+ if enhance:
-+ do_enhance()
-+ # Note that do_enhance() always creates images prefixed
-+ # with 'rimg'. What's important to note if that if the
-+ # images are resized the 'rimg' are indeed resized, but
-+ # if not the 'rimg' are simply symlinks to (or copies of) the 'eimg'
-+ # (enhanced) images.
-+ img_pre = 'rimg'
-+ ext = '.png'
-+ vidname = os.path.join(work_dir, out_drc)
-+ # do_encode() acts on images prefixed by img_pre.
-+ do_encode()
-+ if not keep:
-+ do_clean()
-+ if temp_dir != '':
-+ shutil.rmtree(temp_dir)
-+ if not quiet: print "Done!"
-+
-+
-+"""
-+CHANGELOG:
-+
-+18 Sep 2004 : 0.0.a1 : first alpha release.
-+23 Sep 2004 : 0.0.a2 : renamed from "mkvd_encoder" ro
-+ "dirac_encoder".
-+ use mplayer to create yuv.
-+25 Sep 2004 : 0.0.a3 : updated docs.
-+27 Sep 2004 : 0.0.a5 : switched back to RGBtoYUV420.
-+ YUV generation now reliable but
-+ still very inefficient.
-+27 Sep 2004 : 0.0.a6 : can handle arbitrary fps values.
-+08 Nov 2004 : 0.0.a7 : make sure that the enhanced
-+ color depth is 8-bits/channel.
-+02 Jan 2005 : 0.0.a8 : updated docs.
-+ added sound rate (-b) option (unused for now).
-+24 Feb 2005 : 0.0.a9 : fixed frame rate calculation.
-+26 Mar 2005 : 0.0.a10 : use env python (hopefully >= 2.3).
-+ replace denoise3d with hqdn3d.
-+12 Jun 2005 : 0.0.a11 : updated to use Dirac version 0.5.2.
-+24 Aug 2005 : 0.0.a12 : Fixed 2.21:1 aspect ratio.
-+09 Mar 2006 : 0.0.a13 : added '-depth 8' to resize, as ImageMagick
-+ keeps changing its damn behaviour.
-+13 Mar 2006 : 0.0.a14 : more efficient YUV generation.
-+ updated playback explanation.
-+28 Jun 2007 : 0.1.a15 : handles paths with spaces appropriately
-+ (thanks Gabriel).
-+"""
---- /dev/null
-+++ lives/lives-plugins/marcos-encoders/mkv_encoder
-@@ -0,0 +1,888 @@
-+#!/usr/bin/env python
-+
-+"""
-+mkv_encoder.py
-+
-+Front-end to various programs needed to create MKV (Matroska)
-+movies with some image-enhancing capabilities through the use of
-+ImageMagick. Meant as a companion to LiVES (to possibly call
-+from within a plugin, see http://www.xs4all.nl/~salsaman/lives/ )
-+but can also be used as a stand-alone program.
-+
-+Requires MPlayer, ImageMagick (GraphicsMagick might also
-+work), sox, Oggenc, MKVtoolnix and Python 2.3.0 or greater.
-+
-+Copyright (C) 2004-2005 Marco De la Cruz (marco at reimeika.ca)
-+It's a trivial program, but might as well GPL it, so see:
-+http://www.gnu.org/copyleft/gpl.html for license.
-+
-+See my vids at http://amv.reimeika.ca !
-+"""
-+
-+version = '0.1.5'
-+convert = 'convert'
-+mencoder = 'mencoder'
-+x264 = 'x264'
-+oggenc = 'oggenc'
-+sox = 'sox'
-+mkvplex = 'mkvmerge'
-+identify = 'identify'
-+
-+usage = \
-+ """
-+mkv_encoder.py -h
-+mkv_encoder.py -V
-+mkv_encoder.py -C
-+mkv_encoder.py [-o out] [-p pre] [-d dir] [-a aspect] [-D delay]
-+ [-q|-v] [-t type] [-k] [-e [[-w dir] [-c geom] [-r geom]]]
-+ [-s sndfile] [-b sndrate] [-f fpscode] [-L lv1file]
-+ [firstframe lastframe]
-+ """
-+
-+help = \
-+ """
-+SUMMARY (ver. %s):
-+
-+Encodes a series of PNG or JPG images into an MPEG-4/Ogg Vorbis
-+(MKV) stream and is also capable of performing some simple image
-+enhacements using ImageMagick. The images and audio are assumed to
-+be in an uncompressed LiVES format, hence making this encoder
-+more suitable to be used within a LiVES plugin (but can also
-+be used directly on a LiVES temporary directory).
-+
-+OPTIONS:
-+
-+-h for help.
-+
-+-V shows the version number.
-+
-+-C check external program dependencies and exit.
-+
-+-o out will save the video in file "out".
-+ Default: "'type'_movie.mkv". See below for 'type'.
-+
-+-p pre the encoder assumes that sound and images are named using
-+ LiVES' conventions i.e. "audio" and "00000001.ext",
-+ "00000002.ext"... where "ext" is either "jpg" or "png".
-+ However, mkv_encoder.py will create temporary files
-+ which can be saved for later use (for example, after
-+ enhancing the images with "-e" , which may take a long
-+ time). These temporary files will be named
-+ "pre_00000001.ext", etc... where "pre" is either "eimg"
-+ or "rimg" and will be kept if the "-k" option is used.
-+ mkv_encoder.py can then be run over the enhanced images
-+ only by selecting the appropriate prefix ("eimg" or
-+ "rimg") here. See "-e" to see what each prefix means.
-+ Default: "" (an empty string).
-+
-+-d dir "dir" is the directory containing the source image
-+ files. These must be of the form "00000001.ext" or
-+ "pre_00000001.ext" as explained above.
-+ Default: "."
-+
-+-a aspect sets the aspect ratio of the resulting MPEG-4. This can be:
-+
-+ 1 1:1 display
-+ 2 4:3 display
-+ 3 16:9 display
-+ 4 2.21:1 display
-+
-+ Default: "2"
-+
-+-D delay linearly delay the audio stream by "delay" ms.
-+ Default: "0"
-+
-+-q quiet operation, only complains on error.
-+
-+-v be verbose.
-+
-+-t type type of video created. The options here are:
-+
-+ "hi": a very high quality XviD file, suitable
-+ for archiving images of 720x480.
-+
-+ "mh": medium-high quality XviD, which still allows
-+ to watch small videos (352x240 and below)
-+ fullscreen.
-+
-+ "ml": medium-low quality XviD, suitable for
-+ most videos but in particular small videos
-+ (352x240 and below) meant for online
-+ distribution.
-+
-+ "lo": a low quality XviD format. Enlarging
-+ small videos will result in noticeable
-+ artifacts. Good for distributing over slow
-+ connections.
-+
-+ "hi_x", "mh_x", "ml_x", "lo_x": same as above.
-+
-+ "hi_h", "mh_h", "ml_h", "lo_h": same as above, but
-+ using the h.264 codec.
-+
-+ "hi_d", "mh_d", "ml_d", "lo_d": same as above, but
-+ using DivX 4/5 encoding.
-+
-+ Default: "ml"
-+
-+-e perform some simple filtering/enhancement to improve image
-+ quality. The images created by using this option will be
-+ stored in the directory specified by the "-w" option (or
-+ "-d" if not present, see above) and each filename will be
-+ prefixed with "eimg" (see "-p" above). Using this option will
-+ take enormous amounts of disk space, and in reality does
-+ not do anything that cannot be done within LiVES itself.
-+ Using this option enables the following four:
-+
-+ -w dir "dir" is the working directory where the enhanced
-+ images will be saved. Although these can all
-+ co-exist with the original LiVES files it is
-+ recommended you use a different directory. Note
-+ that temporary files may take a huge amount of
-+ space, perhaps twice as much as the LiVES files
-+ themselves. If this directory does not exist is
-+ will be created.
-+ Default: same as "-d".
-+
-+ -k keep the temporary files, useful to experiment
-+ with different encoding types without having
-+ to repeatedly enhance the images (which can be
-+ very time-consuming). See "-p" above.
-+
-+ -c geom in addition to enhancing the images, crop them
-+ to the specified geometry e.g. "688x448+17+11".
-+ Filename prefix remains "eimg". Note that the
-+ dimensions of the images should both be multiples
-+ of "16", otherwise some players may show artifacts
-+ (such as garbage or green bars at the borders).
-+
-+ -r geom this will create a second set of images resulting
-+ from resizing the images that have already been
-+ enhanced and possibly cropped (if "-c" has been
-+ specified). The geometry here is simple a new
-+ image size e.g. "352x240!". This second set will have
-+ filenames prefixed with the string "rimg" (see "-p"
-+ above). Note that the dimensions of the images
-+ should both be multiples of "16", otherwise some
-+ players may show artifacts (such as garbage or
-+ green bars at the borders).
-+
-+-s sndfile name of the audio file. Can be either raw "audio" or
-+ "[/path/to/]soundfile.wav".
-+ Default: "audio" inside "dir" as specified by "-d".
-+
-+-b sndrate sample rate of the sound file in Hertz.
-+ Default: "44100".
-+
-+-f fpscode frame-rate code. Acceptable values are:
-+
-+ 1 - 24000.0/1001.0 (NTSC 3:2 pulldown converted FILM)
-+ 2 - 24.0 (NATIVE FILM)
-+ 3 - 25.0 (PAL/SECAM VIDEO / converted FILM)
-+ 4 - 30000.0/1001.0 (NTSC VIDEO)
-+ 5 - 30.0
-+ 6 - 50.0 (PAL FIELD RATE)
-+ 7 - 60000.0/1001.0 (NTSC FIELD RATE)
-+ 8 - 60.0
-+
-+ If the input value is a float (e.g. 5.0, 14.555, etc.)
-+ the encoder will use that as frame rate.
-+
-+ Default: "4".
-+
-+-L lv1file use the images stored in the LiVES file "lv1file" (e.g.
-+ "movie.lv1"). Files will be extracted inside "dir" as
-+ specified by "-d". Using this option allows to encode
-+ a movie without having to restore it first with LiVES.
-+ Note that the encoder will not delete the extracted
-+ files after it has finished, this must be done manually
-+ afterwards. If frame code/rate (-f) and/or sound rate (-b)
-+ are not specified the defaults will be used (30000/1001 fps
-+ and 44100 Hz). These, however, may not be correct, in which
-+ case they should be specified explicitly. Furthermore, the
-+ .lv1 audio (if present) is always assumed to have a sample
-+ data size in 16-bit words with two channels, and to be signed
-+ linear (this is usually the case, however). If any of these
-+ latter parameters are incorrect the resulting file may be
-+ corrupted and encoding will have to be done using LiVES.
-+
-+firstframe first frame number. If less than eight digits long it will
-+ be padded with zeroes e.g. 234 -> 00000234. A prefix can
-+ be added using the "-p" option.
-+ Default: "00000001"
-+
-+lastframe last frame number, padded with zeroes if necessary, prefix
-+ set by "-p".
-+ Default: the last frame of its type in the "-d" directory,
-+ where "type" is set by the prefix.
-+
-+Note that either no frames or both first and last frames must be specified.
-+
-+EXAMPLES:
-+
-+Suppose you have restored a LiVES' .lv1 file (in either JPG or PNG format),
-+and that the images are stored in the directory "/tmp/livestmp/991319584/".
-+In this example the movie is assumed to be 16:9. Then, in order to create
-+an MKV file you can simply do the following:
-+
-+ mkv_encoder.py -d /tmp/livestmp/991319584 -o /movies/default.mkv -a 3
-+
-+and the clip "default.mkv" will be created in "/movies/" with the correct
-+aspect ratio.
-+
-+Suppose we want to make a downloadable version of the clip, small in size
-+but of good quality. The following command activates the generic enhancement
-+filter and resizes the images to "352x240". Note that these operations
-+are performed after cropping the originals a bit (using "704x464+5+6").
-+This is done because we are assuming that there is a black border around
-+the original pictures which we want to get rid of (this might distort the
-+images somewhat, so be careful about cropping/resizing, and remember to
-+use dimensions which are multiples of 16):
-+
-+ mkv_encoder.py -v -d /tmp/livestmp/991319584 -w /tmp/tmpmkv \\
-+ -o /movies/download.mkv -a 3 -k -e -c "704x464+5+6" -r "352x240"
-+
-+Since we use the "-k" flag the enhanced images are kept (both full-size
-+crops and the resized ones) in "/tmp/tmpmkv". Beware that this may consume
-+a lot of disk space (about 10x as much as the originals). The reason we
-+keep them is because the above may take quite a long time and we may want
-+to re-use the enhanced images. So, for example, creating a high-quality
-+clip at full size can be accomplished now as follows:
-+
-+ mkv_encoder.py -d /tmp/tmpmkv -t hi -o /movies/archive.mkv \\
-+ -s /tmp/livestmp/991319584/audio -a 3 -k -p eimg
-+
-+If, for example, we only want to encode frames 100 to 150 we can run
-+the following:
-+
-+ mkv_encoder.py -v -d /tmp/tmpmkv -o /movies/selection.mkv \\
-+ -a 3 -k -p eimg 100 150
-+
-+Note that no audio has been selected ("-s"). This is because
-+mkv_encoder.py cannot trim the audio to the appropriate length.
-+You would need to use LiVES to do this.
-+
-+To delete all the enhanced images you can just remove "/tmp/tmpmkv".
-+
-+If you notice that the video and audio become out of sync so that
-+near the end of the movie the video trails the audio by, say, 0.2s,
-+you can use the "-D" option as follows:
-+
-+ mkv_encoder.py -d /tmp/livestmp/991319584 -o test.mkv -D 200
-+
-+Note that negative time values are also allowed.
-+
-+Suppose that you have "movie1.lv1", "movie2.lv1" and "movie3.lv1".
-+Batch-encoding can be done as follows (zsh-syntax):
-+
-+ for i in movie?.lv1
-+ do
-+ mkdir /tmp/$i:r
-+ mkv_encoder.py -d /tmp/$i:r -o /tmp/$i:r.mkv -L $i
-+ rm -rf /tmp/$i:r
-+ done
-+
-+This will generate the files "movie1.mkv", "movie2.mkv" and
-+"movie3.mkv" in "/tmp". Note that is is not necessary to
-+specify whether the files are stored in JPG or PNG format,
-+and that potentially time-consuming options (e.g. "-e") may
-+be enabled. It is not necessary to have a working LiVES
-+installation to encode .lv1 files.
-+ """ % version
-+
-+def run(command):
-+ """
-+ Run a shell command
-+ """
-+
-+ if verbose:
-+ print 'Running: \n' + command + '\n=== ... ==='
-+ std = ''
-+ else:
-+ std = ' > /dev/null 2>&1'
-+
-+ os.system(command + std)
-+
-+
-+def do_enhance():
-+ """
-+ Image cleanup/crop/resize routine. Generic, but seems to work
-+ well with anime :)
-+ """
-+
-+ if not quiet:
-+ print 'Enhancing images... please wait, this might take long...'
-+
-+ enh_opts = "-enhance -sharpen '0.0x0.5' -gamma 1.2 -contrast -depth 8"
-+
-+ if cgeom:
-+ docrop = ' '.join(['-crop', "'%s!'" % cgeom])
-+ else:
-+ docrop = ''
-+
-+ iframe = first_num
-+ while True:
-+ # File names are padded with zeroes to 8 characters
-+ # (not counting the .ext).
-+ frame = str(iframe).zfill(8)
-+ fname = os.path.join(img_dir, frame + ext)
-+ if not os.path.isfile(fname) or (iframe == last_num + 1):
-+ break
-+ eimg_fname = os.path.join(work_dir, 'eimg' + frame + '.png')
-+ rimg_fname = os.path.join(work_dir, 'rimg' + frame + '.png')
-+ command = ' '.join([convert, docrop, enh_opts, fname, eimg_fname])
-+ run(command)
-+ if rgeom:
-+ if os.path.exists(rimg_fname): os.remove(rimg_fname)
-+ shrink = ' '.join([convert, '-resize', "'%s!'" % rgeom, '-depth 8'])
-+ command = ' '.join([shrink, eimg_fname, rimg_fname])
-+ run(command)
-+ else:
-+ if os.path.exists(rimg_fname): os.remove(rimg_fname)
-+ try:
-+ os.symlink(eimg_fname, rimg_fname)
-+ except (IOError, OSError):
-+ shutil.copy(eimg_fname, rimg_fname)
-+ iframe+=1
-+
-+
-+def do_encode():
-+ """
-+ Encode a series of images into an MPEG-4 stream, multiplexing
-+ audio if necessary
-+ """
-+
-+ if not quiet:
-+ print 'Creating "%s"-quality MPEG-4' % vtype
-+
-+ if verbose:
-+ std = ''
-+ hinfo = '--quiet'
-+ else:
-+ std = ' > /dev/null 2>&1'
-+ hinfo = '--progress'
-+
-+ common_vopts = '-mf type=%s:fps=%s ' % (ext[1:], fps) + \
-+ '-nosound -vf hqdn3d=2:1:3,pp=va:128:8/ha:128:8/dr,dsize=%s' % aspect
-+
-+ if vtype[-1] == 'd':
-+ codec_vopts = '-ovc lavc -lavcopts ' + \
-+ 'vcodec=mpeg4:trell:mbd=2:vmax_b_frames=1:v4mv' + \
-+ ':cmp=2:subcmp=2:precmp=2:predia=1:autoaspect:vbitrate='
-+ cpass = 'vpass='
-+ elif vtype[-1] == 'x':
-+ codec_vopts = '-ovc xvid -xvidencopts qpel:chroma_me:chroma_opt' + \
-+ ':max_bframes=1:autoaspect:hq_ac:vhq=4:bitrate='
-+ cpass = 'pass='
-+ elif vtype[-1] == 'h':
-+ mencoder_opts = common_vopts + ',format=i420 -ovc raw -of rawvideo -o '
-+ codec_vopts = hinfo + ' --fps %s -B' % (fps)
-+ cpass = '--pass '
-+ cpass1opts = '--bframes 3 --b-pyramid --filter 1:1 --weightb ' + \
-+ '--qcomp 0.8 --analyse dia --subme 1 --no-psnr'
-+ cpass2opts = '--bframes 3 --b-pyramid --ref 6 --filter 1:1 --weightb ' + \
-+ '--qcomp 0.8 --analyse all --8x8dct --subme 6 --b-rdo ' + \
-+ '--mixed-refs --bime --trellis 2 --no-fast-pskip'
-+ else:
-+ print 'Unexpected video type.'
-+ raise SystemExit
-+
-+ vqual = vtype[0:-2]
-+ if vqual == 'hi':
-+ if vtype[-1] == 'd': rate = '2000:'
-+ if vtype[-1] == 'x': rate = '2000:'
-+ if vtype[-1] == 'h':
-+ rate = '2000'
-+ x264_opts = ' '.join([codec_vopts, rate, cpass])
-+ else:
-+ mencoder_opts = ' '.join([common_vopts, codec_vopts + rate + cpass])
-+ oggenc_opts = '-q 9'
-+ elif vqual == 'mh':
-+ if vtype[-1] == 'd': rate = '1000:'
-+ if vtype[-1] == 'x': rate = '1000:'
-+ if vtype[-1] == 'h':
-+ rate = '1000'
-+ x264_opts = ' '.join([codec_vopts, rate, cpass])
-+ else:
-+ mencoder_opts = ' '.join([common_vopts, codec_vopts + rate + cpass])
-+ oggenc_opts = '-q 6'
-+ elif vqual == 'ml':
-+ if vtype[-1] == 'd': rate = '500:'
-+ if vtype[-1] == 'x': rate = '500:'
-+ if vtype[-1] == 'h':
-+ rate = '500'
-+ x264_opts = ' '.join([codec_vopts, rate, cpass])
-+ else:
-+ mencoder_opts = ' '.join([common_vopts, codec_vopts + rate + cpass])
-+ oggenc_opts = '-q 4'
-+ elif vqual == 'lo':
-+ if vtype[-1] == 'd': rate = '200:'
-+ if vtype[-1] == 'x': rate = '200:'
-+ if vtype[-1] == 'h':
-+ rate = '200'
-+ x264_opts = ' '.join([codec_vopts, rate, cpass])
-+ else:
-+ mencoder_opts = ' '.join([common_vopts, codec_vopts + rate + cpass])
-+ oggenc_opts = '-q 2'
-+
-+ if img_dir != work_dir and not enhance:
-+ source_dir = img_dir
-+ else:
-+ source_dir = work_dir
-+
-+ x264log = os.path.join(source_dir, 'TMP_x264pass.log')
-+ yuvv = os.path.join(source_dir, 'TMP_YUVstream.yuv')
-+ if vtype[-1] == 'h':
-+ vidv = tempfile.mkstemp('.mkv', '', work_dir)[1]
-+ else:
-+ vidv = tempfile.mkstemp('.mpv', '', work_dir)[1]
-+
-+
-+ if frame_range:
-+ frame_list = [img_pre + str(f).zfill(8) + ext \
-+ for f in range(first_num, last_num + 1)]
-+ syml = 'temporary_symlink_'
-+ for iframe in frame_list:
-+ frfile = os.path.join(source_dir, iframe)
-+ frlink = os.path.join(source_dir, syml + iframe)
-+ if os.path.islink(frlink): os.remove(frlink)
-+ os.symlink(frfile, frlink)
-+ else:
-+ syml = ''
-+
-+ fgeom = os.popen(' '.join([identify, '-format "%w %h"', \
-+ os.path.join(source_dir, \
-+ img_pre + \
-+ first_frame_num + \
-+ ext)])).read().strip().split()
-+ fx = int(fgeom[0])
-+ fy = int(fgeom[1])
-+
-+ all_vars = {}
-+ all_vars.update(globals())
-+ all_vars.update(locals())
-+
-+
-+ if vtype[-1] == 'h':
-+ yuvcommand = """cd %(source_dir)s ; \\
-+mkfifo -m 0600 %(yuvv)s ; \\
-+%(mencoder)s mf://%(syml)s%(img_pre)s*%(ext)s %(mencoder_opts)s%(yuvv)s %(std)s &
-+ """ % all_vars
-+ run(yuvcommand)
-+ command = """cd %(source_dir)s ; \\
-+%(x264)s --stats "%(x264log)s" %(cpass1opts)s %(x264_opts)s1 -o /dev/null %(yuvv)s %(fx)sx%(fy)s %(std)s
-+ """ % all_vars
-+ run(command)
-+ os.remove(yuvv)
-+ run(yuvcommand)
-+ command = """cd %(source_dir)s ; \\
-+%(x264)s --stats "%(x264log)s" %(cpass2opts)s %(x264_opts)s2 -o "%(vidv)s" %(yuvv)s %(fx)sx%(fy)s %(std)s
-+ """ % all_vars
-+ run(command)
-+ os.remove(yuvv)
-+ os.remove(x264log)
-+ else:
-+ command = """cd %(source_dir)s ; \\
-+%(mencoder)s "mf://%(syml)s%(img_pre)s*%(ext)s" %(mencoder_opts)s1 -o /dev/null %(std)s ; \\
-+%(mencoder)s "mf://%(syml)s%(img_pre)s*%(ext)s" %(mencoder_opts)s2 -o %(vidv)s %(std)s
-+ """ % all_vars
-+ run(command)
-+
-+ if os.path.exists(os.path.join(source_dir, 'divx2pass.log')):
-+ os.remove(os.path.join(source_dir, 'divx2pass.log'))
-+ if os.path.exists(os.path.join(source_dir, 'xvid-twopass.stats')):
-+ os.remove(os.path.join(source_dir, 'xvid-twopass.stats'))
-+
-+ if audio:
-+ if not quiet:
-+ print 'Creating "%s"-quality ogg vorbis file' % vtype
-+
-+ ogg = tempfile.mkstemp('.ogg', '', work_dir)[1]
-+ if rawsndf:
-+ wav = tempfile.mkstemp('.wav', '', work_dir)[1]
-+ sox_opts = '-t raw -r %s -w -c 2 -s' % sndr
-+ command = ' '.join([sox, sox_opts, sndf, wav])
-+ run(command)
-+ else:
-+ wav = sndf
-+ command = ' '.join([oggenc, oggenc_opts, wav, '-o', ogg, std])
-+ run(command)
-+
-+ if delay != '0':
-+ totfr = len(glob.glob(os.path.join(source_dir, syml + img_pre + '*' + ext)))
-+ # "delay" is in ms, transform into s
-+ totfrshift = int(totfr + round((locale.atof(delay)/1000.0)*locale.atof(fps)))
-+ delaysh = ',%s/%s' % (totfrshift, totfr)
-+ else:
-+ delaysh = ''
-+
-+ all_vars.update(locals())
-+
-+ if not quiet: print 'Multiplexing...'
-+ command = """
-+%(mkvplex)s --aspect-ratio '1:%(aspect)s' -o "%(vidname)s" %(vidv)s -y '0:0%(delaysh)s' %(ogg)s %(std)s""" % all_vars
-+ run(command)
-+ if rawsndf and os.path.exists(wav): os.remove(wav)
-+ if os.path.exists(ogg): os.remove(ogg)
-+ else:
-+ if not quiet: print 'Multiplexing...'
-+ command = """
-+%(mkvplex)s --aspect-ratio '1:%(aspect)s' -o "%(vidname)s" %(vidv)s %(std)s""" % all_vars
-+ run(command)
-+
-+ if os.path.exists(vidv): os.remove(vidv)
-+
-+ if frame_range:
-+ lframes = os.path.join(source_dir, syml)
-+ for frame in glob.glob(lframes + '*'):
-+ os.remove(frame)
-+
-+
-+def do_clean():
-+ """
-+ Delete enhanced files
-+ """
-+
-+ if not quiet:
-+ print 'Deleting all enhanced images (if any)'
-+
-+ eframes = os.path.join(work_dir, 'eimg')
-+ rframes = os.path.join(work_dir, 'rimg')
-+ for frame in glob.glob(eframes + '*'):
-+ os.remove(frame)
-+ for frame in glob.glob(rframes + '*'):
-+ os.remove(frame)
-+
-+
-+def which(command):
-+ """
-+ Finds (or not) a command a la "which"
-+ """
-+
-+ command_found = False
-+
-+ if command[0] == '/':
-+ if os.path.isfile(command) and \
-+ os.access(command, os.X_OK):
-+ command_found = True
-+ abs_command = command
-+ else:
-+ path = os.environ.get('PATH', '').split(os.pathsep)
-+ for dir in path:
-+ abs_command = os.path.join(dir, command)
-+ if os.path.isfile(abs_command) and \
-+ os.access(abs_command, os.X_OK):
-+ command_found = True
-+ break
-+
-+ if not command_found:
-+ abs_command = ''
-+
-+ return abs_command
-+
-+
-+def is_installed(prog):
-+ """
-+ See whether "prog" is installed
-+ """
-+
-+ wprog = which(prog)
-+
-+ if wprog == '':
-+ print prog + ': command not found'
-+ raise SystemExit
-+ else:
-+ if verbose:
-+ print wprog + ': found'
-+
-+
-+if __name__ == '__main__':
-+
-+ import os
-+ import sys
-+ import getopt
-+ import shutil
-+ import tempfile
-+ import glob
-+ import tarfile
-+
-+ try:
-+ if sys.version_info[0:3] < (2, 3, 0):
-+ raise SystemExit
-+ except:
-+ print 'You need Python 2.3.0 or greater to run me!'
-+ raise SystemExit
-+
-+ try:
-+ (opts, args) = getopt.getopt(sys.argv[1:], \
-+ 'ho:p:d:w:a:qvt:ekc:r:s:b:f:VCD:L:')
-+ except:
-+ print "Something's wrong. Try the '-h' flag."
-+ raise SystemExit
-+
-+ opts = dict(opts)
-+
-+ if not opts and not args:
-+ print usage
-+ raise SystemExit
-+
-+ if '-h' in opts:
-+ print usage + help
-+ raise SystemExit
-+
-+ if '-V' in opts:
-+ print 'mkv_encoder.py version ' + version
-+ raise SystemExit
-+
-+ if ('-v' in opts) or ('-C' in opts):
-+ verbose = True
-+ else:
-+ verbose = False
-+
-+ if '-q' in opts:
-+ quiet = True
-+ verbose = False
-+ else:
-+ quiet = False
-+
-+ for i in [convert, mencoder, oggenc, sox, mkvplex, x264, identify]:
-+ is_installed(i)
-+ if '-C' in opts: raise SystemExit
-+
-+ img_pre = opts.get('-p', '')
-+
-+ if img_pre not in ['', 'eimg', 'rimg']:
-+ print 'Improper image name prefix.'
-+ raise SystemExit
-+
-+ temp_dir = ''
-+ img_dir = opts.get('-d', '.')
-+ img_dir = os.path.abspath(img_dir)
-+ if ' ' in img_dir:
-+ temp_dir = tempfile.mkdtemp('', '.lives-', '/tmp/')
-+ os.symlink(img_dir, temp_dir + '/img_dir')
-+ img_dir = temp_dir + '/img_dir'
-+
-+ if not os.path.isdir(img_dir):
-+ print 'The image source directory: ' + img_dir + \
-+ ' does not exist!'
-+ raise SystemExit
-+
-+ if len(args) not in [0, 2]:
-+ print 'If frames are specified both first and last ' + \
-+ 'image numbers must be chosen.'
-+ raise SystemExit
-+ elif len(args) == 0:
-+ args = [None, None]
-+
-+ frame_range = False
-+ if not args[0]:
-+ first_frame_num = '1'
-+ else:
-+ frame_range = True
-+ first_frame_num = args[0]
-+ first_frame_num = first_frame_num.zfill(8)
-+ first_num = int(first_frame_num)
-+
-+ if not args[1]:
-+ last_frame_num = '99999999'
-+ else:
-+ last_frame_num = args[1]
-+ last_frame_num = last_frame_num.zfill(8)
-+ last_num = int(last_frame_num)
-+
-+ aspectc = opts.get('-a', '2')
-+
-+ if aspectc not in [str(i) for i in xrange(1,5)]:
-+ print 'Invalid aspect ratio.'
-+ raise SystemExit
-+ else:
-+ if aspectc == '1': aspect = '1/1'
-+ elif aspectc == '2': aspect = '4/3'
-+ elif aspectc == '3': aspect = '16/9'
-+ elif aspectc == '4': aspect = '2.21/1'
-+
-+ vtype = opts.get('-t', 'ml')
-+
-+ out_mkv = opts.get('-o', vtype + '_movie.mkv')
-+
-+ if '_' not in vtype:
-+ vtype = vtype + '_x'
-+
-+ if vtype not in ['hi_d', 'mh_d', 'ml_d', 'lo_d', \
-+ 'hi_x', 'mh_x', 'ml_x', 'lo_x', \
-+ 'hi_h', 'mh_h', 'ml_h', 'lo_h']:
-+ print 'Invalid video type.'
-+ raise SystemExit
-+
-+ fpsc = opts.get('-f', '4')
-+
-+ if fpsc not in [str(i) for i in xrange(1,9)]:
-+ if not quiet: print 'Invalid fps code, attempting float fps.'
-+ foundfps = False
-+ else:
-+ if fpsc == '1': fps = str(24000.0/1001.0)
-+ elif fpsc == '2': fps = str(24.0)
-+ elif fpsc == '3': fps = str(25.0)
-+ elif fpsc == '4': fps = str(30000.0/1001.0)
-+ elif fpsc == '5': fps = str(30.0)
-+ elif fpsc == '6': fps = str(50.0)
-+ elif fpsc == '7': fps = str(60000.0/1001.0)
-+ elif fpsc == '8': fps = str(60.0)
-+ foundfps = True
-+
-+ if not foundfps:
-+ try:
-+ fps = locale.atof(fpsc)
-+ if not quiet: print 'Using fps = %s' % fps
-+ if fps > 0: foundfps = True
-+ except:
-+ pass
-+
-+ if not foundfps:
-+ print 'Invalid fps code or rate.'
-+ raise SystemExit
-+
-+ if '-e' not in opts:
-+ enhance = False
-+ else:
-+ enhance = True
-+
-+ if enhance and img_pre:
-+ print 'Sorry, you cannot enhance already-enhanced images'
-+ raise SystemExit
-+
-+ if '-k' not in opts:
-+ keep = False
-+ else:
-+ keep = True
-+
-+ cgeom = opts.get('-c', '')
-+ rgeom = opts.get('-r', '')
-+
-+ if (cgeom or rgeom) and not enhance:
-+ print 'Missing "-e" option.'
-+ raise SystemExit
-+
-+ lv1file = opts.get('-L', None)
-+ if lv1file:
-+ if not quiet: print 'Opening lv1 file...'
-+ try:
-+ lv1 = tarfile.open(os.path.abspath(lv1file))
-+ except:
-+ print 'This does not appear to be a valid LiVES file!'
-+ raise SystemExit
-+ if 'header.tar' not in lv1.getnames():
-+ print 'This does not appear to be a valid LiVES file!'
-+ raise SystemExit
-+ for tfile in lv1.getmembers():
-+ lv1.extract(tfile, img_dir)
-+ for tfile in glob.glob(os.path.join(img_dir, '*.tar')):
-+ imgtar = tarfile.open(tfile)
-+ for img in imgtar.getmembers():
-+ imgtar.extract(img, img_dir)
-+ os.remove(tfile)
-+
-+ test_file = os.path.join(img_dir, img_pre + first_frame_num)
-+ if os.path.isfile(test_file + '.jpg'):
-+ ext = '.jpg'
-+ elif os.path.isfile(test_file + '.png'):
-+ ext = '.png'
-+ else:
-+ print 'Cannot find any appropriate %s or %s files!' % ('.jpg','.png')
-+ raise SystemExit
-+ first_frame = test_file + ext
-+ last_frame = os.path.join(img_dir, img_pre + last_frame_num + ext)
-+
-+ if not quiet: print 'Found: ' + first_frame
-+
-+ work_dir = opts.get('-w', img_dir)
-+ work_dir = os.path.abspath(work_dir)
-+ if not os.path.isdir(work_dir):
-+ if not quiet: print 'Creating ' + work_dir
-+ try:
-+ os.makedirs(work_dir)
-+ os.chmod(work_dir, 0755)
-+ except:
-+ print 'Could not create the work directory ' + \
-+ work_dir
-+ raise SystemExit
-+ if ' ' in work_dir:
-+ if temp_dir == '':
-+ temp_dir = tempfile.mkdtemp('', '.lives-', '/tmp/')
-+ os.symlink(work_dir, temp_dir + '/work_dir')
-+ work_dir = temp_dir + '/work_dir'
-+
-+ sndf = opts.get('-s', os.path.join(img_dir, 'audio'))
-+# sndf = os.path.abspath(sndf)
-+ rawsndf = True
-+ if not os.path.isfile(sndf):
-+ audio = False
-+ rawsndf = False
-+ else:
-+ audio = True
-+ if sndf[-4:] == '.wav':
-+ rawsndf = False
-+ if not quiet: print 'Found audio file: ' + sndf
-+
-+ sndr = opts.get('-b', '44100')
-+
-+ delay = opts.get('-D', '0')
-+ if verbose and audio: print 'Linear audio delay (ms): ' + delay
-+
-+ if enhance:
-+ do_enhance()
-+ # Note that do_enhance() always creates images prefixed
-+ # with 'rimg'. What's important to note if that if the
-+ # images are resized the 'rimg' are indeed resized, but
-+ # if not the 'rimg' are simply symlinks to the 'eimg'
-+ # (enhanced) images.
-+ img_pre = 'rimg'
-+ ext = '.png'
-+ vidname = os.path.join(work_dir, out_mkv)
-+ # do_encode() acts on images prefixed by img_pre.
-+ do_encode()
-+ if not keep:
-+ do_clean()
-+ if temp_dir != '':
-+ shutil.rmtree(temp_dir)
-+ if not quiet: print "Done!"
-+
-+
-+"""
-+CHANGELOG:
-+
-+21 Jul 2004 : 0.0.2 : added support for ".wav" files.
-+ added '-C' flag.
-+28 Jul 2004 : 0.0.3 : added '-D' flag.
-+ fixed typos.
-+ eliminated some subshell calls.
-+ convert dirs to absolute paths.
-+ fixed frame range detection.
-+ fixed work_dir permissions.
-+30 Jul 2004 : 0.0.4 : added '-L' flag.
-+ encoder is now feature-complete.
-+25 Sep 2004 : 0.0.5 : make sure "rawsndf" is set correctly.
-+ check if files exist before removing.
-+02 Oct 2004 : 0.0.6 : multiplex even if no audio.
-+28 Oct 2004 : 0.0.7 : can handle arbitrary fps values.
-+02 Nov 2004 : 0.0.8 : added XviD encoding.
-+08 Nov 2004 : 0.0.9 : make sure that the enhanced
-+ color depth is 8-bits/channel.
-+ fixed XviD aspect ratio.
-+ added chroma_opt to XviD.
-+02 Jan 2005 : 0.1.0 : updated docs.
-+ added sound rate (-b) option.
-+26 Mar 2005 : 0.1.1 : use env python (hopefully >= 2.3).
-+ replace denoise3d with hqdn3d.
-+24 Aug 2005 : 0.1.2 : fixed 2.21:1 aspect ratio.
-+ fine-tune mplayer filters.
-+09 Mar 2006 : 0.1.3 : added '-depth 8' to resize, as ImageMagick
-+ keeps changing its damn behaviour.
-+ fixed bitrate levels.
-+12 Mar 2006 : 0.1.4 : added h.264 codec.
-+ tweaked bitrate levels.
-+ fixed audio delay.
-+28 Jun 2007 : 0.1.5 : handles paths with spaces appropriately
-+ (thanks Gabriel).
-+"""
---- lives.orig/lives-plugins/marcos-encoders/mkv_encoder.py
-+++ /dev/null
-@@ -1,888 +0,0 @@
--#!/usr/bin/env python
--
--"""
--mkv_encoder.py
--
--Front-end to various programs needed to create MKV (Matroska)
--movies with some image-enhancing capabilities through the use of
--ImageMagick. Meant as a companion to LiVES (to possibly call
--from within a plugin, see http://www.xs4all.nl/~salsaman/lives/ )
--but can also be used as a stand-alone program.
--
--Requires MPlayer, ImageMagick (GraphicsMagick might also
--work), sox, Oggenc, MKVtoolnix and Python 2.3.0 or greater.
--
--Copyright (C) 2004-2005 Marco De la Cruz (marco at reimeika.ca)
--It's a trivial program, but might as well GPL it, so see:
--http://www.gnu.org/copyleft/gpl.html for license.
--
--See my vids at http://amv.reimeika.ca !
--"""
--
--version = '0.1.5'
--convert = 'convert'
--mencoder = 'mencoder'
--x264 = 'x264'
--oggenc = 'oggenc'
--sox = 'sox'
--mkvplex = 'mkvmerge'
--identify = 'identify'
--
--usage = \
-- """
--mkv_encoder.py -h
--mkv_encoder.py -V
--mkv_encoder.py -C
--mkv_encoder.py [-o out] [-p pre] [-d dir] [-a aspect] [-D delay]
-- [-q|-v] [-t type] [-k] [-e [[-w dir] [-c geom] [-r geom]]]
-- [-s sndfile] [-b sndrate] [-f fpscode] [-L lv1file]
-- [firstframe lastframe]
-- """
--
--help = \
-- """
--SUMMARY (ver. %s):
--
--Encodes a series of PNG or JPG images into an MPEG-4/Ogg Vorbis
--(MKV) stream and is also capable of performing some simple image
--enhacements using ImageMagick. The images and audio are assumed to
--be in an uncompressed LiVES format, hence making this encoder
--more suitable to be used within a LiVES plugin (but can also
--be used directly on a LiVES temporary directory).
--
--OPTIONS:
--
---h for help.
--
---V shows the version number.
--
---C check external program dependencies and exit.
--
---o out will save the video in file "out".
-- Default: "'type'_movie.mkv". See below for 'type'.
--
---p pre the encoder assumes that sound and images are named using
-- LiVES' conventions i.e. "audio" and "00000001.ext",
-- "00000002.ext"... where "ext" is either "jpg" or "png".
-- However, mkv_encoder.py will create temporary files
-- which can be saved for later use (for example, after
-- enhancing the images with "-e" , which may take a long
-- time). These temporary files will be named
-- "pre_00000001.ext", etc... where "pre" is either "eimg"
-- or "rimg" and will be kept if the "-k" option is used.
-- mkv_encoder.py can then be run over the enhanced images
-- only by selecting the appropriate prefix ("eimg" or
-- "rimg") here. See "-e" to see what each prefix means.
-- Default: "" (an empty string).
--
---d dir "dir" is the directory containing the source image
-- files. These must be of the form "00000001.ext" or
-- "pre_00000001.ext" as explained above.
-- Default: "."
--
---a aspect sets the aspect ratio of the resulting MPEG-4. This can be:
--
-- 1 1:1 display
-- 2 4:3 display
-- 3 16:9 display
-- 4 2.21:1 display
--
-- Default: "2"
--
---D delay linearly delay the audio stream by "delay" ms.
-- Default: "0"
--
---q quiet operation, only complains on error.
--
---v be verbose.
--
---t type type of video created. The options here are:
--
-- "hi": a very high quality XviD file, suitable
-- for archiving images of 720x480.
--
-- "mh": medium-high quality XviD, which still allows
-- to watch small videos (352x240 and below)
-- fullscreen.
--
-- "ml": medium-low quality XviD, suitable for
-- most videos but in particular small videos
-- (352x240 and below) meant for online
-- distribution.
--
-- "lo": a low quality XviD format. Enlarging
-- small videos will result in noticeable
-- artifacts. Good for distributing over slow
-- connections.
--
-- "hi_x", "mh_x", "ml_x", "lo_x": same as above.
--
-- "hi_h", "mh_h", "ml_h", "lo_h": same as above, but
-- using the h.264 codec.
--
-- "hi_d", "mh_d", "ml_d", "lo_d": same as above, but
-- using DivX 4/5 encoding.
--
-- Default: "ml"
--
---e perform some simple filtering/enhancement to improve image
-- quality. The images created by using this option will be
-- stored in the directory specified by the "-w" option (or
-- "-d" if not present, see above) and each filename will be
-- prefixed with "eimg" (see "-p" above). Using this option will
-- take enormous amounts of disk space, and in reality does
-- not do anything that cannot be done within LiVES itself.
-- Using this option enables the following four:
--
-- -w dir "dir" is the working directory where the enhanced
-- images will be saved. Although these can all
-- co-exist with the original LiVES files it is
-- recommended you use a different directory. Note
-- that temporary files may take a huge amount of
-- space, perhaps twice as much as the LiVES files
-- themselves. If this directory does not exist is
-- will be created.
-- Default: same as "-d".
--
-- -k keep the temporary files, useful to experiment
-- with different encoding types without having
-- to repeatedly enhance the images (which can be
-- very time-consuming). See "-p" above.
--
-- -c geom in addition to enhancing the images, crop them
-- to the specified geometry e.g. "688x448+17+11".
-- Filename prefix remains "eimg". Note that the
-- dimensions of the images should both be multiples
-- of "16", otherwise some players may show artifacts
-- (such as garbage or green bars at the borders).
--
-- -r geom this will create a second set of images resulting
-- from resizing the images that have already been
-- enhanced and possibly cropped (if "-c" has been
-- specified). The geometry here is simple a new
-- image size e.g. "352x240!". This second set will have
-- filenames prefixed with the string "rimg" (see "-p"
-- above). Note that the dimensions of the images
-- should both be multiples of "16", otherwise some
-- players may show artifacts (such as garbage or
-- green bars at the borders).
--
---s sndfile name of the audio file. Can be either raw "audio" or
-- "[/path/to/]soundfile.wav".
-- Default: "audio" inside "dir" as specified by "-d".
--
---b sndrate sample rate of the sound file in Hertz.
-- Default: "44100".
--
---f fpscode frame-rate code. Acceptable values are:
--
-- 1 - 24000.0/1001.0 (NTSC 3:2 pulldown converted FILM)
-- 2 - 24.0 (NATIVE FILM)
-- 3 - 25.0 (PAL/SECAM VIDEO / converted FILM)
-- 4 - 30000.0/1001.0 (NTSC VIDEO)
-- 5 - 30.0
-- 6 - 50.0 (PAL FIELD RATE)
-- 7 - 60000.0/1001.0 (NTSC FIELD RATE)
-- 8 - 60.0
--
-- If the input value is a float (e.g. 5.0, 14.555, etc.)
-- the encoder will use that as frame rate.
--
-- Default: "4".
--
---L lv1file use the images stored in the LiVES file "lv1file" (e.g.
-- "movie.lv1"). Files will be extracted inside "dir" as
-- specified by "-d". Using this option allows to encode
-- a movie without having to restore it first with LiVES.
-- Note that the encoder will not delete the extracted
-- files after it has finished, this must be done manually
-- afterwards. If frame code/rate (-f) and/or sound rate (-b)
-- are not specified the defaults will be used (30000/1001 fps
-- and 44100 Hz). These, however, may not be correct, in which
-- case they should be specified explicitly. Furthermore, the
-- .lv1 audio (if present) is always assumed to have a sample
-- data size in 16-bit words with two channels, and to be signed
-- linear (this is usually the case, however). If any of these
-- latter parameters are incorrect the resulting file may be
-- corrupted and encoding will have to be done using LiVES.
--
--firstframe first frame number. If less than eight digits long it will
-- be padded with zeroes e.g. 234 -> 00000234. A prefix can
-- be added using the "-p" option.
-- Default: "00000001"
--
--lastframe last frame number, padded with zeroes if necessary, prefix
-- set by "-p".
-- Default: the last frame of its type in the "-d" directory,
-- where "type" is set by the prefix.
--
--Note that either no frames or both first and last frames must be specified.
--
--EXAMPLES:
--
--Suppose you have restored a LiVES' .lv1 file (in either JPG or PNG format),
--and that the images are stored in the directory "/tmp/livestmp/991319584/".
--In this example the movie is assumed to be 16:9. Then, in order to create
--an MKV file you can simply do the following:
--
-- mkv_encoder.py -d /tmp/livestmp/991319584 -o /movies/default.mkv -a 3
--
--and the clip "default.mkv" will be created in "/movies/" with the correct
--aspect ratio.
--
--Suppose we want to make a downloadable version of the clip, small in size
--but of good quality. The following command activates the generic enhancement
--filter and resizes the images to "352x240". Note that these operations
--are performed after cropping the originals a bit (using "704x464+5+6").
--This is done because we are assuming that there is a black border around
--the original pictures which we want to get rid of (this might distort the
--images somewhat, so be careful about cropping/resizing, and remember to
--use dimensions which are multiples of 16):
--
-- mkv_encoder.py -v -d /tmp/livestmp/991319584 -w /tmp/tmpmkv \\
-- -o /movies/download.mkv -a 3 -k -e -c "704x464+5+6" -r "352x240"
--
--Since we use the "-k" flag the enhanced images are kept (both full-size
--crops and the resized ones) in "/tmp/tmpmkv". Beware that this may consume
--a lot of disk space (about 10x as much as the originals). The reason we
--keep them is because the above may take quite a long time and we may want
--to re-use the enhanced images. So, for example, creating a high-quality
--clip at full size can be accomplished now as follows:
--
-- mkv_encoder.py -d /tmp/tmpmkv -t hi -o /movies/archive.mkv \\
-- -s /tmp/livestmp/991319584/audio -a 3 -k -p eimg
--
--If, for example, we only want to encode frames 100 to 150 we can run
--the following:
--
-- mkv_encoder.py -v -d /tmp/tmpmkv -o /movies/selection.mkv \\
-- -a 3 -k -p eimg 100 150
--
--Note that no audio has been selected ("-s"). This is because
--mkv_encoder.py cannot trim the audio to the appropriate length.
--You would need to use LiVES to do this.
--
--To delete all the enhanced images you can just remove "/tmp/tmpmkv".
--
--If you notice that the video and audio become out of sync so that
--near the end of the movie the video trails the audio by, say, 0.2s,
--you can use the "-D" option as follows:
--
-- mkv_encoder.py -d /tmp/livestmp/991319584 -o test.mkv -D 200
--
--Note that negative time values are also allowed.
--
--Suppose that you have "movie1.lv1", "movie2.lv1" and "movie3.lv1".
--Batch-encoding can be done as follows (zsh-syntax):
--
-- for i in movie?.lv1
-- do
-- mkdir /tmp/$i:r
-- mkv_encoder.py -d /tmp/$i:r -o /tmp/$i:r.mkv -L $i
-- rm -rf /tmp/$i:r
-- done
--
--This will generate the files "movie1.mkv", "movie2.mkv" and
--"movie3.mkv" in "/tmp". Note that is is not necessary to
--specify whether the files are stored in JPG or PNG format,
--and that potentially time-consuming options (e.g. "-e") may
--be enabled. It is not necessary to have a working LiVES
--installation to encode .lv1 files.
-- """ % version
--
--def run(command):
-- """
-- Run a shell command
-- """
--
-- if verbose:
-- print 'Running: \n' + command + '\n=== ... ==='
-- std = ''
-- else:
-- std = ' > /dev/null 2>&1'
--
-- os.system(command + std)
--
--
--def do_enhance():
-- """
-- Image cleanup/crop/resize routine. Generic, but seems to work
-- well with anime :)
-- """
--
-- if not quiet:
-- print 'Enhancing images... please wait, this might take long...'
--
-- enh_opts = "-enhance -sharpen '0.0x0.5' -gamma 1.2 -contrast -depth 8"
--
-- if cgeom:
-- docrop = ' '.join(['-crop', "'%s!'" % cgeom])
-- else:
-- docrop = ''
--
-- iframe = first_num
-- while True:
-- # File names are padded with zeroes to 8 characters
-- # (not counting the .ext).
-- frame = str(iframe).zfill(8)
-- fname = os.path.join(img_dir, frame + ext)
-- if not os.path.isfile(fname) or (iframe == last_num + 1):
-- break
-- eimg_fname = os.path.join(work_dir, 'eimg' + frame + '.png')
-- rimg_fname = os.path.join(work_dir, 'rimg' + frame + '.png')
-- command = ' '.join([convert, docrop, enh_opts, fname, eimg_fname])
-- run(command)
-- if rgeom:
-- if os.path.exists(rimg_fname): os.remove(rimg_fname)
-- shrink = ' '.join([convert, '-resize', "'%s!'" % rgeom, '-depth 8'])
-- command = ' '.join([shrink, eimg_fname, rimg_fname])
-- run(command)
-- else:
-- if os.path.exists(rimg_fname): os.remove(rimg_fname)
-- try:
-- os.symlink(eimg_fname, rimg_fname)
-- except (IOError, OSError):
-- shutil.copy(eimg_fname, rimg_fname)
-- iframe+=1
--
--
--def do_encode():
-- """
-- Encode a series of images into an MPEG-4 stream, multiplexing
-- audio if necessary
-- """
--
-- if not quiet:
-- print 'Creating "%s"-quality MPEG-4' % vtype
--
-- if verbose:
-- std = ''
-- hinfo = '--quiet'
-- else:
-- std = ' > /dev/null 2>&1'
-- hinfo = '--progress'
--
-- common_vopts = '-mf type=%s:fps=%s ' % (ext[1:], fps) + \
-- '-nosound -vf hqdn3d=2:1:3,pp=va:128:8/ha:128:8/dr,dsize=%s' % aspect
--
-- if vtype[-1] == 'd':
-- codec_vopts = '-ovc lavc -lavcopts ' + \
-- 'vcodec=mpeg4:trell:mbd=2:vmax_b_frames=1:v4mv' + \
-- ':cmp=2:subcmp=2:precmp=2:predia=1:autoaspect:vbitrate='
-- cpass = 'vpass='
-- elif vtype[-1] == 'x':
-- codec_vopts = '-ovc xvid -xvidencopts qpel:chroma_me:chroma_opt' + \
-- ':max_bframes=1:autoaspect:hq_ac:vhq=4:bitrate='
-- cpass = 'pass='
-- elif vtype[-1] == 'h':
-- mencoder_opts = common_vopts + ',format=i420 -ovc raw -of rawvideo -o '
-- codec_vopts = hinfo + ' --fps %s -B' % (fps)
-- cpass = '--pass '
-- cpass1opts = '--bframes 3 --b-pyramid --filter 1:1 --weightb ' + \
-- '--qcomp 0.8 --analyse dia --subme 1 --no-psnr'
-- cpass2opts = '--bframes 3 --b-pyramid --ref 6 --filter 1:1 --weightb ' + \
-- '--qcomp 0.8 --analyse all --8x8dct --subme 6 --b-rdo ' + \
-- '--mixed-refs --bime --trellis 2 --no-fast-pskip'
-- else:
-- print 'Unexpected video type.'
-- raise SystemExit
--
-- vqual = vtype[0:-2]
-- if vqual == 'hi':
-- if vtype[-1] == 'd': rate = '2000:'
-- if vtype[-1] == 'x': rate = '2000:'
-- if vtype[-1] == 'h':
-- rate = '2000'
-- x264_opts = ' '.join([codec_vopts, rate, cpass])
-- else:
-- mencoder_opts = ' '.join([common_vopts, codec_vopts + rate + cpass])
-- oggenc_opts = '-q 9'
-- elif vqual == 'mh':
-- if vtype[-1] == 'd': rate = '1000:'
-- if vtype[-1] == 'x': rate = '1000:'
-- if vtype[-1] == 'h':
-- rate = '1000'
-- x264_opts = ' '.join([codec_vopts, rate, cpass])
-- else:
-- mencoder_opts = ' '.join([common_vopts, codec_vopts + rate + cpass])
-- oggenc_opts = '-q 6'
-- elif vqual == 'ml':
-- if vtype[-1] == 'd': rate = '500:'
-- if vtype[-1] == 'x': rate = '500:'
-- if vtype[-1] == 'h':
-- rate = '500'
-- x264_opts = ' '.join([codec_vopts, rate, cpass])
-- else:
-- mencoder_opts = ' '.join([common_vopts, codec_vopts + rate + cpass])
-- oggenc_opts = '-q 4'
-- elif vqual == 'lo':
-- if vtype[-1] == 'd': rate = '200:'
-- if vtype[-1] == 'x': rate = '200:'
-- if vtype[-1] == 'h':
-- rate = '200'
-- x264_opts = ' '.join([codec_vopts, rate, cpass])
-- else:
-- mencoder_opts = ' '.join([common_vopts, codec_vopts + rate + cpass])
-- oggenc_opts = '-q 2'
--
-- if img_dir != work_dir and not enhance:
-- source_dir = img_dir
-- else:
-- source_dir = work_dir
--
-- x264log = os.path.join(source_dir, 'TMP_x264pass.log')
-- yuvv = os.path.join(source_dir, 'TMP_YUVstream.yuv')
-- if vtype[-1] == 'h':
-- vidv = tempfile.mkstemp('.mkv', '', work_dir)[1]
-- else:
-- vidv = tempfile.mkstemp('.mpv', '', work_dir)[1]
--
--
-- if frame_range:
-- frame_list = [img_pre + str(f).zfill(8) + ext \
-- for f in range(first_num, last_num + 1)]
-- syml = 'temporary_symlink_'
-- for iframe in frame_list:
-- frfile = os.path.join(source_dir, iframe)
-- frlink = os.path.join(source_dir, syml + iframe)
-- if os.path.islink(frlink): os.remove(frlink)
-- os.symlink(frfile, frlink)
-- else:
-- syml = ''
--
-- fgeom = os.popen(' '.join([identify, '-format "%w %h"', \
-- os.path.join(source_dir, \
-- img_pre + \
-- first_frame_num + \
-- ext)])).read().strip().split()
-- fx = int(fgeom[0])
-- fy = int(fgeom[1])
--
-- all_vars = {}
-- all_vars.update(globals())
-- all_vars.update(locals())
--
--
-- if vtype[-1] == 'h':
-- yuvcommand = """cd %(source_dir)s ; \\
--mkfifo -m 0600 %(yuvv)s ; \\
--%(mencoder)s mf://%(syml)s%(img_pre)s*%(ext)s %(mencoder_opts)s%(yuvv)s %(std)s &
-- """ % all_vars
-- run(yuvcommand)
-- command = """cd %(source_dir)s ; \\
--%(x264)s --stats "%(x264log)s" %(cpass1opts)s %(x264_opts)s1 -o /dev/null %(yuvv)s %(fx)sx%(fy)s %(std)s
-- """ % all_vars
-- run(command)
-- os.remove(yuvv)
-- run(yuvcommand)
-- command = """cd %(source_dir)s ; \\
--%(x264)s --stats "%(x264log)s" %(cpass2opts)s %(x264_opts)s2 -o "%(vidv)s" %(yuvv)s %(fx)sx%(fy)s %(std)s
-- """ % all_vars
-- run(command)
-- os.remove(yuvv)
-- os.remove(x264log)
-- else:
-- command = """cd %(source_dir)s ; \\
--%(mencoder)s "mf://%(syml)s%(img_pre)s*%(ext)s" %(mencoder_opts)s1 -o /dev/null %(std)s ; \\
--%(mencoder)s "mf://%(syml)s%(img_pre)s*%(ext)s" %(mencoder_opts)s2 -o %(vidv)s %(std)s
-- """ % all_vars
-- run(command)
--
-- if os.path.exists(os.path.join(source_dir, 'divx2pass.log')):
-- os.remove(os.path.join(source_dir, 'divx2pass.log'))
-- if os.path.exists(os.path.join(source_dir, 'xvid-twopass.stats')):
-- os.remove(os.path.join(source_dir, 'xvid-twopass.stats'))
--
-- if audio:
-- if not quiet:
-- print 'Creating "%s"-quality ogg vorbis file' % vtype
--
-- ogg = tempfile.mkstemp('.ogg', '', work_dir)[1]
-- if rawsndf:
-- wav = tempfile.mkstemp('.wav', '', work_dir)[1]
-- sox_opts = '-t raw -r %s -w -c 2 -s' % sndr
-- command = ' '.join([sox, sox_opts, sndf, wav])
-- run(command)
-- else:
-- wav = sndf
-- command = ' '.join([oggenc, oggenc_opts, wav, '-o', ogg, std])
-- run(command)
--
-- if delay != '0':
-- totfr = len(glob.glob(os.path.join(source_dir, syml + img_pre + '*' + ext)))
-- # "delay" is in ms, transform into s
-- totfrshift = int(totfr + round((locale.atof(delay)/1000.0)*locale.atof(fps)))
-- delaysh = ',%s/%s' % (totfrshift, totfr)
-- else:
-- delaysh = ''
--
-- all_vars.update(locals())
--
-- if not quiet: print 'Multiplexing...'
-- command = """
--%(mkvplex)s --aspect-ratio '1:%(aspect)s' -o "%(vidname)s" %(vidv)s -y '0:0%(delaysh)s' %(ogg)s %(std)s""" % all_vars
-- run(command)
-- if rawsndf and os.path.exists(wav): os.remove(wav)
-- if os.path.exists(ogg): os.remove(ogg)
-- else:
-- if not quiet: print 'Multiplexing...'
-- command = """
--%(mkvplex)s --aspect-ratio '1:%(aspect)s' -o "%(vidname)s" %(vidv)s %(std)s""" % all_vars
-- run(command)
--
-- if os.path.exists(vidv): os.remove(vidv)
--
-- if frame_range:
-- lframes = os.path.join(source_dir, syml)
-- for frame in glob.glob(lframes + '*'):
-- os.remove(frame)
--
--
--def do_clean():
-- """
-- Delete enhanced files
-- """
--
-- if not quiet:
-- print 'Deleting all enhanced images (if any)'
--
-- eframes = os.path.join(work_dir, 'eimg')
-- rframes = os.path.join(work_dir, 'rimg')
-- for frame in glob.glob(eframes + '*'):
-- os.remove(frame)
-- for frame in glob.glob(rframes + '*'):
-- os.remove(frame)
--
--
--def which(command):
-- """
-- Finds (or not) a command a la "which"
-- """
--
-- command_found = False
--
-- if command[0] == '/':
-- if os.path.isfile(command) and \
-- os.access(command, os.X_OK):
-- command_found = True
-- abs_command = command
-- else:
-- path = os.environ.get('PATH', '').split(os.pathsep)
-- for dir in path:
-- abs_command = os.path.join(dir, command)
-- if os.path.isfile(abs_command) and \
-- os.access(abs_command, os.X_OK):
-- command_found = True
-- break
--
-- if not command_found:
-- abs_command = ''
--
-- return abs_command
--
--
--def is_installed(prog):
-- """
-- See whether "prog" is installed
-- """
--
-- wprog = which(prog)
--
-- if wprog == '':
-- print prog + ': command not found'
-- raise SystemExit
-- else:
-- if verbose:
-- print wprog + ': found'
--
--
--if __name__ == '__main__':
--
-- import os
-- import sys
-- import getopt
-- import shutil
-- import tempfile
-- import glob
-- import tarfile
--
-- try:
-- if sys.version_info[0:3] < (2, 3, 0):
-- raise SystemExit
-- except:
-- print 'You need Python 2.3.0 or greater to run me!'
-- raise SystemExit
--
-- try:
-- (opts, args) = getopt.getopt(sys.argv[1:], \
-- 'ho:p:d:w:a:qvt:ekc:r:s:b:f:VCD:L:')
-- except:
-- print "Something's wrong. Try the '-h' flag."
-- raise SystemExit
--
-- opts = dict(opts)
--
-- if not opts and not args:
-- print usage
-- raise SystemExit
--
-- if '-h' in opts:
-- print usage + help
-- raise SystemExit
--
-- if '-V' in opts:
-- print 'mkv_encoder.py version ' + version
-- raise SystemExit
--
-- if ('-v' in opts) or ('-C' in opts):
-- verbose = True
-- else:
-- verbose = False
--
-- if '-q' in opts:
-- quiet = True
-- verbose = False
-- else:
-- quiet = False
--
-- for i in [convert, mencoder, oggenc, sox, mkvplex, x264, identify]:
-- is_installed(i)
-- if '-C' in opts: raise SystemExit
--
-- img_pre = opts.get('-p', '')
--
-- if img_pre not in ['', 'eimg', 'rimg']:
-- print 'Improper image name prefix.'
-- raise SystemExit
--
-- temp_dir = ''
-- img_dir = opts.get('-d', '.')
-- img_dir = os.path.abspath(img_dir)
-- if ' ' in img_dir:
-- temp_dir = tempfile.mkdtemp('', '.lives-', '/tmp/')
-- os.symlink(img_dir, temp_dir + '/img_dir')
-- img_dir = temp_dir + '/img_dir'
--
-- if not os.path.isdir(img_dir):
-- print 'The image source directory: ' + img_dir + \
-- ' does not exist!'
-- raise SystemExit
--
-- if len(args) not in [0, 2]:
-- print 'If frames are specified both first and last ' + \
-- 'image numbers must be chosen.'
-- raise SystemExit
-- elif len(args) == 0:
-- args = [None, None]
--
-- frame_range = False
-- if not args[0]:
-- first_frame_num = '1'
-- else:
-- frame_range = True
-- first_frame_num = args[0]
-- first_frame_num = first_frame_num.zfill(8)
-- first_num = int(first_frame_num)
--
-- if not args[1]:
-- last_frame_num = '99999999'
-- else:
-- last_frame_num = args[1]
-- last_frame_num = last_frame_num.zfill(8)
-- last_num = int(last_frame_num)
--
-- aspectc = opts.get('-a', '2')
--
-- if aspectc not in [str(i) for i in xrange(1,5)]:
-- print 'Invalid aspect ratio.'
-- raise SystemExit
-- else:
-- if aspectc == '1': aspect = '1/1'
-- elif aspectc == '2': aspect = '4/3'
-- elif aspectc == '3': aspect = '16/9'
-- elif aspectc == '4': aspect = '2.21/1'
--
-- vtype = opts.get('-t', 'ml')
--
-- out_mkv = opts.get('-o', vtype + '_movie.mkv')
--
-- if '_' not in vtype:
-- vtype = vtype + '_x'
--
-- if vtype not in ['hi_d', 'mh_d', 'ml_d', 'lo_d', \
-- 'hi_x', 'mh_x', 'ml_x', 'lo_x', \
-- 'hi_h', 'mh_h', 'ml_h', 'lo_h']:
-- print 'Invalid video type.'
-- raise SystemExit
--
-- fpsc = opts.get('-f', '4')
--
-- if fpsc not in [str(i) for i in xrange(1,9)]:
-- if not quiet: print 'Invalid fps code, attempting float fps.'
-- foundfps = False
-- else:
-- if fpsc == '1': fps = str(24000.0/1001.0)
-- elif fpsc == '2': fps = str(24.0)
-- elif fpsc == '3': fps = str(25.0)
-- elif fpsc == '4': fps = str(30000.0/1001.0)
-- elif fpsc == '5': fps = str(30.0)
-- elif fpsc == '6': fps = str(50.0)
-- elif fpsc == '7': fps = str(60000.0/1001.0)
-- elif fpsc == '8': fps = str(60.0)
-- foundfps = True
--
-- if not foundfps:
-- try:
-- fps = locale.atof(fpsc)
-- if not quiet: print 'Using fps = %s' % fps
-- if fps > 0: foundfps = True
-- except:
-- pass
--
-- if not foundfps:
-- print 'Invalid fps code or rate.'
-- raise SystemExit
--
-- if '-e' not in opts:
-- enhance = False
-- else:
-- enhance = True
--
-- if enhance and img_pre:
-- print 'Sorry, you cannot enhance already-enhanced images'
-- raise SystemExit
--
-- if '-k' not in opts:
-- keep = False
-- else:
-- keep = True
--
-- cgeom = opts.get('-c', '')
-- rgeom = opts.get('-r', '')
--
-- if (cgeom or rgeom) and not enhance:
-- print 'Missing "-e" option.'
-- raise SystemExit
--
-- lv1file = opts.get('-L', None)
-- if lv1file:
-- if not quiet: print 'Opening lv1 file...'
-- try:
-- lv1 = tarfile.open(os.path.abspath(lv1file))
-- except:
-- print 'This does not appear to be a valid LiVES file!'
-- raise SystemExit
-- if 'header.tar' not in lv1.getnames():
-- print 'This does not appear to be a valid LiVES file!'
-- raise SystemExit
-- for tfile in lv1.getmembers():
-- lv1.extract(tfile, img_dir)
-- for tfile in glob.glob(os.path.join(img_dir, '*.tar')):
-- imgtar = tarfile.open(tfile)
-- for img in imgtar.getmembers():
-- imgtar.extract(img, img_dir)
-- os.remove(tfile)
--
-- test_file = os.path.join(img_dir, img_pre + first_frame_num)
-- if os.path.isfile(test_file + '.jpg'):
-- ext = '.jpg'
-- elif os.path.isfile(test_file + '.png'):
-- ext = '.png'
-- else:
-- print 'Cannot find any appropriate %s or %s files!' % ('.jpg','.png')
-- raise SystemExit
-- first_frame = test_file + ext
-- last_frame = os.path.join(img_dir, img_pre + last_frame_num + ext)
--
-- if not quiet: print 'Found: ' + first_frame
--
-- work_dir = opts.get('-w', img_dir)
-- work_dir = os.path.abspath(work_dir)
-- if not os.path.isdir(work_dir):
-- if not quiet: print 'Creating ' + work_dir
-- try:
-- os.makedirs(work_dir)
-- os.chmod(work_dir, 0755)
-- except:
-- print 'Could not create the work directory ' + \
-- work_dir
-- raise SystemExit
-- if ' ' in work_dir:
-- if temp_dir == '':
-- temp_dir = tempfile.mkdtemp('', '.lives-', '/tmp/')
-- os.symlink(work_dir, temp_dir + '/work_dir')
-- work_dir = temp_dir + '/work_dir'
--
-- sndf = opts.get('-s', os.path.join(img_dir, 'audio'))
--# sndf = os.path.abspath(sndf)
-- rawsndf = True
-- if not os.path.isfile(sndf):
-- audio = False
-- rawsndf = False
-- else:
-- audio = True
-- if sndf[-4:] == '.wav':
-- rawsndf = False
-- if not quiet: print 'Found audio file: ' + sndf
--
-- sndr = opts.get('-b', '44100')
--
-- delay = opts.get('-D', '0')
-- if verbose and audio: print 'Linear audio delay (ms): ' + delay
--
-- if enhance:
-- do_enhance()
-- # Note that do_enhance() always creates images prefixed
-- # with 'rimg'. What's important to note if that if the
-- # images are resized the 'rimg' are indeed resized, but
-- # if not the 'rimg' are simply symlinks to the 'eimg'
-- # (enhanced) images.
-- img_pre = 'rimg'
-- ext = '.png'
-- vidname = os.path.join(work_dir, out_mkv)
-- # do_encode() acts on images prefixed by img_pre.
-- do_encode()
-- if not keep:
-- do_clean()
-- if temp_dir != '':
-- shutil.rmtree(temp_dir)
-- if not quiet: print "Done!"
--
--
--"""
--CHANGELOG:
--
--21 Jul 2004 : 0.0.2 : added support for ".wav" files.
-- added '-C' flag.
--28 Jul 2004 : 0.0.3 : added '-D' flag.
-- fixed typos.
-- eliminated some subshell calls.
-- convert dirs to absolute paths.
-- fixed frame range detection.
-- fixed work_dir permissions.
--30 Jul 2004 : 0.0.4 : added '-L' flag.
-- encoder is now feature-complete.
--25 Sep 2004 : 0.0.5 : make sure "rawsndf" is set correctly.
-- check if files exist before removing.
--02 Oct 2004 : 0.0.6 : multiplex even if no audio.
--28 Oct 2004 : 0.0.7 : can handle arbitrary fps values.
--02 Nov 2004 : 0.0.8 : added XviD encoding.
--08 Nov 2004 : 0.0.9 : make sure that the enhanced
-- color depth is 8-bits/channel.
-- fixed XviD aspect ratio.
-- added chroma_opt to XviD.
--02 Jan 2005 : 0.1.0 : updated docs.
-- added sound rate (-b) option.
--26 Mar 2005 : 0.1.1 : use env python (hopefully >= 2.3).
-- replace denoise3d with hqdn3d.
--24 Aug 2005 : 0.1.2 : fixed 2.21:1 aspect ratio.
-- fine-tune mplayer filters.
--09 Mar 2006 : 0.1.3 : added '-depth 8' to resize, as ImageMagick
-- keeps changing its damn behaviour.
-- fixed bitrate levels.
--12 Mar 2006 : 0.1.4 : added h.264 codec.
-- tweaked bitrate levels.
-- fixed audio delay.
--28 Jun 2007 : 0.1.5 : handles paths with spaces appropriately
-- (thanks Gabriel).
--"""
---- /dev/null
-+++ lives/lives-plugins/marcos-encoders/mng_encoder
-@@ -0,0 +1,651 @@
-+#!/usr/bin/env python
-+
-+"""
-+mng_encoder.py
-+
-+Front-end to various programs needed to create MNG
-+movies with some image-enhancing capabilities through the use of
-+ImageMagick. Meant as a companion to LiVES (to possibly call
-+from within a plugin, see http://www.xs4all.nl/~salsaman/lives/ )
-+but can also be used as a stand-alone program.
-+
-+Requires ImageMagick (GraphicsMagick might also
-+work) and Python 2.3.0 or greater. Note that audio
-+support is not implemented, only video encoding.
-+Note that encoding and decoding requires huge amounts
-+of memory, and so it's mostly meant for very short
-+clips (e.g. animated web graphics). The resulting
-+clips can be viewed using the "animate" command which is
-+part of ImageMagick.
-+
-+Copyright (C) 2004-2005 Marco De la Cruz (marco at reimeika.ca)
-+It's a trivial program, but might as well GPL it, so see:
-+http://www.gnu.org/copyleft/gpl.html for license.
-+
-+See my vids at http://amv.reimeika.ca !
-+"""
-+
-+version = '0.0.6'
-+convert = 'convert'
-+
-+usage = \
-+ """
-+mng_encoder.py -h
-+mng_encoder.py -V
-+mng_encoder.py -C
-+mng_encoder.py [-o out] [-p pre] [-d dir] [-a aspect*] [-D delay*]
-+ [-q|-v] [-t type*] [-k] [-e [[-w dir] [-c geom] [-r geom]]]
-+ [-s sndfile*] [-b sndrate*] [-f fpscode] [-L lv1file]
-+ [firstframe lastframe]
-+ """
-+
-+help = \
-+ """
-+SUMMARY (ver. %s):
-+
-+Encodes a series of PNG or JPG images into an MNG
-+(.mng) stream and is also capable of performing some simple image
-+enhacements using ImageMagick. The images and audio are assumed to
-+be in an uncompressed LiVES format, hence making this encoder
-+more suitable to be used within a LiVES plugin (but can also
-+be used directly on a LiVES temporary directory).
-+
-+OPTIONS:
-+
-+-h for help.
-+
-+-V shows the version number.
-+
-+-C check external program dependencies and exit.
-+
-+-o out will save the video in file "out".
-+ Default: "mng_movie.mng".
-+
-+-p pre the encoder assumes that sound and images are named using
-+ LiVES' conventions i.e. "audio" and "00000001.ext",
-+ "00000002.ext"... where "ext" is either "jpg" or "png".
-+ However, mng_encoder.py will create temporary files
-+ which can be saved for later use (for example, after
-+ enhancing the images with "-e" , which may take a long
-+ time). These temporary files will be named
-+ "pre_00000001.ext", etc... where "pre" is either "eimg"
-+ or "rimg" and will be kept if the "-k" option is used.
-+ mng_encoder.py can then be run over the enhanced images
-+ only by selecting the appropriate prefix ("eimg" or
-+ "rimg") here. See "-e" to see what each prefix means.
-+ Default: "" (an empty string).
-+
-+-d dir "dir" is the directory containing the source image
-+ files. These must be of the form "00000001.ext" or
-+ "pre_00000001.ext" as explained above.
-+ Default: "."
-+
-+-a aspect* sets the aspect ratio of the resulting movie.
-+ * = NOT IMPLEMENTED
-+
-+-D delay* linearly delay the audio stream by "delay" ms.
-+ * = NOT IMPLEMENTED
-+
-+-q quiet operation, only complains on error.
-+
-+-v be verbose.
-+
-+-t type* type of video created.
-+ * = NOT IMPLEMENTED
-+
-+-e perform some simple filtering/enhancement to improve image
-+ quality. The images created by using this option will be
-+ stored in the directory specified by the "-w" option (or
-+ "-d" if not present, see above) and each filename will be
-+ prefixed with "eimg" (see "-p" above). Using this option will
-+ take enormous amounts of disk space, and in reality does
-+ not do anything that cannot be done within LiVES itself.
-+ Using this option enables the following four:
-+
-+ -w dir "dir" is the working directory where the enhanced
-+ images will be saved. Although these can all
-+ co-exist with the original LiVES files it is
-+ recommended you use a different directory. Note
-+ that temporary files may take a huge amount of
-+ space, perhaps twice as much as the LiVES files
-+ themselves. If this directory does not exist is
-+ will be created.
-+ Default: same as "-d".
-+
-+ -k keep the temporary files, useful to experiment
-+ with different encoding types without having
-+ to repeatedly enhance the images (which can be
-+ very time-consuming). See "-p" above.
-+
-+ -c geom in addition to enhancing the images, crop them
-+ to the specified geometry e.g. "688x448+17+11".
-+ Filename prefix remains "eimg".
-+
-+ -r geom this will create a second set of images resulting
-+ from resizing the images that have already been
-+ enhanced and possibly cropped (if "-c" has been
-+ specified). The geometry here is simple a new
-+ image size e.g. "352x240!". This second set will have
-+ filenames prefixed with the string "rimg" (see "-p"
-+ above).
-+
-+-s sndfile* name of the audio file.
-+ * = NOT IMPLEMENTED
-+
-+-b sndrate* sample rate of the sound file in Hertz.
-+ * = NOT IMPLEMENTED
-+
-+-f fpscode frame-rate code. Acceptable values are:
-+
-+ 1 - 24000.0/1001.0 (NTSC 3:2 pulldown converted FILM)
-+ 2 - 24.0 (NATIVE FILM)
-+ 3 - 25.0 (PAL/SECAM VIDEO / converted FILM)
-+ 4 - 30000.0/1001.0 (NTSC VIDEO)
-+ 5 - 30.0
-+ 6 - 50.0 (PAL FIELD RATE)
-+ 7 - 60000.0/1001.0 (NTSC FIELD RATE)
-+ 8 - 60.0
-+
-+ If the input value is a float (e.g. 5.0, 14.555, etc.)
-+ the encoder will use that as frame rate.
-+
-+ Default: "4".
-+
-+-L lv1file use the images stored in the LiVES file "lv1file" (e.g.
-+ "movie.lv1"). Files will be extracted inside "dir" as
-+ specified by "-d". Using this option allows to encode
-+ a movie without having to restore it first with LiVES.
-+ Note that the encoder will not delete the extracted
-+ files after it has finished, this must be done manually
-+ afterwards. If frame code/rate (-f) and/or sound rate (-b)
-+ are not specified the defaults will be used (30000/1001 fps
-+ and 44100 Hz). These, however, may not be correct, in which
-+ case they should be specified explicitly. Furthermore, the
-+ .lv1 audio (if present) is always assumed to have a sample
-+ data size in 16-bit words with two channels, and to be signed
-+ linear (this is usually the case, however). If any of these
-+ latter parameters are incorrect the resulting file may be
-+ corrupted and encoding will have to be done using LiVES.
-+
-+firstframe first frame number. If less than eight digits long it will
-+ be padded with zeroes e.g. 234 -> 00000234. A prefix can
-+ be added using the "-p" option.
-+ Default: "00000001"
-+
-+lastframe last frame number, padded with zeroes if necessary, prefix
-+ set by "-p".
-+ Default: the last frame of its type in the "-d" directory,
-+ where "type" is set by the prefix.
-+
-+Note that either no frames or both first and last frames must be specified.
-+
-+EXAMPLES:
-+
-+Suppose you have restored a LiVES' .lv1 file (in either JPG or PNG format),
-+and that the images are stored in the directory "/tmp/livestmp/991319584/".
-+Then, in order to create an mng file you can simply do the following:
-+
-+ mng_encoder.py -d /tmp/livestmp/991319584 -o /movies/default.mng
-+
-+and the clip "default.mng" will be created in "/movies/".
-+
-+Suppose we want to make a downloadable version of the clip, small in size
-+but of good quality. The following command activates the generic enhancement
-+filter and resizes the images to "352x240". Note that these operations
-+are performed after cropping the originals a bit (using "704x464+5+6").
-+This is done because we are assuming that there is a black border around
-+the original pictures which we want to get rid of (this might distort the
-+images somewhat, so be careful about cropping/resizing):
-+
-+ mng_encoder.py -v -d /tmp/livestmp/991319584 -w /tmp/tmpmng \\
-+ -o /movies/download.mng -k -e -c "704x464+5+6" -r "352x240"
-+
-+Since we use the "-k" flag the enhanced images are kept (both full-size
-+crops and the resized ones) in "/tmp/tmpmng". Beware that this may consume
-+a lot of disk space (about 10x as much as the originals). The reason we
-+keep them is because the above may take quite a long time and we may want
-+to re-use the enhanced images. So, for example, creating a
-+clip at full size can be accomplished now as follows:
-+
-+ mng_encoder.py -d /tmp/tmpmng -o /movies/archive.mng \\
-+ -s /tmp/livestmp/991319584/audio -k -p eimg
-+
-+If, for example, we only want to encode frames 100 to 150 we can run
-+the following:
-+
-+ mng_encoder.py -v -d /tmp/tmpmng -o /movies/selection.mng \\
-+ -k -p eimg 100 150
-+
-+To delete all the enhanced images you can just remove "/tmp/tmpmng".
-+
-+Suppose that you have "movie1.lv1", "movie2.lv1" and "movie3.lv1".
-+Batch-encoding can be done as follows (zsh-syntax):
-+
-+ for i in movie?.lv1
-+ do
-+ mkdir /tmp/$i:r
-+ mng_encoder.py -d /tmp/$i:r -o /tmp/$i:r.mng -L $i
-+ rm -rf /tmp/$i:r
-+ done
-+
-+This will generate the files "movie1.mng", "movie2.mng" and
-+"movie3.mng" in "/tmp". Note that is is not necessary to
-+specify whether the files are stored in JPG or PNG format,
-+and that potentially time-consuming options (e.g. "-e") may
-+be enabled. It is not necessary to have a working LiVES
-+installation to encode .lv1 files.
-+ """ % version
-+
-+def run(command):
-+ """
-+ Run a shell command
-+ """
-+
-+ if verbose:
-+ print 'Running: \n' + command + '\n=== ... ==='
-+ std = ''
-+ else:
-+ std = ' > /dev/null 2>&1'
-+
-+ os.system(command + std)
-+
-+
-+def do_enhance():
-+ """
-+ Image cleanup/crop/resize routine. Generic, but seems to work
-+ well with anime :)
-+ """
-+
-+ if not quiet:
-+ print 'Enhancing images... please wait, this might take long...'
-+
-+ enh_opts = "-enhance -sharpen '0.0x0.5' -gamma 1.2 -contrast -depth 8"
-+
-+ if cgeom:
-+ docrop = ' '.join(['-crop', "'%s!'" % cgeom])
-+ else:
-+ docrop = ''
-+
-+ iframe = first_num
-+ while True:
-+ # File names are padded with zeroes to 8 characters
-+ # (not counting the .ext).
-+ frame = str(iframe).zfill(8)
-+ fname = os.path.join(img_dir, frame + ext)
-+ if not os.path.isfile(fname) or (iframe == last_num + 1):
-+ break
-+ eimg_fname = os.path.join(work_dir, 'eimg' + frame + '.png')
-+ rimg_fname = os.path.join(work_dir, 'rimg' + frame + '.png')
-+ command = ' '.join([convert, docrop, enh_opts, fname, eimg_fname])
-+ run(command)
-+ if rgeom:
-+ if os.path.exists(rimg_fname): os.remove(rimg_fname)
-+ shrink = ' '.join([convert, '-resize', "'%s!'" % rgeom, '-depth 8'])
-+ command = ' '.join([shrink, eimg_fname, rimg_fname])
-+ run(command)
-+ else:
-+ if os.path.exists(rimg_fname): os.remove(rimg_fname)
-+ try:
-+ os.symlink(eimg_fname, rimg_fname)
-+ except (IOError, OSError):
-+ shutil.copy(eimg_fname, rimg_fname)
-+ iframe+=1
-+
-+
-+def do_encode():
-+ """
-+ Encode a series of images as an MNG file.
-+ """
-+
-+ if verbose:
-+ std = ''
-+ std2 = ''
-+ be_verbose = '-verbose'
-+ else:
-+ std = ' > /dev/null 2>&1'
-+ std2 = ' 2> /dev/null'
-+ be_verbose = ''
-+
-+ if img_dir != work_dir and not enhance:
-+ source_dir = img_dir
-+ else:
-+ source_dir = work_dir
-+
-+ if frame_range:
-+ numframes = str(last_num - first_num + 1)
-+ frame_list = [img_pre + str(f).zfill(8) + ext \
-+ for f in range(first_num, last_num + 1)]
-+ syml = 'temporary_symlink_'
-+ for iframe in frame_list:
-+ frfile = os.path.join(source_dir, iframe)
-+ frlink = os.path.join(source_dir, syml + iframe)
-+ if os.path.islink(frlink): os.remove(frlink)
-+ os.symlink(frfile, frlink)
-+ else:
-+ syml = ''
-+ numframes = len(glob.glob(os.path.join(source_dir, \
-+ img_pre + '*' + ext)))
-+
-+ # Delay between frames is in 100ths of a second
-+ spf = 100*(1/fps)
-+
-+ mngv = tempfile.mkstemp('.mng', '', work_dir)[1]
-+
-+ all_vars = {}
-+ all_vars.update(globals())
-+ all_vars.update(locals())
-+
-+ if not quiet:
-+ print 'Creating MNG file'
-+
-+ command = """cd %(source_dir)s ; \\
-+%(convert)s -delay %(spf)s %(syml)s%(img_pre)s*%(ext)s %(mngv)s
-+""" % all_vars
-+ run(command)
-+
-+ shutil.move(mngv, vidname)
-+
-+ if frame_range:
-+ lframes = os.path.join(source_dir, syml)
-+ for frame in glob.glob(lframes + '*'):
-+ os.remove(frame)
-+
-+
-+def do_clean():
-+ """
-+ Delete enhanced files
-+ """
-+
-+ if not quiet:
-+ print 'Deleting all enhanced images (if any)'
-+
-+ eframes = os.path.join(work_dir, 'eimg')
-+ rframes = os.path.join(work_dir, 'rimg')
-+ for frame in glob.glob(eframes + '*'):
-+ os.remove(frame)
-+ for frame in glob.glob(rframes + '*'):
-+ os.remove(frame)
-+
-+
-+def which(command):
-+ """
-+ Finds (or not) a command a la "which"
-+ """
-+
-+ command_found = False
-+
-+ if command[0] == '/':
-+ if os.path.isfile(command) and \
-+ os.access(command, os.X_OK):
-+ command_found = True
-+ abs_command = command
-+ else:
-+ path = os.environ.get('PATH', '').split(os.pathsep)
-+ for dir in path:
-+ abs_command = os.path.join(dir, command)
-+ if os.path.isfile(abs_command) and \
-+ os.access(abs_command, os.X_OK):
-+ command_found = True
-+ break
-+
-+ if not command_found:
-+ abs_command = ''
-+
-+ return abs_command
-+
-+
-+def is_installed(prog):
-+ """
-+ See whether "prog" is installed
-+ """
-+
-+ wprog = which(prog)
-+
-+ if wprog == '':
-+ print prog + ': command not found'
-+ raise SystemExit
-+ else:
-+ if verbose:
-+ print wprog + ': found'
-+
-+
-+if __name__ == '__main__':
-+
-+ import os
-+ import sys
-+ import getopt
-+ import shutil
-+ import tempfile
-+ import glob
-+ import tarfile
-+
-+ try:
-+ if sys.version_info[0:3] < (2, 3, 0):
-+ raise SystemExit
-+ except:
-+ print 'You need Python 2.3.0 or greater to run me!'
-+ raise SystemExit
-+
-+ try:
-+ (opts, args) = getopt.getopt(sys.argv[1:], \
-+ 'ho:p:d:w:a:qvt:ekc:r:s:b:f:VCD:L:')
-+ except:
-+ print "Something's wrong. Try the '-h' flag."
-+ raise SystemExit
-+
-+ opts = dict(opts)
-+
-+ if not opts and not args:
-+ print usage
-+ raise SystemExit
-+
-+ if '-h' in opts:
-+ print usage + help
-+ raise SystemExit
-+
-+ if '-V' in opts:
-+ print 'mng_encoder.py version ' + version
-+ raise SystemExit
-+
-+ if ('-v' in opts) or ('-C' in opts):
-+ verbose = True
-+ else:
-+ verbose = False
-+
-+ if '-q' in opts:
-+ quiet = True
-+ verbose = False
-+ else:
-+ quiet = False
-+
-+ for i in [convert]:
-+ is_installed(i)
-+ if '-C' in opts: raise SystemExit
-+
-+ img_pre = opts.get('-p', '')
-+
-+ if img_pre not in ['', 'eimg', 'rimg']:
-+ print 'Improper image name prefix.'
-+ raise SystemExit
-+
-+ temp_dir = ''
-+ img_dir = opts.get('-d', '.')
-+ img_dir = os.path.abspath(img_dir)
-+ if ' ' in img_dir:
-+ temp_dir = tempfile.mkdtemp('', '.lives-', '/tmp/')
-+ os.symlink(img_dir, temp_dir + '/img_dir')
-+ img_dir = temp_dir + '/img_dir'
-+
-+ if not os.path.isdir(img_dir):
-+ print 'The image source directory: ' + img_dir + \
-+ ' does not exist!'
-+ raise SystemExit
-+
-+ if len(args) not in [0, 2]:
-+ print 'If frames are specified both first and last ' + \
-+ 'image numbers must be chosen.'
-+ raise SystemExit
-+ elif len(args) == 0:
-+ args = [None, None]
-+
-+ frame_range = False
-+ if not args[0]:
-+ first_frame_num = '1'
-+ else:
-+ frame_range = True
-+ first_frame_num = args[0]
-+ first_frame_num = first_frame_num.zfill(8)
-+ first_num = int(first_frame_num)
-+
-+ if not args[1]:
-+ last_frame_num = '99999999'
-+ else:
-+ last_frame_num = args[1]
-+ last_frame_num = last_frame_num.zfill(8)
-+ last_num = int(last_frame_num)
-+
-+ # Aspect ratio is not used
-+ aspectc = opts.get('-a', '2')
-+
-+ # Video type is not used
-+ vtype = opts.get('-t', 'mng')
-+
-+ out_mng = opts.get('-o', vtype + '_movie.mng')
-+
-+ fpsc = opts.get('-f', '4')
-+
-+ if fpsc not in [str(i) for i in xrange(1,9)]:
-+ if not quiet: print 'Invalid fps code, attempting float fps.'
-+ foundfps = False
-+ else:
-+ if fpsc == '1': fps = 24000.0/1001.0
-+ elif fpsc == '2': fps = 24.0
-+ elif fpsc == '3': fps = 25.0
-+ elif fpsc == '4': fps = 30000.0/1001.0
-+ elif fpsc == '5': fps = 30.0
-+ elif fpsc == '6': fps = 50.0
-+ elif fpsc == '7': fps = 60000.0/1001.0
-+ elif fpsc == '8': fps = 60.0
-+ foundfps = True
-+
-+ if not foundfps:
-+ try:
-+ fps = locale.atof(fpsc)
-+ if not quiet: print 'Using fps = %s' % fps
-+ if fps > 0: foundfps = True
-+ except:
-+ pass
-+
-+ if not foundfps:
-+ print 'Invalid fps code or rate.'
-+ raise SystemExit
-+
-+ if '-e' not in opts:
-+ enhance = False
-+ else:
-+ enhance = True
-+
-+ if enhance and img_pre:
-+ print 'Sorry, you cannot enhance already-enhanced images'
-+ raise SystemExit
-+
-+ if '-k' not in opts:
-+ keep = False
-+ else:
-+ keep = True
-+
-+ cgeom = opts.get('-c', '')
-+ rgeom = opts.get('-r', '')
-+
-+ if (cgeom or rgeom) and not enhance:
-+ print 'Missing "-e" option.'
-+ raise SystemExit
-+
-+ delay = opts.get('-D', '0')
-+ if verbose: print 'Linear audio delay (ms): ' + delay
-+
-+ lv1file = opts.get('-L', None)
-+ if lv1file:
-+ if not quiet: print 'Opening lv1 file...'
-+ try:
-+ lv1 = tarfile.open(os.path.abspath(lv1file))
-+ except:
-+ print 'This does not appear to be a valid LiVES file!'
-+ raise SystemExit
-+ if 'header.tar' not in lv1.getnames():
-+ print 'This does not appear to be a valid LiVES file!'
-+ raise SystemExit
-+ for tfile in lv1.getmembers():
-+ lv1.extract(tfile, img_dir)
-+ for tfile in glob.glob(os.path.join(img_dir, '*.tar')):
-+ imgtar = tarfile.open(tfile)
-+ for img in imgtar.getmembers():
-+ imgtar.extract(img, img_dir)
-+ os.remove(tfile)
-+
-+ test_file = os.path.join(img_dir, img_pre + first_frame_num)
-+ if os.path.isfile(test_file + '.jpg'):
-+ ext = '.jpg'
-+ elif os.path.isfile(test_file + '.png'):
-+ ext = '.png'
-+ else:
-+ print 'Cannot find any appropriate %s or %s files!' % ('.jpg','.png')
-+ raise SystemExit
-+ first_frame = test_file + ext
-+ last_frame = os.path.join(img_dir, img_pre + last_frame_num + ext)
-+
-+ if not quiet: print 'Found: ' + first_frame
-+
-+ work_dir = opts.get('-w', img_dir)
-+ work_dir = os.path.abspath(work_dir)
-+ if not os.path.isdir(work_dir):
-+ if not quiet: print 'Creating ' + work_dir
-+ try:
-+ os.makedirs(work_dir)
-+ os.chmod(work_dir, 0755)
-+ except:
-+ print 'Could not create the work directory ' + \
-+ work_dir
-+ raise SystemExit
-+ if ' ' in work_dir:
-+ if temp_dir == '':
-+ temp_dir = tempfile.mkdtemp('', '.lives-', '/tmp/')
-+ os.symlink(work_dir, temp_dir + '/work_dir')
-+ work_dir = temp_dir + '/work_dir'
-+
-+ # Audio is not used
-+ sndf = opts.get('-s', os.path.join(img_dir, 'audio'))
-+
-+ if enhance:
-+ do_enhance()
-+ # Note that do_enhance() always creates images prefixed
-+ # with 'rimg'. What's important to note if that if the
-+ # images are resized the 'rimg' are indeed resized, but
-+ # if not the 'rimg' are simply symlinks to (or copies of) the 'eimg'
-+ # (enhanced) images.
-+ img_pre = 'rimg'
-+ ext = '.png'
-+ vidname = os.path.join(work_dir, out_mng)
-+ # do_encode() acts on images prefixed by img_pre.
-+ do_encode()
-+ if not keep:
-+ do_clean()
-+ if temp_dir != '':
-+ shutil.rmtree(temp_dir)
-+ if not quiet: print "Done!"
-+
-+
-+"""
-+CHANGELOG:
-+
-+27 Oct 2004 : 0.0.1 : first release.
-+08 Nov 2004 : 0.0.2 : make sure that the enhanced
-+ color depth is 8-bits/channel.
-+02 Jan 2005 : 0.0.3 : updated docs.
-+ added sound rate (-b) option (unused).
-+21 Mar 2005 : 0.0.4 : use env python (hopefully >= 2.3)
-+09 Mar 2006 : 0.0.5 : added '-depth 8' to resize, as ImageMagick
-+ keeps changing its damn behaviour.
-+28 Jun 2007 : 0.0.6 : handles paths with spaces appropriately
-+ (thanks Gabriel).
-+"""
---- lives.orig/lives-plugins/marcos-encoders/mng_encoder.py
-+++ /dev/null
-@@ -1,651 +0,0 @@
--#!/usr/bin/env python
--
--"""
--mng_encoder.py
--
--Front-end to various programs needed to create MNG
--movies with some image-enhancing capabilities through the use of
--ImageMagick. Meant as a companion to LiVES (to possibly call
--from within a plugin, see http://www.xs4all.nl/~salsaman/lives/ )
--but can also be used as a stand-alone program.
--
--Requires ImageMagick (GraphicsMagick might also
--work) and Python 2.3.0 or greater. Note that audio
--support is not implemented, only video encoding.
--Note that encoding and decoding requires huge amounts
--of memory, and so it's mostly meant for very short
--clips (e.g. animated web graphics). The resulting
--clips can be viewed using the "animate" command which is
--part of ImageMagick.
--
--Copyright (C) 2004-2005 Marco De la Cruz (marco at reimeika.ca)
--It's a trivial program, but might as well GPL it, so see:
--http://www.gnu.org/copyleft/gpl.html for license.
--
--See my vids at http://amv.reimeika.ca !
--"""
--
--version = '0.0.6'
--convert = 'convert'
--
--usage = \
-- """
--mng_encoder.py -h
--mng_encoder.py -V
--mng_encoder.py -C
--mng_encoder.py [-o out] [-p pre] [-d dir] [-a aspect*] [-D delay*]
-- [-q|-v] [-t type*] [-k] [-e [[-w dir] [-c geom] [-r geom]]]
-- [-s sndfile*] [-b sndrate*] [-f fpscode] [-L lv1file]
-- [firstframe lastframe]
-- """
--
--help = \
-- """
--SUMMARY (ver. %s):
--
--Encodes a series of PNG or JPG images into an MNG
--(.mng) stream and is also capable of performing some simple image
--enhacements using ImageMagick. The images and audio are assumed to
--be in an uncompressed LiVES format, hence making this encoder
--more suitable to be used within a LiVES plugin (but can also
--be used directly on a LiVES temporary directory).
--
--OPTIONS:
--
---h for help.
--
---V shows the version number.
--
---C check external program dependencies and exit.
--
---o out will save the video in file "out".
-- Default: "mng_movie.mng".
--
---p pre the encoder assumes that sound and images are named using
-- LiVES' conventions i.e. "audio" and "00000001.ext",
-- "00000002.ext"... where "ext" is either "jpg" or "png".
-- However, mng_encoder.py will create temporary files
-- which can be saved for later use (for example, after
-- enhancing the images with "-e" , which may take a long
-- time). These temporary files will be named
-- "pre_00000001.ext", etc... where "pre" is either "eimg"
-- or "rimg" and will be kept if the "-k" option is used.
-- mng_encoder.py can then be run over the enhanced images
-- only by selecting the appropriate prefix ("eimg" or
-- "rimg") here. See "-e" to see what each prefix means.
-- Default: "" (an empty string).
--
---d dir "dir" is the directory containing the source image
-- files. These must be of the form "00000001.ext" or
-- "pre_00000001.ext" as explained above.
-- Default: "."
--
---a aspect* sets the aspect ratio of the resulting movie.
-- * = NOT IMPLEMENTED
--
---D delay* linearly delay the audio stream by "delay" ms.
-- * = NOT IMPLEMENTED
--
---q quiet operation, only complains on error.
--
---v be verbose.
--
---t type* type of video created.
-- * = NOT IMPLEMENTED
--
---e perform some simple filtering/enhancement to improve image
-- quality. The images created by using this option will be
-- stored in the directory specified by the "-w" option (or
-- "-d" if not present, see above) and each filename will be
-- prefixed with "eimg" (see "-p" above). Using this option will
-- take enormous amounts of disk space, and in reality does
-- not do anything that cannot be done within LiVES itself.
-- Using this option enables the following four:
--
-- -w dir "dir" is the working directory where the enhanced
-- images will be saved. Although these can all
-- co-exist with the original LiVES files it is
-- recommended you use a different directory. Note
-- that temporary files may take a huge amount of
-- space, perhaps twice as much as the LiVES files
-- themselves. If this directory does not exist is
-- will be created.
-- Default: same as "-d".
--
-- -k keep the temporary files, useful to experiment
-- with different encoding types without having
-- to repeatedly enhance the images (which can be
-- very time-consuming). See "-p" above.
--
-- -c geom in addition to enhancing the images, crop them
-- to the specified geometry e.g. "688x448+17+11".
-- Filename prefix remains "eimg".
--
-- -r geom this will create a second set of images resulting
-- from resizing the images that have already been
-- enhanced and possibly cropped (if "-c" has been
-- specified). The geometry here is simple a new
-- image size e.g. "352x240!". This second set will have
-- filenames prefixed with the string "rimg" (see "-p"
-- above).
--
---s sndfile* name of the audio file.
-- * = NOT IMPLEMENTED
--
---b sndrate* sample rate of the sound file in Hertz.
-- * = NOT IMPLEMENTED
--
---f fpscode frame-rate code. Acceptable values are:
--
-- 1 - 24000.0/1001.0 (NTSC 3:2 pulldown converted FILM)
-- 2 - 24.0 (NATIVE FILM)
-- 3 - 25.0 (PAL/SECAM VIDEO / converted FILM)
-- 4 - 30000.0/1001.0 (NTSC VIDEO)
-- 5 - 30.0
-- 6 - 50.0 (PAL FIELD RATE)
-- 7 - 60000.0/1001.0 (NTSC FIELD RATE)
-- 8 - 60.0
--
-- If the input value is a float (e.g. 5.0, 14.555, etc.)
-- the encoder will use that as frame rate.
--
-- Default: "4".
--
---L lv1file use the images stored in the LiVES file "lv1file" (e.g.
-- "movie.lv1"). Files will be extracted inside "dir" as
-- specified by "-d". Using this option allows to encode
-- a movie without having to restore it first with LiVES.
-- Note that the encoder will not delete the extracted
-- files after it has finished, this must be done manually
-- afterwards. If frame code/rate (-f) and/or sound rate (-b)
-- are not specified the defaults will be used (30000/1001 fps
-- and 44100 Hz). These, however, may not be correct, in which
-- case they should be specified explicitly. Furthermore, the
-- .lv1 audio (if present) is always assumed to have a sample
-- data size in 16-bit words with two channels, and to be signed
-- linear (this is usually the case, however). If any of these
-- latter parameters are incorrect the resulting file may be
-- corrupted and encoding will have to be done using LiVES.
--
--firstframe first frame number. If less than eight digits long it will
-- be padded with zeroes e.g. 234 -> 00000234. A prefix can
-- be added using the "-p" option.
-- Default: "00000001"
--
--lastframe last frame number, padded with zeroes if necessary, prefix
-- set by "-p".
-- Default: the last frame of its type in the "-d" directory,
-- where "type" is set by the prefix.
--
--Note that either no frames or both first and last frames must be specified.
--
--EXAMPLES:
--
--Suppose you have restored a LiVES' .lv1 file (in either JPG or PNG format),
--and that the images are stored in the directory "/tmp/livestmp/991319584/".
--Then, in order to create an mng file you can simply do the following:
--
-- mng_encoder.py -d /tmp/livestmp/991319584 -o /movies/default.mng
--
--and the clip "default.mng" will be created in "/movies/".
--
--Suppose we want to make a downloadable version of the clip, small in size
--but of good quality. The following command activates the generic enhancement
--filter and resizes the images to "352x240". Note that these operations
--are performed after cropping the originals a bit (using "704x464+5+6").
--This is done because we are assuming that there is a black border around
--the original pictures which we want to get rid of (this might distort the
--images somewhat, so be careful about cropping/resizing):
--
-- mng_encoder.py -v -d /tmp/livestmp/991319584 -w /tmp/tmpmng \\
-- -o /movies/download.mng -k -e -c "704x464+5+6" -r "352x240"
--
--Since we use the "-k" flag the enhanced images are kept (both full-size
--crops and the resized ones) in "/tmp/tmpmng". Beware that this may consume
--a lot of disk space (about 10x as much as the originals). The reason we
--keep them is because the above may take quite a long time and we may want
--to re-use the enhanced images. So, for example, creating a
--clip at full size can be accomplished now as follows:
--
-- mng_encoder.py -d /tmp/tmpmng -o /movies/archive.mng \\
-- -s /tmp/livestmp/991319584/audio -k -p eimg
--
--If, for example, we only want to encode frames 100 to 150 we can run
--the following:
--
-- mng_encoder.py -v -d /tmp/tmpmng -o /movies/selection.mng \\
-- -k -p eimg 100 150
--
--To delete all the enhanced images you can just remove "/tmp/tmpmng".
--
--Suppose that you have "movie1.lv1", "movie2.lv1" and "movie3.lv1".
--Batch-encoding can be done as follows (zsh-syntax):
--
-- for i in movie?.lv1
-- do
-- mkdir /tmp/$i:r
-- mng_encoder.py -d /tmp/$i:r -o /tmp/$i:r.mng -L $i
-- rm -rf /tmp/$i:r
-- done
--
--This will generate the files "movie1.mng", "movie2.mng" and
--"movie3.mng" in "/tmp". Note that is is not necessary to
--specify whether the files are stored in JPG or PNG format,
--and that potentially time-consuming options (e.g. "-e") may
--be enabled. It is not necessary to have a working LiVES
--installation to encode .lv1 files.
-- """ % version
--
--def run(command):
-- """
-- Run a shell command
-- """
--
-- if verbose:
-- print 'Running: \n' + command + '\n=== ... ==='
-- std = ''
-- else:
-- std = ' > /dev/null 2>&1'
--
-- os.system(command + std)
--
--
--def do_enhance():
-- """
-- Image cleanup/crop/resize routine. Generic, but seems to work
-- well with anime :)
-- """
--
-- if not quiet:
-- print 'Enhancing images... please wait, this might take long...'
--
-- enh_opts = "-enhance -sharpen '0.0x0.5' -gamma 1.2 -contrast -depth 8"
--
-- if cgeom:
-- docrop = ' '.join(['-crop', "'%s!'" % cgeom])
-- else:
-- docrop = ''
--
-- iframe = first_num
-- while True:
-- # File names are padded with zeroes to 8 characters
-- # (not counting the .ext).
-- frame = str(iframe).zfill(8)
-- fname = os.path.join(img_dir, frame + ext)
-- if not os.path.isfile(fname) or (iframe == last_num + 1):
-- break
-- eimg_fname = os.path.join(work_dir, 'eimg' + frame + '.png')
-- rimg_fname = os.path.join(work_dir, 'rimg' + frame + '.png')
-- command = ' '.join([convert, docrop, enh_opts, fname, eimg_fname])
-- run(command)
-- if rgeom:
-- if os.path.exists(rimg_fname): os.remove(rimg_fname)
-- shrink = ' '.join([convert, '-resize', "'%s!'" % rgeom, '-depth 8'])
-- command = ' '.join([shrink, eimg_fname, rimg_fname])
-- run(command)
-- else:
-- if os.path.exists(rimg_fname): os.remove(rimg_fname)
-- try:
-- os.symlink(eimg_fname, rimg_fname)
-- except (IOError, OSError):
-- shutil.copy(eimg_fname, rimg_fname)
-- iframe+=1
--
--
--def do_encode():
-- """
-- Encode a series of images as an MNG file.
-- """
--
-- if verbose:
-- std = ''
-- std2 = ''
-- be_verbose = '-verbose'
-- else:
-- std = ' > /dev/null 2>&1'
-- std2 = ' 2> /dev/null'
-- be_verbose = ''
--
-- if img_dir != work_dir and not enhance:
-- source_dir = img_dir
-- else:
-- source_dir = work_dir
--
-- if frame_range:
-- numframes = str(last_num - first_num + 1)
-- frame_list = [img_pre + str(f).zfill(8) + ext \
-- for f in range(first_num, last_num + 1)]
-- syml = 'temporary_symlink_'
-- for iframe in frame_list:
-- frfile = os.path.join(source_dir, iframe)
-- frlink = os.path.join(source_dir, syml + iframe)
-- if os.path.islink(frlink): os.remove(frlink)
-- os.symlink(frfile, frlink)
-- else:
-- syml = ''
-- numframes = len(glob.glob(os.path.join(source_dir, \
-- img_pre + '*' + ext)))
--
-- # Delay between frames is in 100ths of a second
-- spf = 100*(1/fps)
--
-- mngv = tempfile.mkstemp('.mng', '', work_dir)[1]
--
-- all_vars = {}
-- all_vars.update(globals())
-- all_vars.update(locals())
--
-- if not quiet:
-- print 'Creating MNG file'
--
-- command = """cd %(source_dir)s ; \\
--%(convert)s -delay %(spf)s %(syml)s%(img_pre)s*%(ext)s %(mngv)s
--""" % all_vars
-- run(command)
--
-- shutil.move(mngv, vidname)
--
-- if frame_range:
-- lframes = os.path.join(source_dir, syml)
-- for frame in glob.glob(lframes + '*'):
-- os.remove(frame)
--
--
--def do_clean():
-- """
-- Delete enhanced files
-- """
--
-- if not quiet:
-- print 'Deleting all enhanced images (if any)'
--
-- eframes = os.path.join(work_dir, 'eimg')
-- rframes = os.path.join(work_dir, 'rimg')
-- for frame in glob.glob(eframes + '*'):
-- os.remove(frame)
-- for frame in glob.glob(rframes + '*'):
-- os.remove(frame)
--
--
--def which(command):
-- """
-- Finds (or not) a command a la "which"
-- """
--
-- command_found = False
--
-- if command[0] == '/':
-- if os.path.isfile(command) and \
-- os.access(command, os.X_OK):
-- command_found = True
-- abs_command = command
-- else:
-- path = os.environ.get('PATH', '').split(os.pathsep)
-- for dir in path:
-- abs_command = os.path.join(dir, command)
-- if os.path.isfile(abs_command) and \
-- os.access(abs_command, os.X_OK):
-- command_found = True
-- break
--
-- if not command_found:
-- abs_command = ''
--
-- return abs_command
--
--
--def is_installed(prog):
-- """
-- See whether "prog" is installed
-- """
--
-- wprog = which(prog)
--
-- if wprog == '':
-- print prog + ': command not found'
-- raise SystemExit
-- else:
-- if verbose:
-- print wprog + ': found'
--
--
--if __name__ == '__main__':
--
-- import os
-- import sys
-- import getopt
-- import shutil
-- import tempfile
-- import glob
-- import tarfile
--
-- try:
-- if sys.version_info[0:3] < (2, 3, 0):
-- raise SystemExit
-- except:
-- print 'You need Python 2.3.0 or greater to run me!'
-- raise SystemExit
--
-- try:
-- (opts, args) = getopt.getopt(sys.argv[1:], \
-- 'ho:p:d:w:a:qvt:ekc:r:s:b:f:VCD:L:')
-- except:
-- print "Something's wrong. Try the '-h' flag."
-- raise SystemExit
--
-- opts = dict(opts)
--
-- if not opts and not args:
-- print usage
-- raise SystemExit
--
-- if '-h' in opts:
-- print usage + help
-- raise SystemExit
--
-- if '-V' in opts:
-- print 'mng_encoder.py version ' + version
-- raise SystemExit
--
-- if ('-v' in opts) or ('-C' in opts):
-- verbose = True
-- else:
-- verbose = False
--
-- if '-q' in opts:
-- quiet = True
-- verbose = False
-- else:
-- quiet = False
--
-- for i in [convert]:
-- is_installed(i)
-- if '-C' in opts: raise SystemExit
--
-- img_pre = opts.get('-p', '')
--
-- if img_pre not in ['', 'eimg', 'rimg']:
-- print 'Improper image name prefix.'
-- raise SystemExit
--
-- temp_dir = ''
-- img_dir = opts.get('-d', '.')
-- img_dir = os.path.abspath(img_dir)
-- if ' ' in img_dir:
-- temp_dir = tempfile.mkdtemp('', '.lives-', '/tmp/')
-- os.symlink(img_dir, temp_dir + '/img_dir')
-- img_dir = temp_dir + '/img_dir'
--
-- if not os.path.isdir(img_dir):
-- print 'The image source directory: ' + img_dir + \
-- ' does not exist!'
-- raise SystemExit
--
-- if len(args) not in [0, 2]:
-- print 'If frames are specified both first and last ' + \
-- 'image numbers must be chosen.'
-- raise SystemExit
-- elif len(args) == 0:
-- args = [None, None]
--
-- frame_range = False
-- if not args[0]:
-- first_frame_num = '1'
-- else:
-- frame_range = True
-- first_frame_num = args[0]
-- first_frame_num = first_frame_num.zfill(8)
-- first_num = int(first_frame_num)
--
-- if not args[1]:
-- last_frame_num = '99999999'
-- else:
-- last_frame_num = args[1]
-- last_frame_num = last_frame_num.zfill(8)
-- last_num = int(last_frame_num)
--
-- # Aspect ratio is not used
-- aspectc = opts.get('-a', '2')
--
-- # Video type is not used
-- vtype = opts.get('-t', 'mng')
--
-- out_mng = opts.get('-o', vtype + '_movie.mng')
--
-- fpsc = opts.get('-f', '4')
--
-- if fpsc not in [str(i) for i in xrange(1,9)]:
-- if not quiet: print 'Invalid fps code, attempting float fps.'
-- foundfps = False
-- else:
-- if fpsc == '1': fps = 24000.0/1001.0
-- elif fpsc == '2': fps = 24.0
-- elif fpsc == '3': fps = 25.0
-- elif fpsc == '4': fps = 30000.0/1001.0
-- elif fpsc == '5': fps = 30.0
-- elif fpsc == '6': fps = 50.0
-- elif fpsc == '7': fps = 60000.0/1001.0
-- elif fpsc == '8': fps = 60.0
-- foundfps = True
--
-- if not foundfps:
-- try:
-- fps = locale.atof(fpsc)
-- if not quiet: print 'Using fps = %s' % fps
-- if fps > 0: foundfps = True
-- except:
-- pass
--
-- if not foundfps:
-- print 'Invalid fps code or rate.'
-- raise SystemExit
--
-- if '-e' not in opts:
-- enhance = False
-- else:
-- enhance = True
--
-- if enhance and img_pre:
-- print 'Sorry, you cannot enhance already-enhanced images'
-- raise SystemExit
--
-- if '-k' not in opts:
-- keep = False
-- else:
-- keep = True
--
-- cgeom = opts.get('-c', '')
-- rgeom = opts.get('-r', '')
--
-- if (cgeom or rgeom) and not enhance:
-- print 'Missing "-e" option.'
-- raise SystemExit
--
-- delay = opts.get('-D', '0')
-- if verbose: print 'Linear audio delay (ms): ' + delay
--
-- lv1file = opts.get('-L', None)
-- if lv1file:
-- if not quiet: print 'Opening lv1 file...'
-- try:
-- lv1 = tarfile.open(os.path.abspath(lv1file))
-- except:
-- print 'This does not appear to be a valid LiVES file!'
-- raise SystemExit
-- if 'header.tar' not in lv1.getnames():
-- print 'This does not appear to be a valid LiVES file!'
-- raise SystemExit
-- for tfile in lv1.getmembers():
-- lv1.extract(tfile, img_dir)
-- for tfile in glob.glob(os.path.join(img_dir, '*.tar')):
-- imgtar = tarfile.open(tfile)
-- for img in imgtar.getmembers():
-- imgtar.extract(img, img_dir)
-- os.remove(tfile)
--
-- test_file = os.path.join(img_dir, img_pre + first_frame_num)
-- if os.path.isfile(test_file + '.jpg'):
-- ext = '.jpg'
-- elif os.path.isfile(test_file + '.png'):
-- ext = '.png'
-- else:
-- print 'Cannot find any appropriate %s or %s files!' % ('.jpg','.png')
-- raise SystemExit
-- first_frame = test_file + ext
-- last_frame = os.path.join(img_dir, img_pre + last_frame_num + ext)
--
-- if not quiet: print 'Found: ' + first_frame
--
-- work_dir = opts.get('-w', img_dir)
-- work_dir = os.path.abspath(work_dir)
-- if not os.path.isdir(work_dir):
-- if not quiet: print 'Creating ' + work_dir
-- try:
-- os.makedirs(work_dir)
-- os.chmod(work_dir, 0755)
-- except:
-- print 'Could not create the work directory ' + \
-- work_dir
-- raise SystemExit
-- if ' ' in work_dir:
-- if temp_dir == '':
-- temp_dir = tempfile.mkdtemp('', '.lives-', '/tmp/')
-- os.symlink(work_dir, temp_dir + '/work_dir')
-- work_dir = temp_dir + '/work_dir'
--
-- # Audio is not used
-- sndf = opts.get('-s', os.path.join(img_dir, 'audio'))
--
-- if enhance:
-- do_enhance()
-- # Note that do_enhance() always creates images prefixed
-- # with 'rimg'. What's important to note if that if the
-- # images are resized the 'rimg' are indeed resized, but
-- # if not the 'rimg' are simply symlinks to (or copies of) the 'eimg'
-- # (enhanced) images.
-- img_pre = 'rimg'
-- ext = '.png'
-- vidname = os.path.join(work_dir, out_mng)
-- # do_encode() acts on images prefixed by img_pre.
-- do_encode()
-- if not keep:
-- do_clean()
-- if temp_dir != '':
-- shutil.rmtree(temp_dir)
-- if not quiet: print "Done!"
--
--
--"""
--CHANGELOG:
--
--27 Oct 2004 : 0.0.1 : first release.
--08 Nov 2004 : 0.0.2 : make sure that the enhanced
-- color depth is 8-bits/channel.
--02 Jan 2005 : 0.0.3 : updated docs.
-- added sound rate (-b) option (unused).
--21 Mar 2005 : 0.0.4 : use env python (hopefully >= 2.3)
--09 Mar 2006 : 0.0.5 : added '-depth 8' to resize, as ImageMagick
-- keeps changing its damn behaviour.
--28 Jun 2007 : 0.0.6 : handles paths with spaces appropriately
-- (thanks Gabriel).
--"""
---- /dev/null
-+++ lives/lives-plugins/marcos-encoders/mpeg_encoder
-@@ -0,0 +1,886 @@
-+#!/usr/bin/env python
-+
-+"""
-+mpeg_encoder.py
-+
-+Simple front-end to MJPEGtools with some image-enhancing
-+capabilities through the use of ImageMagick. Meant as a
-+companion to LiVES (to possibly call from within a plugin,
-+see http://www.xs4all.nl/~salsaman/lives/ ) but can also
-+be used as a stand-alone program.
-+
-+Requires MJPEGtools, ImageMagick (GraphicsMagick might also
-+work), sox, and Python 2.3.0 or greater.
-+
-+Copyright (C) 2004-2005 Marco De la Cruz (marco at reimeika.ca)
-+It's a trivial program, but might as well GPL it, so see:
-+http://www.gnu.org/copyleft/gpl.html for license.
-+
-+See my vids at http://amv.reimeika.ca !
-+"""
-+
-+version = '0.1.8'
-+convert = 'convert'
-+mpeg2enc = 'mpeg2enc'
-+mp2enc = 'mp2enc'
-+sox = 'sox'
-+png2yuv = 'png2yuv'
-+jpeg2yuv = 'jpeg2yuv'
-+yuvdenoise = 'yuvdenoise'
-+yuvscaler = 'yuvscaler'
-+mplex = 'mplex'
-+
-+usage = \
-+ """
-+mpeg_encoder.py -h
-+mpeg_encoder.py -V
-+mpeg_encoder.py -C
-+mpeg_encoder.py [-o out] [-p pre] [-d dir] [-a aspect] [-D delay]
-+ [-q|-v] [-t type] [-k] [-e [[-w dir] [-c geom] [-r geom]]]
-+ [-s sndfile] [-b sndrate] [-f fpscode] [-L lv1file]
-+ [firstframe lastframe]
-+ """
-+
-+help = \
-+ """
-+SUMMARY (ver. %s):
-+
-+Encodes a series of PNG or JPG images into an MPEG-1 or MPEG-2
-+stream. It behaves mostly as a simplified front-end to mjpegtools,
-+although it is also capable of performing some simple image
-+enhacements using ImageMagick. The images and audio are assumed to
-+be in an uncompressed LiVES format, hence making this encoder
-+more suitable to be used within a LiVES plugin (but can also
-+be used directly on a LiVES temporary directory).
-+
-+Note: this program currently handles only non-interlaced source.
-+
-+OPTIONS:
-+
-+-h for help.
-+
-+-V shows the version number.
-+
-+-C check external program dependencies and exit.
-+
-+-o out will save the video in file "out".
-+ Default: "'type'_movie.mpg". See below for 'type'.
-+
-+-p pre the encoder assumes that sound and images are named using
-+ LiVES' conventions i.e. "audio" and "00000001.ext",
-+ "00000002.ext"... where "ext" is either "jpg" or "png".
-+ However, mpeg_encoder.py will create temporary files
-+ which can be saved for later use (for example, after
-+ enhancing the images with "-e" , which may take a long
-+ time). These temporary files will be named
-+ "pre_00000001.ext", etc... where "pre" is either "eimg"
-+ or "rimg" and will be kept if the "-k" option is used.
-+ mpeg_encoder.py can then be run over the enhanced images
-+ only by selecting the appropriate prefix ("eimg" or
-+ "rimg") here. See "-e" to see what each prefix means.
-+ Default: "" (an empty string).
-+
-+-d dir "dir" is the directory containing the source image
-+ files. These must be of the form "00000001.ext" or
-+ "pre_00000001.ext" as explained above.
-+ Default: "."
-+
-+-a aspect sets the aspect ratio of the resulting MPEG. This can be:
-+
-+ 1 1:1 display
-+ 2 4:3 display
-+ 3 16:9 display
-+ 4 2.21:1 display (does not really work)
-+
-+ Currently selecting "4" will fall back to "3".
-+ Default: "2"
-+
-+-D delay linearly delay the audio stream by "delay" ms.
-+ Default: "0"
-+
-+-q quiet operation, only complains on error.
-+
-+-v be verbose.
-+
-+-t type type of video created. The options here are:
-+
-+ "hi": a very high quality MPEG-1 file, suitable
-+ for archiving images of 720x480.
-+
-+ "mh": medium-high quality MPEG-1, which still allows
-+ to watch small videos (352x240 and below)
-+ fullscreen.
-+
-+ "ml": medium-low quality MPEG-1, suitable for
-+ most videos but in particular small videos
-+ (352x240 and below) meant for online
-+ distribution.
-+
-+ "lo": a low quality MPEG-1 format. Enlarging
-+ small videos will result in very noticeable
-+ artifacts. Good for distributing over slow
-+ connections.
-+
-+ "qlo": a quick and dirty (but fast) low quality MPEG-1.
-+
-+ "vcd": VCD-conformant MPEG-1 stream (NTSC VIDEO).
-+
-+ "svcd": SVCD-conformant MPEG-2 stream (NTSC VIDEO).
-+
-+ "dvd": DVD-conformant MPEG-2 stream (NTSC VIDEO).
-+
-+ "sdvd": Strictly DVD-conformant MPEG-2 stream (NTSC VIDEO).
-+
-+ "pvcd": VCD-conformant MPEG-1 stream (PAL VIDEO).
-+
-+ "psvcd": SVCD-conformant MPEG-2 stream (PAL VIDEO).
-+
-+ "pdvd": DVD-conformant MPEG-2 stream (PAL VIDEO).
-+
-+ "spdvd": Strictly DVD-conformant MPEG-2 stream (PAL VIDEO).
-+
-+ Default: "ml"
-+
-+-e perform some simple filtering/enhancement to improve image
-+ quality. The images created by using this option will be
-+ stored in the directory specified by the "-w" option (or
-+ "-d" if not present, see above) and each filename will be
-+ prefixed with "eimg" (see "-p" above). Using this option will
-+ take enormous amounts of disk space, and in reality does
-+ not do anything that cannot be done within LiVES itself.
-+ Using this option enables the following four:
-+
-+ -w dir "dir" is the working directory where the enhanced
-+ images will be saved. Although these can all
-+ co-exist with the original LiVES files it is
-+ recommended you use a different directory. Note
-+ that temporary files may take a huge amount of
-+ space, perhaps twice as much as the LiVES files
-+ themselves. If this directory does not exist is
-+ will be created.
-+ Default: same as "-d".
-+
-+ -k keep the temporary files, useful to experiment
-+ with different encoding types without having
-+ to repeatedly enhance the images (which can be
-+ very time-consuming). See "-p" above.
-+
-+ -c geom in addition to enhancing the images, crop them
-+ to the specified geometry e.g. "688x448+17+11".
-+ Filename prefix remains "eimg". Note that the
-+ dimensions of the images should both be multiples
-+ of "16", otherwise some players may show artifacts
-+ (such as garbage or green bars at the borders).
-+
-+ -r geom this will create a second set of images resulting
-+ from resizing the images that have already been
-+ enhanced and possibly cropped (if "-c" has been
-+ specified). The geometry here is simple a new
-+ image size e.g. "352x240!". This second set will have
-+ filenames prefixed with the string "rimg" (see "-p"
-+ above). Note that the dimensions of the images
-+ should both be multiples of "16", otherwise some
-+ players may show artifacts (such as garbage or
-+ green bars at the borders).
-+
-+-s sndfile name of the audio file. Can be either raw "audio" or
-+ "[/path/to/]soundfile.wav". Note that for raw audio
-+ the sound will always be stereo and sampled at 44100Hz.
-+ Default: "audio" inside "dir" as specified by "-d".
-+
-+-b sndrate sample rate of the sound file in Hertz.
-+ Default: "44100".
-+
-+-f fpscode frame-rate code. Acceptable values are:
-+
-+ 1 - 24000.0/1001.0 (NTSC 3:2 pulldown converted FILM)
-+ 2 - 24.0 (NATIVE FILM)
-+ 3 - 25.0 (PAL/SECAM VIDEO / converted FILM)
-+ 4 - 30000.0/1001.0 (NTSC VIDEO)
-+ 5 - 30.0
-+ 6 - 50.0 (PAL FIELD RATE)
-+ 7 - 60000.0/1001.0 (NTSC FIELD RATE)
-+ 8 - 60.0
-+
-+ Note that when type is "vcd", "svcd", or "(s)dvd" this value
-+ is set to "4" to make NTSC video. For "pvcd", "psvcd", or
-+ "(s)pdvd" the value is set to "3".
-+
-+ Default: "4".
-+
-+-L lv1file use the images stored in the LiVES file "lv1file" (e.g.
-+ "movie.lv1"). Files will be extracted inside "dir" as
-+ specified by "-d". Using this option allows to encode
-+ a movie without having to restore it first with LiVES.
-+ Note that the encoder will not delete the extracted
-+ files after it has finished, this must be done manually
-+ afterwards. If frame code/rate (-f) and/or sound rate (-b)
-+ are not specified the defaults will be used (30000/1001 fps
-+ and 44100 Hz). These, however, may not be correct, in which
-+ case they should be specified explicitly. Furthermore, the
-+ .lv1 audio (if present) is always assumed to have a sample
-+ data size in 16-bit words with two channels, and to be signed
-+ linear (this is usually the case, however). If any of these
-+ latter parameters are incorrect the resulting file may be
-+ corrupted and encoding will have to be done using LiVES.
-+
-+firstframe first frame number. If less than eight digits long it will
-+ be padded with zeroes e.g. 234 -> 00000234. A prefix can
-+ be added using the "-p" option.
-+ Default: "00000001"
-+
-+lastframe last frame number, padded with zeroes if necessary, prefix
-+ set by "-p".
-+ Default: the last frame of its type in the "-d" directory,
-+ where "type" is set by the prefix.
-+
-+Note that either no frames or both first and last frames must be specified.
-+
-+EXAMPLES:
-+
-+Suppose you have restored a LiVES' .lv1 file (in either JPG or PNG format),
-+and that the images are stored in the directory "/tmp/livestmp/991319584/".
-+In this example the movie is assumed to be 16:9. NOTE THAT THE VIDEO MUST
-+BE PROGRESSIVE (NON-INTERLACED) FOR THIS TO WORK. Then, in order to
-+create an MPEG-1 file you can simply do the following:
-+
-+ mpeg_encoder.py -d /tmp/livestmp/991319584 -o /movies/default.mpg -a 3
-+
-+and the clip "default.mpg" will be created in "/movies/" with the correct
-+aspect ratio.
-+
-+Suppose we want to make a downloadable version of the clip, small in size
-+but of good quality. The following command activates the generic enhancement
-+filter and resizes the images to "352x240". Note that these operations
-+are performed after cropping the originals a bit (using "704x464+5+6").
-+This is done because we are assuming that there is a black border around
-+the original pictures which we want to get rid of (this might distort the
-+images somewhat, so be careful about cropping/resizing, and remember to
-+use dimensions which are multiples of 16):
-+
-+ mpeg_encoder.py -v -d /tmp/livestmp/991319584 -w /tmp/tmpmpg \\
-+ -o /movies/download.mpg -a 3 -k -e -c "704x464+5+6" -r "352x240"
-+
-+Since we use the "-k" flag the enhanced images are kept (both full-size
-+crops and the resized ones) in "/tmp/tmpmpg". Beware that this may consume
-+a lot of disk space (about 10x as much as the originals). The reason we
-+keep them is because the above may take quite a long time and we may want
-+to re-use the enhanced images. So, for example, creating a high-quality
-+clip at full size can be accomplished now as follows:
-+
-+ mpeg_encoder.py -d /tmp/tmpmpg -t hi -o /movies/archive.mpg \\
-+ -s /tmp/livestmp/991319584/audio -a 3 -k -p eimg
-+
-+Creating VCD/SVCD/DVD-compatible clips is also readily done:
-+
-+ mpeg_encoder.py -d /tmp/tmpmpg -t vcd -o /movies/vcd.mpg \\
-+ -s /tmp/livestmp/991319584/audio -a 3 -k -p eimg
-+
-+ mpeg_encoder.py -q -d /tmp/tmpmpg -t svcd -o /movies/svcd.mpg \\
-+ -s /tmp/livestmp/991319584/audio -a 3 -k -p eimg
-+
-+ mpeg_encoder.py -v -d /tmp/tmpmpg -t dvd -o /movies/dvd.mpg \\
-+ -s /tmp/livestmp/991319584/audio -a 3 -k -p eimg
-+
-+If, for example, we only want to encode frames 100 to 150 we can run
-+the following:
-+
-+ mpeg_encoder.py -v -d /tmp/tmpmpg -o /movies/selection.mpg \\
-+ -a 3 -k -p eimg 100 150
-+
-+Note that no audio has been selected ("-s"). This is because
-+mpeg_encoder.py cannot trim the audio to the appropriate length.
-+You would need to use LiVES to do this.
-+
-+To delete all the enhanced images you can just remove "/tmp/tmpmpg".
-+
-+If you notice that the video and audio become out of sync so that
-+near the end of the movie the video trails the audio by, say, 0.2s,
-+you can use the "-D" option as follows:
-+
-+ mpeg_encoder.py -d /tmp/livestmp/991319584 -o test.mpg -D 200
-+
-+Note that negative time values are also allowed.
-+
-+Suppose that you have "movie1.lv1", "movie2.lv1" and "movie3.lv1".
-+Batch-encoding can be done as follows (zsh-syntax):
-+
-+ for i in movie?.lv1
-+ do
-+ mkdir /tmp/$i:r
-+ mpeg_encoder.py -d /tmp/$i:r -o /tmp/$i:r.mpg -L $i
-+ rm -rf /tmp/$i:r
-+ done
-+
-+This will generate the files "movie1.mpg", "movie2.mpg" and
-+"movie3.mpg" in "/tmp". Note that is is not necessary to
-+specify whether the files are stored in JPG or PNG format,
-+and that potentially time-consuming options (e.g. "-e") may
-+be enabled. It is not necessary to have a working LiVES
-+installation to encode .lv1 files.
-+ """ % version
-+
-+def run(command):
-+ """
-+ Run a shell command
-+ """
-+
-+ if verbose:
-+ print 'Running: \n' + command + '\n=== ... ==='
-+ std = ''
-+ else:
-+ std = ' > /dev/null 2>&1'
-+
-+ os.system(command + std)
-+
-+
-+def do_enhance():
-+ """
-+ Image cleanup/crop/resize routine. Generic, but seems to work
-+ well with anime :)
-+ """
-+
-+ if not quiet:
-+ print 'Enhancing images... please wait, this might take long...'
-+
-+ enh_opts = "-enhance -sharpen '0.0x0.5' -gamma 1.2 -contrast -depth 8"
-+
-+ if cgeom:
-+ docrop = ' '.join(['-crop', "'%s!'" % cgeom])
-+ else:
-+ docrop = ''
-+
-+ iframe = first_num
-+ while True:
-+ # File names are padded with zeroes to 8 characters
-+ # (not counting the .ext).
-+ frame = str(iframe).zfill(8)
-+ fname = os.path.join(img_dir, frame + ext)
-+ if not os.path.isfile(fname) or (iframe == last_num + 1):
-+ break
-+ eimg_fname = os.path.join(work_dir, 'eimg' + frame + '.png')
-+ rimg_fname = os.path.join(work_dir, 'rimg' + frame + '.png')
-+ command = ' '.join([convert, docrop, enh_opts, fname, eimg_fname])
-+ run(command)
-+ if rgeom:
-+ if os.path.exists(rimg_fname): os.remove(rimg_fname)
-+ shrink = ' '.join([convert, '-resize', "'%s!'" % rgeom, '-depth 8'])
-+ command = ' '.join([shrink, eimg_fname, rimg_fname])
-+ run(command)
-+ else:
-+ if os.path.exists(rimg_fname): os.remove(rimg_fname)
-+ try:
-+ os.symlink(eimg_fname, rimg_fname)
-+ except (IOError, OSError):
-+ shutil.copy(eimg_fname, rimg_fname)
-+ iframe+=1
-+
-+
-+def do_encode():
-+ """
-+ Encode a series of images into an MPEG stream, multiplexing
-+ audio if necessary
-+ """
-+
-+ if not quiet:
-+ print 'Creating "%s"-quality MPEG' % vtype
-+
-+ if verbose:
-+ std = ''
-+ else:
-+ std = ' 2> /dev/null'
-+
-+ # There are a lot of magic numbers here, but in a sense that's
-+ # the point of boiling down all the complicated parameter settings
-+ # to "low", "medium lo/hi", and "hi". These numbers work OK, but
-+ # in order to fully understand them it is necessary to read the
-+ # excellent MJPEGtools HOWTO:
-+ # https://sourceforge.net/docman/display_doc.php?docid=3456&group_id=5776
-+
-+ scaler = ''
-+ denoise = '2'
-+ if vtype == 'qlo':
-+ common_opts = ' -f 0 -F %s -r 8 -4 4 -2 4 -P ' % fpsc
-+ else:
-+ common_opts = ' -f 0 -F %s -H -r 24 -4 1 -2 1 -P -g 6 -G 18 ' % fpsc
-+ if aspect in ['3','4']:
-+ widescreen = '-M WIDE2STD'
-+ else:
-+ widescreen = ''
-+ if ext == '.png':
-+ img2yuv = png2yuv
-+ else:
-+ img2yuv = jpeg2yuv
-+
-+ # For -B: round up (vid + audio)*0.01 + audio bitrates
-+ # For -r: round up (vid + audio)*1.02
-+ # For -V: decent software decoder... push this up to 500K+
-+ # For -b in mplex: "at least -V". I do -V*1.1
-+
-+ if vtype == 'hi':
-+ mpeg2enc_opts = common_opts + \
-+ '-a %s -b 13000 -q 4 -B 600 -V 2000' % aspect
-+ mp2enc_opts = '-b 384 -r 44100'
-+ mplex_opts = '-f 0 -b 2200 -V -r 14000'
-+ elif vtype == 'mh':
-+ mpeg2enc_opts = common_opts + \
-+ '-a %s -b 6500 -q 4 -B 350 -V 1000' % aspect
-+ mp2enc_opts = '-b 256 -r 44100'
-+ mplex_opts = '-f 0 -b 1100 -V -r 7000'
-+ elif vtype == 'ml':
-+ denoise = '1'
-+ mpeg2enc_opts = common_opts + \
-+ '-a %s -b 6500 -q 4 -B 300 -V 1000' % aspect
-+ mp2enc_opts = '-b 192 -r 44100'
-+ mplex_opts = '-f 0 -b 1100 -V -r 7000'
-+ elif vtype in ['lo', 'qlo']:
-+ denoise = '1'
-+ mpeg2enc_opts = common_opts + \
-+ '-a %s -b 2500 -q 6 -B 160 -V 1000' % aspect
-+ mp2enc_opts = '-b 128 -r 44100'
-+ mplex_opts = '-f 0 -b 1100 -V -r 3000'
-+ elif vtype in ['vcd', 'pvcd']:
-+ scaler = yuvscaler + ' %s -O VCD %s |' % (widescreen, std)
-+ mpeg2enc_opts = '-f 1 -r 16'
-+ mp2enc_opts = '-V'
-+ mplex_opts = '-f 1'
-+ elif vtype in ['svcd', 'psvcd']:
-+ scaler = yuvscaler + ' %s -O SVCD %s |' % (widescreen, std)
-+ mpeg2enc_opts = '-f 4 -q 7 -I 0 -V 200'
-+ mp2enc_opts = '-V -e'
-+ mplex_opts = '-f 4 -b 200 -r 2750'
-+ elif vtype in ['dvd', 'pdvd']:
-+ scaler = yuvscaler + ' %s -O DVD %s |' % (widescreen, std)
-+ mpeg2enc_opts = '-f 8 -q 7 -4 1 -2 1 -P -I 0'
-+ mp2enc_opts = '-r 48000'
-+ mplex_opts = '-f 8'
-+ elif vtype in ['sdvd', 'spdvd']:
-+ scaler = yuvscaler + ' %s -O DVD %s |' % (widescreen, std)
-+ mpeg2enc_opts = '-f 8 -q 7 -4 1 -2 1 -P -I 0'
-+ pcmsox_opts = '-r 48000 -x -t raw'
-+ mplex_opts = '-f 8 -L 48000:2:16'
-+
-+ if img_dir != work_dir and not enhance:
-+ source_dir = img_dir
-+ else:
-+ source_dir = work_dir
-+ mpegv = tempfile.mkstemp('.mpv', '', work_dir)[1]
-+ if last_num < 99999999:
-+ numframes = str(last_num - first_num + 1)
-+ offset = str(first_num)
-+ else:
-+ numframes = '-1'
-+ offset = '1'
-+
-+ # We set fps to 24 in png/jpeg2yuv because the converter
-+ # has problems with other (correct e.g. 30fps) frame
-+ # rates. In the end this works out OK because we force
-+ # the correct rate with mpeg2enc, although then it's the scaler
-+ # which has problems, and hence we need to use the right
-+ # fps in those cases (which are 25 and 30000/1001 fps, both
-+ # of which fortunately the converter can handle OK). BTW, these
-+ # same problems occur with ppmtoy4m. fps codes 6 and 7 may still
-+ # not work well.
-+
-+ if fpsc not in ['1', '2', '3', '4']: fps = '24'
-+
-+ if vtype == 'qlo':
-+ do_denoise = ''
-+ else:
-+ do_denoise = '%s -t %s %s | ' % (yuvdenoise, denoise, std)
-+
-+ all_vars = {}
-+ all_vars.update(globals())
-+ all_vars.update(locals())
-+
-+ command = """cd %(source_dir)s ; \\
-+%(img2yuv)s -b %(offset)s -n %(numframes)s -f %(fps)s -I p -L 0 -j %(img_pre)s%%08d%(ext)s %(std)s | \\
-+%(do_denoise)s %(scaler)s \\
-+%(mpeg2enc)s %(mpeg2enc_opts)s -o %(mpegv)s""" % all_vars
-+ run(command)
-+
-+ if audio:
-+ if not quiet:
-+ print 'Creating "%s"-quality sound file' % vtype
-+
-+ if vtype in ['sdvd', 'spdvd']:
-+ tmpsndf = tempfile.mkstemp('.lpcm', '', work_dir)[1]
-+ else:
-+ tmpsndf = tempfile.mkstemp('.mp2', '', work_dir)[1]
-+
-+ if rawsndf:
-+ wav = tempfile.mkstemp('.wav', '', work_dir)[1]
-+ sox_opts = '-t raw -r %s -w -c 2 -s' % sndr
-+ command = ' '.join([sox, sox_opts, sndf, wav])
-+ run(command)
-+ else:
-+ wav = sndf
-+
-+ if vtype in ['sdvd', 'spdvd']:
-+ command = ' '.join([sox, wav, pcmsox_opts, tmpsndf, 'resample'])
-+ else:
-+ files = ' '.join(['-o', tmpsndf, '<', wav])
-+ command = ' '.join([mp2enc, mp2enc_opts, files])
-+
-+ run(command)
-+
-+ if delay != '0':
-+ delaysh = str(-1*int(delay))
-+ else:
-+ delaysh = delay
-+
-+ all_vars.update(locals())
-+
-+ if not quiet: print 'Multiplexing...'
-+ command = """
-+%(mplex)s %(mplex_opts)s -O %(delaysh)sms %(tmpsndf)s %(mpegv)s -o "%(vidname)s" """ % all_vars
-+ run(command)
-+
-+ if rawsndf and os.path.exists(wav): os.remove(wav)
-+ if os.path.exists(tmpsndf): os.remove(tmpsndf)
-+ else:
-+ if not quiet: print 'Multiplexing...'
-+ command = """
-+%(mplex)s %(mplex_opts)s %(mpegv)s -o "%(vidname)s" """ % all_vars
-+ run(command)
-+
-+ if os.path.exists(mpegv): os.remove(mpegv)
-+
-+
-+def do_clean():
-+ """
-+ Delete enhanced files
-+ """
-+
-+ if not quiet:
-+ print 'Deleting all enhanced images (if any)'
-+
-+ eframes = os.path.join(work_dir, 'eimg')
-+ rframes = os.path.join(work_dir, 'rimg')
-+ for frame in glob.glob(eframes + '*'):
-+ os.remove(frame)
-+ for frame in glob.glob(rframes + '*'):
-+ os.remove(frame)
-+
-+
-+def which(command):
-+ """
-+ Finds (or not) a command a la "which"
-+ """
-+
-+ command_found = False
-+
-+ if command[0] == '/':
-+ if os.path.isfile(command) and \
-+ os.access(command, os.X_OK):
-+ command_found = True
-+ abs_command = command
-+ else:
-+ path = os.environ.get('PATH', '').split(os.pathsep)
-+ for dir in path:
-+ abs_command = os.path.join(dir, command)
-+ if os.path.isfile(abs_command) and \
-+ os.access(abs_command, os.X_OK):
-+ command_found = True
-+ break
-+
-+ if not command_found:
-+ abs_command = ''
-+
-+ return abs_command
-+
-+
-+def is_installed(prog):
-+ """
-+ See whether "prog" is installed
-+ """
-+
-+ wprog = which(prog)
-+
-+ if wprog == '':
-+ print prog + ': command not found'
-+ raise SystemExit
-+ else:
-+ if verbose:
-+ print wprog + ': found'
-+
-+
-+if __name__ == '__main__':
-+
-+ import os
-+ import sys
-+ import getopt
-+ import shutil
-+ import tempfile
-+ import glob
-+ import tarfile
-+
-+ try:
-+ if sys.version_info[0:3] < (2, 3, 0):
-+ raise SystemExit
-+ except:
-+ print 'You need Python 2.3.0 or greater to run me!'
-+ raise SystemExit
-+
-+ try:
-+ (opts, args) = getopt.getopt(sys.argv[1:], \
-+ 'ho:p:d:w:a:qvt:ekc:r:s:b:f:VCD:L:')
-+ except:
-+ print "Something's wrong. Try the '-h' flag."
-+ raise SystemExit
-+
-+ opts = dict(opts)
-+
-+ if not opts and not args:
-+ print usage
-+ raise SystemExit
-+
-+ if '-h' in opts:
-+ print usage + help
-+ raise SystemExit
-+
-+ if '-V' in opts:
-+ print 'mpeg_encoder.py version ' + version
-+ raise SystemExit
-+
-+ if ('-v' in opts) or ('-C' in opts):
-+ verbose = True
-+ else:
-+ verbose = False
-+
-+ if '-q' in opts:
-+ quiet = True
-+ verbose = False
-+ else:
-+ quiet = False
-+
-+ for i in [convert, mpeg2enc, mp2enc, sox, png2yuv, jpeg2yuv, \
-+ yuvdenoise, yuvscaler, mplex]:
-+ is_installed(i)
-+ if '-C' in opts: raise SystemExit
-+
-+ img_pre = opts.get('-p', '')
-+
-+ if img_pre not in ['', 'eimg', 'rimg']:
-+ print 'Improper image name prefix.'
-+ raise SystemExit
-+
-+ temp_dir = ''
-+ img_dir = opts.get('-d', '.')
-+ img_dir = os.path.abspath(img_dir)
-+ if ' ' in img_dir:
-+ temp_dir = tempfile.mkdtemp('', '.lives-', '/tmp/')
-+ os.symlink(img_dir, temp_dir + '/img_dir')
-+ img_dir = temp_dir + '/img_dir'
-+
-+ if not os.path.isdir(img_dir):
-+ print 'The image source directory: ' + img_dir + \
-+ ' does not exist!'
-+ raise SystemExit
-+
-+ if len(args) not in [0, 2]:
-+ print 'If frames are specified both first and last ' + \
-+ 'image numbers must be chosen.'
-+ raise SystemExit
-+ elif len(args) == 0:
-+ args = [None, None]
-+
-+ frame_range = False
-+ if not args[0]:
-+ first_frame_num = '1'
-+ else:
-+ frame_range = True
-+ first_frame_num = args[0]
-+ first_frame_num = first_frame_num.zfill(8)
-+ first_num = int(first_frame_num)
-+
-+ if not args[1]:
-+ last_frame_num = '99999999'
-+ else:
-+ last_frame_num = args[1]
-+ last_frame_num = last_frame_num.zfill(8)
-+ last_num = int(last_frame_num)
-+
-+ aspect = opts.get('-a', '2')
-+
-+ if aspect not in [str(i) for i in xrange(1,5)]:
-+ print 'Invalid aspect ratio.'
-+ raise SystemExit
-+
-+ # 2.21:1 seems to be broken in mp2enc!
-+ if aspect == '4':
-+ if not quiet: print "Warning: using aspect ratio 16:9 instead of 2.21:1."
-+ aspect = '3'
-+
-+ vtype = opts.get('-t', 'ml')
-+
-+ if vtype not in ['hi', 'mh', 'ml', 'lo', \
-+ 'qlo', 'vcd', 'svcd', 'dvd', \
-+ 'pvcd', 'psvcd', 'pdvd', \
-+ 'sdvd', 'spdvd']:
-+ print 'Invalid video type.'
-+ raise SystemExit
-+
-+ out_mpg = opts.get('-o', vtype + '_movie.mpg')
-+
-+ fpsc = opts.get('-f', '4')
-+
-+ if fpsc not in [str(i) for i in xrange(1,9)]:
-+ print 'Invalid fps code.'
-+ raise SystemExit
-+ elif vtype in ['vcd', 'svcd', 'dvd', 'sdvd']:
-+ fps = str(30000.0/1001.0)
-+ elif vtype in ['pvcd', 'psvcd', 'pdvd', 'spdvd']:
-+ fps = str(25.0)
-+ else:
-+ if fpsc == '1': fps = str(24000.0/1001.0)
-+ elif fpsc == '2': fps = str(24.0)
-+ elif fpsc == '3': fps = str(25.0)
-+ elif fpsc == '4': fps = str(30000.0/1001.0)
-+ elif fpsc == '5': fps = str(30.0)
-+ elif fpsc == '6': fps = str(50.0)
-+ elif fpsc == '7': fps = str(60000.0/1001.0)
-+ elif fpsc == '8': fps = str(60.0)
-+
-+ if '-e' not in opts:
-+ enhance = False
-+ else:
-+ enhance = True
-+
-+ if enhance and img_pre:
-+ print 'Sorry, you cannot enhance already-enhanced images'
-+ raise SystemExit
-+
-+ if '-k' not in opts:
-+ keep = False
-+ else:
-+ keep = True
-+
-+ cgeom = opts.get('-c', '')
-+ rgeom = opts.get('-r', '')
-+
-+ if (cgeom or rgeom) and not enhance:
-+ print 'Missing "-e" option.'
-+ raise SystemExit
-+
-+ lv1file = opts.get('-L', None)
-+ if lv1file:
-+ if not quiet: print 'Opening lv1 file...'
-+ try:
-+ lv1 = tarfile.open(os.path.abspath(lv1file))
-+ except:
-+ print 'This does not appear to be a valid LiVES file!'
-+ raise SystemExit
-+ if 'header.tar' not in lv1.getnames():
-+ print 'This does not appear to be a valid LiVES file!'
-+ raise SystemExit
-+ for tfile in lv1.getmembers():
-+ lv1.extract(tfile, img_dir)
-+ for tfile in glob.glob(os.path.join(img_dir, '*.tar')):
-+ imgtar = tarfile.open(tfile)
-+ for img in imgtar.getmembers():
-+ imgtar.extract(img, img_dir)
-+ os.remove(tfile)
-+
-+ test_file = os.path.join(img_dir, img_pre + first_frame_num)
-+ if os.path.isfile(test_file + '.jpg'):
-+ ext = '.jpg'
-+ elif os.path.isfile(test_file + '.png'):
-+ ext = '.png'
-+ else:
-+ print 'Cannot find any appropriate %s or %s files!' % ('.jpg','.png')
-+ raise SystemExit
-+ first_frame = test_file + ext
-+ last_frame = os.path.join(img_dir, img_pre + last_frame_num + ext)
-+
-+ if not quiet: print 'Found: ' + first_frame
-+
-+ work_dir = opts.get('-w', img_dir)
-+ work_dir = os.path.abspath(work_dir)
-+ if not os.path.isdir(work_dir):
-+ if not quiet: print 'Creating ' + work_dir
-+ try:
-+ os.makedirs(work_dir)
-+ os.chmod(work_dir, 0755)
-+ except:
-+ print 'Could not create the work directory ' + \
-+ work_dir
-+ raise SystemExit
-+ if ' ' in work_dir:
-+ if temp_dir == '':
-+ temp_dir = tempfile.mkdtemp('', '.lives-', '/tmp/')
-+ os.symlink(work_dir, temp_dir + '/work_dir')
-+ work_dir = temp_dir + '/work_dir'
-+
-+ sndf = opts.get('-s', os.path.join(img_dir, 'audio'))
-+# sndf = os.path.abspath(sndf)
-+ rawsndf = True
-+ if not os.path.isfile(sndf):
-+ audio = False
-+ rawsndf = False
-+ else:
-+ audio = True
-+ if sndf[-4:] == '.wav':
-+ rawsndf = False
-+ if not quiet: print 'Found audio file: ' + sndf
-+
-+ sndr = opts.get('-b', '44100')
-+
-+ delay = opts.get('-D', '0')
-+ if verbose and audio: print 'Linear audio delay (ms): ' + delay
-+
-+ if enhance:
-+ do_enhance()
-+ # Note that do_enhance() always creates images prefixed
-+ # with 'rimg'. What's important to note if that if the
-+ # images are resized the 'rimg' are indeed resized, but
-+ # if not the 'rimg' are simply symlinks to (or copies of) the 'eimg'
-+ # (enhanced) images.
-+ img_pre = 'rimg'
-+ ext = '.png'
-+ vidname = os.path.join(work_dir, out_mpg)
-+ # do_encode() acts on images prefixed by img_pre.
-+ do_encode()
-+ if not keep:
-+ do_clean()
-+ if temp_dir != '':
-+ shutil.rmtree(temp_dir)
-+ if not quiet: print "Done!"
-+
-+
-+"""
-+CHANGELOG:
-+
-+21 Jul 2004 : 0.0.2 : fixed frame range error in img2yuv argument.
-+ added support for ".wav" files.
-+ added '-C' flag.
-+28 Jul 2004 : 0.0.3 : added '-D' flag.
-+ fixed typos.
-+ eliminated some subshell calls.
-+ convert dirs to absolute paths.
-+ fixed work_dir permissions.
-+30 Jul 2004 : 0.0.4 : added '-L' flag.
-+ encoder is now feature-complete.
-+25 Sep 2004 : 0.0.5 : make sure "rawsndf" is set correctly.
-+ check if files exist before removing.
-+02 Oct 2004 : 0.0.6 : multiplex even if no audio.
-+28 Oct 2004 : 0.0.7 : added support for PAL (untested!).
-+ fps fix in "common_options".
-+08 Nov 2004 : 0.0.8 : make sure that the enhanced
-+ color depth is 8-bits/channel.
-+05 Dec 2004 : 0.0.9 : tweak encoding parameters.
-+ mention raw audio settings in help.
-+02 Jan 2005 : 0.1.0 : updated docs.
-+ added sound rate (-b) option.
-+05 Jan 2005 : 0.1.1 : bypass an fps/aspect ratio jpeg2yuv bug.
-+ letterbox if 2.21:1.
-+29 Jan 2005 : 0.1.2 : fix fps 0.1.1 regression.
-+21 Mar 2005 : 0.1.3 : use env python (hopefully >= 2.3)
-+26 Mar 2005 : 0.1.4 : added "qlo" setting.
-+27 Jun 2005 : 0.1.5 : added "sdvd" and "spdvd" settings.
-+26 Aug 2005 : 0.1.6 : Bypass 2.21:1 brokenness.
-+09 Mar 2006 : 0.1.7 : added '-depth 8' to resize, as ImageMagick
-+ keeps changing its damn behaviour.
-+28 Jun 2007 : 0.1.8 : handles paths with spaces appropriately
-+ (thanks Gabriel).
-+"""
---- lives.orig/lives-plugins/marcos-encoders/mpeg_encoder.py
-+++ /dev/null
-@@ -1,886 +0,0 @@
--#!/usr/bin/env python
--
--"""
--mpeg_encoder.py
--
--Simple front-end to MJPEGtools with some image-enhancing
--capabilities through the use of ImageMagick. Meant as a
--companion to LiVES (to possibly call from within a plugin,
--see http://www.xs4all.nl/~salsaman/lives/ ) but can also
--be used as a stand-alone program.
--
--Requires MJPEGtools, ImageMagick (GraphicsMagick might also
--work), sox, and Python 2.3.0 or greater.
--
--Copyright (C) 2004-2005 Marco De la Cruz (marco at reimeika.ca)
--It's a trivial program, but might as well GPL it, so see:
--http://www.gnu.org/copyleft/gpl.html for license.
--
--See my vids at http://amv.reimeika.ca !
--"""
--
--version = '0.1.8'
--convert = 'convert'
--mpeg2enc = 'mpeg2enc'
--mp2enc = 'mp2enc'
--sox = 'sox'
--png2yuv = 'png2yuv'
--jpeg2yuv = 'jpeg2yuv'
--yuvdenoise = 'yuvdenoise'
--yuvscaler = 'yuvscaler'
--mplex = 'mplex'
--
--usage = \
-- """
--mpeg_encoder.py -h
--mpeg_encoder.py -V
--mpeg_encoder.py -C
--mpeg_encoder.py [-o out] [-p pre] [-d dir] [-a aspect] [-D delay]
-- [-q|-v] [-t type] [-k] [-e [[-w dir] [-c geom] [-r geom]]]
-- [-s sndfile] [-b sndrate] [-f fpscode] [-L lv1file]
-- [firstframe lastframe]
-- """
--
--help = \
-- """
--SUMMARY (ver. %s):
--
--Encodes a series of PNG or JPG images into an MPEG-1 or MPEG-2
--stream. It behaves mostly as a simplified front-end to mjpegtools,
--although it is also capable of performing some simple image
--enhacements using ImageMagick. The images and audio are assumed to
--be in an uncompressed LiVES format, hence making this encoder
--more suitable to be used within a LiVES plugin (but can also
--be used directly on a LiVES temporary directory).
--
--Note: this program currently handles only non-interlaced source.
--
--OPTIONS:
--
---h for help.
--
---V shows the version number.
--
---C check external program dependencies and exit.
--
---o out will save the video in file "out".
-- Default: "'type'_movie.mpg". See below for 'type'.
--
---p pre the encoder assumes that sound and images are named using
-- LiVES' conventions i.e. "audio" and "00000001.ext",
-- "00000002.ext"... where "ext" is either "jpg" or "png".
-- However, mpeg_encoder.py will create temporary files
-- which can be saved for later use (for example, after
-- enhancing the images with "-e" , which may take a long
-- time). These temporary files will be named
-- "pre_00000001.ext", etc... where "pre" is either "eimg"
-- or "rimg" and will be kept if the "-k" option is used.
-- mpeg_encoder.py can then be run over the enhanced images
-- only by selecting the appropriate prefix ("eimg" or
-- "rimg") here. See "-e" to see what each prefix means.
-- Default: "" (an empty string).
--
---d dir "dir" is the directory containing the source image
-- files. These must be of the form "00000001.ext" or
-- "pre_00000001.ext" as explained above.
-- Default: "."
--
---a aspect sets the aspect ratio of the resulting MPEG. This can be:
--
-- 1 1:1 display
-- 2 4:3 display
-- 3 16:9 display
-- 4 2.21:1 display (does not really work)
--
-- Currently selecting "4" will fall back to "3".
-- Default: "2"
--
---D delay linearly delay the audio stream by "delay" ms.
-- Default: "0"
--
---q quiet operation, only complains on error.
--
---v be verbose.
--
---t type type of video created. The options here are:
--
-- "hi": a very high quality MPEG-1 file, suitable
-- for archiving images of 720x480.
--
-- "mh": medium-high quality MPEG-1, which still allows
-- to watch small videos (352x240 and below)
-- fullscreen.
--
-- "ml": medium-low quality MPEG-1, suitable for
-- most videos but in particular small videos
-- (352x240 and below) meant for online
-- distribution.
--
-- "lo": a low quality MPEG-1 format. Enlarging
-- small videos will result in very noticeable
-- artifacts. Good for distributing over slow
-- connections.
--
-- "qlo": a quick and dirty (but fast) low quality MPEG-1.
--
-- "vcd": VCD-conformant MPEG-1 stream (NTSC VIDEO).
--
-- "svcd": SVCD-conformant MPEG-2 stream (NTSC VIDEO).
--
-- "dvd": DVD-conformant MPEG-2 stream (NTSC VIDEO).
--
-- "sdvd": Strictly DVD-conformant MPEG-2 stream (NTSC VIDEO).
--
-- "pvcd": VCD-conformant MPEG-1 stream (PAL VIDEO).
--
-- "psvcd": SVCD-conformant MPEG-2 stream (PAL VIDEO).
--
-- "pdvd": DVD-conformant MPEG-2 stream (PAL VIDEO).
--
-- "spdvd": Strictly DVD-conformant MPEG-2 stream (PAL VIDEO).
--
-- Default: "ml"
--
---e perform some simple filtering/enhancement to improve image
-- quality. The images created by using this option will be
-- stored in the directory specified by the "-w" option (or
-- "-d" if not present, see above) and each filename will be
-- prefixed with "eimg" (see "-p" above). Using this option will
-- take enormous amounts of disk space, and in reality does
-- not do anything that cannot be done within LiVES itself.
-- Using this option enables the following four:
--
-- -w dir "dir" is the working directory where the enhanced
-- images will be saved. Although these can all
-- co-exist with the original LiVES files it is
-- recommended you use a different directory. Note
-- that temporary files may take a huge amount of
-- space, perhaps twice as much as the LiVES files
-- themselves. If this directory does not exist is
-- will be created.
-- Default: same as "-d".
--
-- -k keep the temporary files, useful to experiment
-- with different encoding types without having
-- to repeatedly enhance the images (which can be
-- very time-consuming). See "-p" above.
--
-- -c geom in addition to enhancing the images, crop them
-- to the specified geometry e.g. "688x448+17+11".
-- Filename prefix remains "eimg". Note that the
-- dimensions of the images should both be multiples
-- of "16", otherwise some players may show artifacts
-- (such as garbage or green bars at the borders).
--
-- -r geom this will create a second set of images resulting
-- from resizing the images that have already been
-- enhanced and possibly cropped (if "-c" has been
-- specified). The geometry here is simple a new
-- image size e.g. "352x240!". This second set will have
-- filenames prefixed with the string "rimg" (see "-p"
-- above). Note that the dimensions of the images
-- should both be multiples of "16", otherwise some
-- players may show artifacts (such as garbage or
-- green bars at the borders).
--
---s sndfile name of the audio file. Can be either raw "audio" or
-- "[/path/to/]soundfile.wav". Note that for raw audio
-- the sound will always be stereo and sampled at 44100Hz.
-- Default: "audio" inside "dir" as specified by "-d".
--
---b sndrate sample rate of the sound file in Hertz.
-- Default: "44100".
--
---f fpscode frame-rate code. Acceptable values are:
--
-- 1 - 24000.0/1001.0 (NTSC 3:2 pulldown converted FILM)
-- 2 - 24.0 (NATIVE FILM)
-- 3 - 25.0 (PAL/SECAM VIDEO / converted FILM)
-- 4 - 30000.0/1001.0 (NTSC VIDEO)
-- 5 - 30.0
-- 6 - 50.0 (PAL FIELD RATE)
-- 7 - 60000.0/1001.0 (NTSC FIELD RATE)
-- 8 - 60.0
--
-- Note that when type is "vcd", "svcd", or "(s)dvd" this value
-- is set to "4" to make NTSC video. For "pvcd", "psvcd", or
-- "(s)pdvd" the value is set to "3".
--
-- Default: "4".
--
---L lv1file use the images stored in the LiVES file "lv1file" (e.g.
-- "movie.lv1"). Files will be extracted inside "dir" as
-- specified by "-d". Using this option allows to encode
-- a movie without having to restore it first with LiVES.
-- Note that the encoder will not delete the extracted
-- files after it has finished, this must be done manually
-- afterwards. If frame code/rate (-f) and/or sound rate (-b)
-- are not specified the defaults will be used (30000/1001 fps
-- and 44100 Hz). These, however, may not be correct, in which
-- case they should be specified explicitly. Furthermore, the
-- .lv1 audio (if present) is always assumed to have a sample
-- data size in 16-bit words with two channels, and to be signed
-- linear (this is usually the case, however). If any of these
-- latter parameters are incorrect the resulting file may be
-- corrupted and encoding will have to be done using LiVES.
--
--firstframe first frame number. If less than eight digits long it will
-- be padded with zeroes e.g. 234 -> 00000234. A prefix can
-- be added using the "-p" option.
-- Default: "00000001"
--
--lastframe last frame number, padded with zeroes if necessary, prefix
-- set by "-p".
-- Default: the last frame of its type in the "-d" directory,
-- where "type" is set by the prefix.
--
--Note that either no frames or both first and last frames must be specified.
--
--EXAMPLES:
--
--Suppose you have restored a LiVES' .lv1 file (in either JPG or PNG format),
--and that the images are stored in the directory "/tmp/livestmp/991319584/".
--In this example the movie is assumed to be 16:9. NOTE THAT THE VIDEO MUST
--BE PROGRESSIVE (NON-INTERLACED) FOR THIS TO WORK. Then, in order to
--create an MPEG-1 file you can simply do the following:
--
-- mpeg_encoder.py -d /tmp/livestmp/991319584 -o /movies/default.mpg -a 3
--
--and the clip "default.mpg" will be created in "/movies/" with the correct
--aspect ratio.
--
--Suppose we want to make a downloadable version of the clip, small in size
--but of good quality. The following command activates the generic enhancement
--filter and resizes the images to "352x240". Note that these operations
--are performed after cropping the originals a bit (using "704x464+5+6").
--This is done because we are assuming that there is a black border around
--the original pictures which we want to get rid of (this might distort the
--images somewhat, so be careful about cropping/resizing, and remember to
--use dimensions which are multiples of 16):
--
-- mpeg_encoder.py -v -d /tmp/livestmp/991319584 -w /tmp/tmpmpg \\
-- -o /movies/download.mpg -a 3 -k -e -c "704x464+5+6" -r "352x240"
--
--Since we use the "-k" flag the enhanced images are kept (both full-size
--crops and the resized ones) in "/tmp/tmpmpg". Beware that this may consume
--a lot of disk space (about 10x as much as the originals). The reason we
--keep them is because the above may take quite a long time and we may want
--to re-use the enhanced images. So, for example, creating a high-quality
--clip at full size can be accomplished now as follows:
--
-- mpeg_encoder.py -d /tmp/tmpmpg -t hi -o /movies/archive.mpg \\
-- -s /tmp/livestmp/991319584/audio -a 3 -k -p eimg
--
--Creating VCD/SVCD/DVD-compatible clips is also readily done:
--
-- mpeg_encoder.py -d /tmp/tmpmpg -t vcd -o /movies/vcd.mpg \\
-- -s /tmp/livestmp/991319584/audio -a 3 -k -p eimg
--
-- mpeg_encoder.py -q -d /tmp/tmpmpg -t svcd -o /movies/svcd.mpg \\
-- -s /tmp/livestmp/991319584/audio -a 3 -k -p eimg
--
-- mpeg_encoder.py -v -d /tmp/tmpmpg -t dvd -o /movies/dvd.mpg \\
-- -s /tmp/livestmp/991319584/audio -a 3 -k -p eimg
--
--If, for example, we only want to encode frames 100 to 150 we can run
--the following:
--
-- mpeg_encoder.py -v -d /tmp/tmpmpg -o /movies/selection.mpg \\
-- -a 3 -k -p eimg 100 150
--
--Note that no audio has been selected ("-s"). This is because
--mpeg_encoder.py cannot trim the audio to the appropriate length.
--You would need to use LiVES to do this.
--
--To delete all the enhanced images you can just remove "/tmp/tmpmpg".
--
--If you notice that the video and audio become out of sync so that
--near the end of the movie the video trails the audio by, say, 0.2s,
--you can use the "-D" option as follows:
--
-- mpeg_encoder.py -d /tmp/livestmp/991319584 -o test.mpg -D 200
--
--Note that negative time values are also allowed.
--
--Suppose that you have "movie1.lv1", "movie2.lv1" and "movie3.lv1".
--Batch-encoding can be done as follows (zsh-syntax):
--
-- for i in movie?.lv1
-- do
-- mkdir /tmp/$i:r
-- mpeg_encoder.py -d /tmp/$i:r -o /tmp/$i:r.mpg -L $i
-- rm -rf /tmp/$i:r
-- done
--
--This will generate the files "movie1.mpg", "movie2.mpg" and
--"movie3.mpg" in "/tmp". Note that is is not necessary to
--specify whether the files are stored in JPG or PNG format,
--and that potentially time-consuming options (e.g. "-e") may
--be enabled. It is not necessary to have a working LiVES
--installation to encode .lv1 files.
-- """ % version
--
--def run(command):
-- """
-- Run a shell command
-- """
--
-- if verbose:
-- print 'Running: \n' + command + '\n=== ... ==='
-- std = ''
-- else:
-- std = ' > /dev/null 2>&1'
--
-- os.system(command + std)
--
--
--def do_enhance():
-- """
-- Image cleanup/crop/resize routine. Generic, but seems to work
-- well with anime :)
-- """
--
-- if not quiet:
-- print 'Enhancing images... please wait, this might take long...'
--
-- enh_opts = "-enhance -sharpen '0.0x0.5' -gamma 1.2 -contrast -depth 8"
--
-- if cgeom:
-- docrop = ' '.join(['-crop', "'%s!'" % cgeom])
-- else:
-- docrop = ''
--
-- iframe = first_num
-- while True:
-- # File names are padded with zeroes to 8 characters
-- # (not counting the .ext).
-- frame = str(iframe).zfill(8)
-- fname = os.path.join(img_dir, frame + ext)
-- if not os.path.isfile(fname) or (iframe == last_num + 1):
-- break
-- eimg_fname = os.path.join(work_dir, 'eimg' + frame + '.png')
-- rimg_fname = os.path.join(work_dir, 'rimg' + frame + '.png')
-- command = ' '.join([convert, docrop, enh_opts, fname, eimg_fname])
-- run(command)
-- if rgeom:
-- if os.path.exists(rimg_fname): os.remove(rimg_fname)
-- shrink = ' '.join([convert, '-resize', "'%s!'" % rgeom, '-depth 8'])
-- command = ' '.join([shrink, eimg_fname, rimg_fname])
-- run(command)
-- else:
-- if os.path.exists(rimg_fname): os.remove(rimg_fname)
-- try:
-- os.symlink(eimg_fname, rimg_fname)
-- except (IOError, OSError):
-- shutil.copy(eimg_fname, rimg_fname)
-- iframe+=1
--
--
--def do_encode():
-- """
-- Encode a series of images into an MPEG stream, multiplexing
-- audio if necessary
-- """
--
-- if not quiet:
-- print 'Creating "%s"-quality MPEG' % vtype
--
-- if verbose:
-- std = ''
-- else:
-- std = ' 2> /dev/null'
--
-- # There are a lot of magic numbers here, but in a sense that's
-- # the point of boiling down all the complicated parameter settings
-- # to "low", "medium lo/hi", and "hi". These numbers work OK, but
-- # in order to fully understand them it is necessary to read the
-- # excellent MJPEGtools HOWTO:
-- # https://sourceforge.net/docman/display_doc.php?docid=3456&group_id=5776
--
-- scaler = ''
-- denoise = '2'
-- if vtype == 'qlo':
-- common_opts = ' -f 0 -F %s -r 8 -4 4 -2 4 -P ' % fpsc
-- else:
-- common_opts = ' -f 0 -F %s -H -r 24 -4 1 -2 1 -P -g 6 -G 18 ' % fpsc
-- if aspect in ['3','4']:
-- widescreen = '-M WIDE2STD'
-- else:
-- widescreen = ''
-- if ext == '.png':
-- img2yuv = png2yuv
-- else:
-- img2yuv = jpeg2yuv
--
-- # For -B: round up (vid + audio)*0.01 + audio bitrates
-- # For -r: round up (vid + audio)*1.02
-- # For -V: decent software decoder... push this up to 500K+
-- # For -b in mplex: "at least -V". I do -V*1.1
--
-- if vtype == 'hi':
-- mpeg2enc_opts = common_opts + \
-- '-a %s -b 13000 -q 4 -B 600 -V 2000' % aspect
-- mp2enc_opts = '-b 384 -r 44100'
-- mplex_opts = '-f 0 -b 2200 -V -r 14000'
-- elif vtype == 'mh':
-- mpeg2enc_opts = common_opts + \
-- '-a %s -b 6500 -q 4 -B 350 -V 1000' % aspect
-- mp2enc_opts = '-b 256 -r 44100'
-- mplex_opts = '-f 0 -b 1100 -V -r 7000'
-- elif vtype == 'ml':
-- denoise = '1'
-- mpeg2enc_opts = common_opts + \
-- '-a %s -b 6500 -q 4 -B 300 -V 1000' % aspect
-- mp2enc_opts = '-b 192 -r 44100'
-- mplex_opts = '-f 0 -b 1100 -V -r 7000'
-- elif vtype in ['lo', 'qlo']:
-- denoise = '1'
-- mpeg2enc_opts = common_opts + \
-- '-a %s -b 2500 -q 6 -B 160 -V 1000' % aspect
-- mp2enc_opts = '-b 128 -r 44100'
-- mplex_opts = '-f 0 -b 1100 -V -r 3000'
-- elif vtype in ['vcd', 'pvcd']:
-- scaler = yuvscaler + ' %s -O VCD %s |' % (widescreen, std)
-- mpeg2enc_opts = '-f 1 -r 16'
-- mp2enc_opts = '-V'
-- mplex_opts = '-f 1'
-- elif vtype in ['svcd', 'psvcd']:
-- scaler = yuvscaler + ' %s -O SVCD %s |' % (widescreen, std)
-- mpeg2enc_opts = '-f 4 -q 7 -I 0 -V 200'
-- mp2enc_opts = '-V -e'
-- mplex_opts = '-f 4 -b 200 -r 2750'
-- elif vtype in ['dvd', 'pdvd']:
-- scaler = yuvscaler + ' %s -O DVD %s |' % (widescreen, std)
-- mpeg2enc_opts = '-f 8 -q 7 -4 1 -2 1 -P -I 0'
-- mp2enc_opts = '-r 48000'
-- mplex_opts = '-f 8'
-- elif vtype in ['sdvd', 'spdvd']:
-- scaler = yuvscaler + ' %s -O DVD %s |' % (widescreen, std)
-- mpeg2enc_opts = '-f 8 -q 7 -4 1 -2 1 -P -I 0'
-- pcmsox_opts = '-r 48000 -x -t raw'
-- mplex_opts = '-f 8 -L 48000:2:16'
--
-- if img_dir != work_dir and not enhance:
-- source_dir = img_dir
-- else:
-- source_dir = work_dir
-- mpegv = tempfile.mkstemp('.mpv', '', work_dir)[1]
-- if last_num < 99999999:
-- numframes = str(last_num - first_num + 1)
-- offset = str(first_num)
-- else:
-- numframes = '-1'
-- offset = '1'
--
-- # We set fps to 24 in png/jpeg2yuv because the converter
-- # has problems with other (correct e.g. 30fps) frame
-- # rates. In the end this works out OK because we force
-- # the correct rate with mpeg2enc, although then it's the scaler
-- # which has problems, and hence we need to use the right
-- # fps in those cases (which are 25 and 30000/1001 fps, both
-- # of which fortunately the converter can handle OK). BTW, these
-- # same problems occur with ppmtoy4m. fps codes 6 and 7 may still
-- # not work well.
--
-- if fpsc not in ['1', '2', '3', '4']: fps = '24'
--
-- if vtype == 'qlo':
-- do_denoise = ''
-- else:
-- do_denoise = '%s -t %s %s | ' % (yuvdenoise, denoise, std)
--
-- all_vars = {}
-- all_vars.update(globals())
-- all_vars.update(locals())
--
-- command = """cd %(source_dir)s ; \\
--%(img2yuv)s -b %(offset)s -n %(numframes)s -f %(fps)s -I p -L 0 -j %(img_pre)s%%08d%(ext)s %(std)s | \\
--%(do_denoise)s %(scaler)s \\
--%(mpeg2enc)s %(mpeg2enc_opts)s -o %(mpegv)s""" % all_vars
-- run(command)
--
-- if audio:
-- if not quiet:
-- print 'Creating "%s"-quality sound file' % vtype
--
-- if vtype in ['sdvd', 'spdvd']:
-- tmpsndf = tempfile.mkstemp('.lpcm', '', work_dir)[1]
-- else:
-- tmpsndf = tempfile.mkstemp('.mp2', '', work_dir)[1]
--
-- if rawsndf:
-- wav = tempfile.mkstemp('.wav', '', work_dir)[1]
-- sox_opts = '-t raw -r %s -w -c 2 -s' % sndr
-- command = ' '.join([sox, sox_opts, sndf, wav])
-- run(command)
-- else:
-- wav = sndf
--
-- if vtype in ['sdvd', 'spdvd']:
-- command = ' '.join([sox, wav, pcmsox_opts, tmpsndf, 'resample'])
-- else:
-- files = ' '.join(['-o', tmpsndf, '<', wav])
-- command = ' '.join([mp2enc, mp2enc_opts, files])
--
-- run(command)
--
-- if delay != '0':
-- delaysh = str(-1*int(delay))
-- else:
-- delaysh = delay
--
-- all_vars.update(locals())
--
-- if not quiet: print 'Multiplexing...'
-- command = """
--%(mplex)s %(mplex_opts)s -O %(delaysh)sms %(tmpsndf)s %(mpegv)s -o "%(vidname)s" """ % all_vars
-- run(command)
--
-- if rawsndf and os.path.exists(wav): os.remove(wav)
-- if os.path.exists(tmpsndf): os.remove(tmpsndf)
-- else:
-- if not quiet: print 'Multiplexing...'
-- command = """
--%(mplex)s %(mplex_opts)s %(mpegv)s -o "%(vidname)s" """ % all_vars
-- run(command)
--
-- if os.path.exists(mpegv): os.remove(mpegv)
--
--
--def do_clean():
-- """
-- Delete enhanced files
-- """
--
-- if not quiet:
-- print 'Deleting all enhanced images (if any)'
--
-- eframes = os.path.join(work_dir, 'eimg')
-- rframes = os.path.join(work_dir, 'rimg')
-- for frame in glob.glob(eframes + '*'):
-- os.remove(frame)
-- for frame in glob.glob(rframes + '*'):
-- os.remove(frame)
--
--
--def which(command):
-- """
-- Finds (or not) a command a la "which"
-- """
--
-- command_found = False
--
-- if command[0] == '/':
-- if os.path.isfile(command) and \
-- os.access(command, os.X_OK):
-- command_found = True
-- abs_command = command
-- else:
-- path = os.environ.get('PATH', '').split(os.pathsep)
-- for dir in path:
-- abs_command = os.path.join(dir, command)
-- if os.path.isfile(abs_command) and \
-- os.access(abs_command, os.X_OK):
-- command_found = True
-- break
--
-- if not command_found:
-- abs_command = ''
--
-- return abs_command
--
--
--def is_installed(prog):
-- """
-- See whether "prog" is installed
-- """
--
-- wprog = which(prog)
--
-- if wprog == '':
-- print prog + ': command not found'
-- raise SystemExit
-- else:
-- if verbose:
-- print wprog + ': found'
--
--
--if __name__ == '__main__':
--
-- import os
-- import sys
-- import getopt
-- import shutil
-- import tempfile
-- import glob
-- import tarfile
--
-- try:
-- if sys.version_info[0:3] < (2, 3, 0):
-- raise SystemExit
-- except:
-- print 'You need Python 2.3.0 or greater to run me!'
-- raise SystemExit
--
-- try:
-- (opts, args) = getopt.getopt(sys.argv[1:], \
-- 'ho:p:d:w:a:qvt:ekc:r:s:b:f:VCD:L:')
-- except:
-- print "Something's wrong. Try the '-h' flag."
-- raise SystemExit
--
-- opts = dict(opts)
--
-- if not opts and not args:
-- print usage
-- raise SystemExit
--
-- if '-h' in opts:
-- print usage + help
-- raise SystemExit
--
-- if '-V' in opts:
-- print 'mpeg_encoder.py version ' + version
-- raise SystemExit
--
-- if ('-v' in opts) or ('-C' in opts):
-- verbose = True
-- else:
-- verbose = False
--
-- if '-q' in opts:
-- quiet = True
-- verbose = False
-- else:
-- quiet = False
--
-- for i in [convert, mpeg2enc, mp2enc, sox, png2yuv, jpeg2yuv, \
-- yuvdenoise, yuvscaler, mplex]:
-- is_installed(i)
-- if '-C' in opts: raise SystemExit
--
-- img_pre = opts.get('-p', '')
--
-- if img_pre not in ['', 'eimg', 'rimg']:
-- print 'Improper image name prefix.'
-- raise SystemExit
--
-- temp_dir = ''
-- img_dir = opts.get('-d', '.')
-- img_dir = os.path.abspath(img_dir)
-- if ' ' in img_dir:
-- temp_dir = tempfile.mkdtemp('', '.lives-', '/tmp/')
-- os.symlink(img_dir, temp_dir + '/img_dir')
-- img_dir = temp_dir + '/img_dir'
--
-- if not os.path.isdir(img_dir):
-- print 'The image source directory: ' + img_dir + \
-- ' does not exist!'
-- raise SystemExit
--
-- if len(args) not in [0, 2]:
-- print 'If frames are specified both first and last ' + \
-- 'image numbers must be chosen.'
-- raise SystemExit
-- elif len(args) == 0:
-- args = [None, None]
--
-- frame_range = False
-- if not args[0]:
-- first_frame_num = '1'
-- else:
-- frame_range = True
-- first_frame_num = args[0]
-- first_frame_num = first_frame_num.zfill(8)
-- first_num = int(first_frame_num)
--
-- if not args[1]:
-- last_frame_num = '99999999'
-- else:
-- last_frame_num = args[1]
-- last_frame_num = last_frame_num.zfill(8)
-- last_num = int(last_frame_num)
--
-- aspect = opts.get('-a', '2')
--
-- if aspect not in [str(i) for i in xrange(1,5)]:
-- print 'Invalid aspect ratio.'
-- raise SystemExit
--
-- # 2.21:1 seems to be broken in mp2enc!
-- if aspect == '4':
-- if not quiet: print "Warning: using aspect ratio 16:9 instead of 2.21:1."
-- aspect = '3'
--
-- vtype = opts.get('-t', 'ml')
--
-- if vtype not in ['hi', 'mh', 'ml', 'lo', \
-- 'qlo', 'vcd', 'svcd', 'dvd', \
-- 'pvcd', 'psvcd', 'pdvd', \
-- 'sdvd', 'spdvd']:
-- print 'Invalid video type.'
-- raise SystemExit
--
-- out_mpg = opts.get('-o', vtype + '_movie.mpg')
--
-- fpsc = opts.get('-f', '4')
--
-- if fpsc not in [str(i) for i in xrange(1,9)]:
-- print 'Invalid fps code.'
-- raise SystemExit
-- elif vtype in ['vcd', 'svcd', 'dvd', 'sdvd']:
-- fps = str(30000.0/1001.0)
-- elif vtype in ['pvcd', 'psvcd', 'pdvd', 'spdvd']:
-- fps = str(25.0)
-- else:
-- if fpsc == '1': fps = str(24000.0/1001.0)
-- elif fpsc == '2': fps = str(24.0)
-- elif fpsc == '3': fps = str(25.0)
-- elif fpsc == '4': fps = str(30000.0/1001.0)
-- elif fpsc == '5': fps = str(30.0)
-- elif fpsc == '6': fps = str(50.0)
-- elif fpsc == '7': fps = str(60000.0/1001.0)
-- elif fpsc == '8': fps = str(60.0)
--
-- if '-e' not in opts:
-- enhance = False
-- else:
-- enhance = True
--
-- if enhance and img_pre:
-- print 'Sorry, you cannot enhance already-enhanced images'
-- raise SystemExit
--
-- if '-k' not in opts:
-- keep = False
-- else:
-- keep = True
--
-- cgeom = opts.get('-c', '')
-- rgeom = opts.get('-r', '')
--
-- if (cgeom or rgeom) and not enhance:
-- print 'Missing "-e" option.'
-- raise SystemExit
--
-- lv1file = opts.get('-L', None)
-- if lv1file:
-- if not quiet: print 'Opening lv1 file...'
-- try:
-- lv1 = tarfile.open(os.path.abspath(lv1file))
-- except:
-- print 'This does not appear to be a valid LiVES file!'
-- raise SystemExit
-- if 'header.tar' not in lv1.getnames():
-- print 'This does not appear to be a valid LiVES file!'
-- raise SystemExit
-- for tfile in lv1.getmembers():
-- lv1.extract(tfile, img_dir)
-- for tfile in glob.glob(os.path.join(img_dir, '*.tar')):
-- imgtar = tarfile.open(tfile)
-- for img in imgtar.getmembers():
-- imgtar.extract(img, img_dir)
-- os.remove(tfile)
--
-- test_file = os.path.join(img_dir, img_pre + first_frame_num)
-- if os.path.isfile(test_file + '.jpg'):
-- ext = '.jpg'
-- elif os.path.isfile(test_file + '.png'):
-- ext = '.png'
-- else:
-- print 'Cannot find any appropriate %s or %s files!' % ('.jpg','.png')
-- raise SystemExit
-- first_frame = test_file + ext
-- last_frame = os.path.join(img_dir, img_pre + last_frame_num + ext)
--
-- if not quiet: print 'Found: ' + first_frame
--
-- work_dir = opts.get('-w', img_dir)
-- work_dir = os.path.abspath(work_dir)
-- if not os.path.isdir(work_dir):
-- if not quiet: print 'Creating ' + work_dir
-- try:
-- os.makedirs(work_dir)
-- os.chmod(work_dir, 0755)
-- except:
-- print 'Could not create the work directory ' + \
-- work_dir
-- raise SystemExit
-- if ' ' in work_dir:
-- if temp_dir == '':
-- temp_dir = tempfile.mkdtemp('', '.lives-', '/tmp/')
-- os.symlink(work_dir, temp_dir + '/work_dir')
-- work_dir = temp_dir + '/work_dir'
--
-- sndf = opts.get('-s', os.path.join(img_dir, 'audio'))
--# sndf = os.path.abspath(sndf)
-- rawsndf = True
-- if not os.path.isfile(sndf):
-- audio = False
-- rawsndf = False
-- else:
-- audio = True
-- if sndf[-4:] == '.wav':
-- rawsndf = False
-- if not quiet: print 'Found audio file: ' + sndf
--
-- sndr = opts.get('-b', '44100')
--
-- delay = opts.get('-D', '0')
-- if verbose and audio: print 'Linear audio delay (ms): ' + delay
--
-- if enhance:
-- do_enhance()
-- # Note that do_enhance() always creates images prefixed
-- # with 'rimg'. What's important to note if that if the
-- # images are resized the 'rimg' are indeed resized, but
-- # if not the 'rimg' are simply symlinks to (or copies of) the 'eimg'
-- # (enhanced) images.
-- img_pre = 'rimg'
-- ext = '.png'
-- vidname = os.path.join(work_dir, out_mpg)
-- # do_encode() acts on images prefixed by img_pre.
-- do_encode()
-- if not keep:
-- do_clean()
-- if temp_dir != '':
-- shutil.rmtree(temp_dir)
-- if not quiet: print "Done!"
--
--
--"""
--CHANGELOG:
--
--21 Jul 2004 : 0.0.2 : fixed frame range error in img2yuv argument.
-- added support for ".wav" files.
-- added '-C' flag.
--28 Jul 2004 : 0.0.3 : added '-D' flag.
-- fixed typos.
-- eliminated some subshell calls.
-- convert dirs to absolute paths.
-- fixed work_dir permissions.
--30 Jul 2004 : 0.0.4 : added '-L' flag.
-- encoder is now feature-complete.
--25 Sep 2004 : 0.0.5 : make sure "rawsndf" is set correctly.
-- check if files exist before removing.
--02 Oct 2004 : 0.0.6 : multiplex even if no audio.
--28 Oct 2004 : 0.0.7 : added support for PAL (untested!).
-- fps fix in "common_options".
--08 Nov 2004 : 0.0.8 : make sure that the enhanced
-- color depth is 8-bits/channel.
--05 Dec 2004 : 0.0.9 : tweak encoding parameters.
-- mention raw audio settings in help.
--02 Jan 2005 : 0.1.0 : updated docs.
-- added sound rate (-b) option.
--05 Jan 2005 : 0.1.1 : bypass an fps/aspect ratio jpeg2yuv bug.
-- letterbox if 2.21:1.
--29 Jan 2005 : 0.1.2 : fix fps 0.1.1 regression.
--21 Mar 2005 : 0.1.3 : use env python (hopefully >= 2.3)
--26 Mar 2005 : 0.1.4 : added "qlo" setting.
--27 Jun 2005 : 0.1.5 : added "sdvd" and "spdvd" settings.
--26 Aug 2005 : 0.1.6 : Bypass 2.21:1 brokenness.
--09 Mar 2006 : 0.1.7 : added '-depth 8' to resize, as ImageMagick
-- keeps changing its damn behaviour.
--28 Jun 2007 : 0.1.8 : handles paths with spaces appropriately
-- (thanks Gabriel).
--"""
---- /dev/null
-+++ lives/lives-plugins/marcos-encoders/ogm_encoder
-@@ -0,0 +1,816 @@
-+#!/usr/bin/env python
-+
-+"""
-+ogm_encoder.py
-+
-+Front-end to various programs needed to create OGM movies
-+with some image-enhancing capabilities through the use of
-+ImageMagick. Meant as a companion to LiVES (to possibly call
-+from within a plugin, see http://www.xs4all.nl/~salsaman/lives/ )
-+but can also be used as a stand-alone program.
-+
-+Requires MPlayer, ImageMagick (GraphicsMagick might also
-+work), sox, Oggenc, OGMtools and Python 2.3.0 or greater.
-+
-+Copyright (C) 2004-2005 Marco De la Cruz (marco at reimeika.ca)
-+It's a trivial program, but might as well GPL it, so see:
-+http://www.gnu.org/copyleft/gpl.html for license.
-+
-+See my vids at http://amv.reimeika.ca !
-+"""
-+
-+version = '0.1.5'
-+convert = 'convert'
-+mencoder = 'mencoder'
-+oggenc = 'oggenc'
-+sox = 'sox'
-+ogmplex = 'ogmmerge'
-+
-+usage = \
-+ """
-+ogm_encoder.py -h
-+ogm_encoder.py -V
-+ogm_encoder.py -C
-+ogm_encoder.py [-o out] [-p pre] [-d dir] [-a aspect] [-D delay]
-+ [-q|-v] [-t type] [-k] [-e [[-w dir] [-c geom] [-r geom]]]
-+ [-s sndfile] [-b sndrate] [-f fpscode] [-L lv1file]
-+ [firstframe lastframe]
-+ """
-+
-+help = \
-+ """
-+SUMMARY (ver. %s):
-+
-+Encodes a series of PNG or JPG images into an MPEG-4/Ogg Vorbis
-+(OGM) stream and is also capable of performing some simple image
-+enhacements using ImageMagick. The images and audio are assumed to
-+be in an uncompressed LiVES format, hence making this encoder
-+more suitable to be used within a LiVES plugin (but can also
-+be used directly on a LiVES temporary directory).
-+
-+OPTIONS:
-+
-+-h for help.
-+
-+-V shows the version number.
-+
-+-C check external program dependencies and exit.
-+
-+-o out will save the video in file "out".
-+ Default: "'type'_movie.ogm". See below for 'type'.
-+
-+-p pre the encoder assumes that sound and images are named using
-+ LiVES' conventions i.e. "audio" and "00000001.ext",
-+ "00000002.ext"... where "ext" is either "jpg" or "png".
-+ However, ogm_encoder.py will create temporary files
-+ which can be saved for later use (for example, after
-+ enhancing the images with "-e" , which may take a long
-+ time). These temporary files will be named
-+ "pre_00000001.ext", etc... where "pre" is either "eimg"
-+ or "rimg" and will be kept if the "-k" option is used.
-+ ogm_encoder.py can then be run over the enhanced images
-+ only by selecting the appropriate prefix ("eimg" or
-+ "rimg") here. See "-e" to see what each prefix means.
-+ Default: "" (an empty string).
-+
-+-d dir "dir" is the directory containing the source image
-+ files. These must be of the form "00000001.ext" or
-+ "pre_00000001.ext" as explained above.
-+ Default: "."
-+
-+-a aspect sets the aspect ratio of the resulting MPEG-4. This can be:
-+
-+ 1 1:1 display
-+ 2 4:3 display
-+ 3 16:9 display
-+ 4 2.21:1 display
-+
-+ Default: "2"
-+
-+-D delay linearly delay the audio stream by "delay" ms.
-+ Default: "0"
-+
-+-q quiet operation, only complains on error.
-+
-+-v be verbose.
-+
-+-t type type of video created. The options here are:
-+
-+ "hi": a very high quality DivX 4/5 file, suitable
-+ for archiving images of 720x480.
-+
-+ "mh": medium-high quality DivX 4/5, which still allows
-+ to watch small videos (352x240 and below)
-+ fullscreen.
-+
-+ "ml": medium-low quality DivX 4/5, suitable for
-+ most videos but in particular small videos
-+ (352x240 and below) meant for online
-+ distribution.
-+
-+ "lo": a low quality DivX 4/5 format. Enlarging
-+ small videos will result in noticeable
-+ artifacts. Good for distributing over slow
-+ connections.
-+
-+ "hi_d", "mh_d", "ml_d", "lo_d": same as above.
-+
-+ "hi_x", "mh_x", "ml_x", "lo_x": same as above, but
-+ using XviD encoding.
-+
-+ Default: "ml"
-+
-+-e perform some simple filtering/enhancement to improve image
-+ quality. The images created by using this option will be
-+ stored in the directory specified by the "-w" option (or
-+ "-d" if not present, see above) and each filename will be
-+ prefixed with "eimg" (see "-p" above). Using this option will
-+ take enormous amounts of disk space, and in reality does
-+ not do anything that cannot be done within LiVES itself.
-+ Using this option enables the following four:
-+
-+ -w dir "dir" is the working directory where the enhanced
-+ images will be saved. Although these can all
-+ co-exist with the original LiVES files it is
-+ recommended you use a different directory. Note
-+ that temporary files may take a huge amount of
-+ space, perhaps twice as much as the LiVES files
-+ themselves. If this directory does not exist is
-+ will be created.
-+ Default: same as "-d".
-+
-+ -k keep the temporary files, useful to experiment
-+ with different encoding types without having
-+ to repeatedly enhance the images (which can be
-+ very time-consuming). See "-p" above.
-+
-+ -c geom in addition to enhancing the images, crop them
-+ to the specified geometry e.g. "688x448+17+11".
-+ Filename prefix remains "eimg". Note that the
-+ dimensions of the images should both be multiples
-+ of "16", otherwise some players may show artifacts
-+ (such as garbage or green bars at the borders).
-+
-+ -r geom this will create a second set of images resulting
-+ from resizing the images that have already been
-+ enhanced and possibly cropped (if "-c" has been
-+ specified). The geometry here is simple a new
-+ image size e.g. "352x240!". This second set will have
-+ filenames prefixed with the string "rimg" (see "-p"
-+ above). Note that the dimensions of the images
-+ should both be multiples of "16", otherwise some
-+ players may show artifacts (such as garbage or
-+ green bars at the borders).
-+
-+-s sndfile name of the audio file. Can be either raw "audio" or
-+ "[/path/to/]soundfile.wav".
-+ Default: "audio" inside "dir" as specified by "-d".
-+
-+-b sndrate sample rate of the sound file in Hertz.
-+ Default: "44100".
-+
-+-f fpscode frame-rate code. Acceptable values are:
-+
-+ 1 - 24000.0/1001.0 (NTSC 3:2 pulldown converted FILM)
-+ 2 - 24.0 (NATIVE FILM)
-+ 3 - 25.0 (PAL/SECAM VIDEO / converted FILM)
-+ 4 - 30000.0/1001.0 (NTSC VIDEO)
-+ 5 - 30.0
-+ 6 - 50.0 (PAL FIELD RATE)
-+ 7 - 60000.0/1001.0 (NTSC FIELD RATE)
-+ 8 - 60.0
-+
-+ If the input value is a float (e.g. 5.0, 14.555, etc.)
-+ the encoder will use that as frame rate.
-+
-+ Default: "4".
-+
-+-L lv1file use the images stored in the LiVES file "lv1file" (e.g.
-+ "movie.lv1"). Files will be extracted inside "dir" as
-+ specified by "-d". Using this option allows to encode
-+ a movie without having to restore it first with LiVES.
-+ Note that the encoder will not delete the extracted
-+ files after it has finished, this must be done manually
-+ afterwards. If frame code/rate (-f) and/or sound rate (-b)
-+ are not specified the defaults will be used (30000/1001 fps
-+ and 44100 Hz). These, however, may not be correct, in which
-+ case they should be specified explicitly. Furthermore, the
-+ .lv1 audio (if present) is always assumed to have a sample
-+ data size in 16-bit words with two channels, and to be signed
-+ linear (this is usually the case, however). If any of these
-+ latter parameters are incorrect the resulting file may be
-+ corrupted and encoding will have to be done using LiVES.
-+
-+firstframe first frame number. If less than eight digits long it will
-+ be padded with zeroes e.g. 234 -> 00000234. A prefix can
-+ be added using the "-p" option.
-+ Default: "00000001"
-+
-+lastframe last frame number, padded with zeroes if necessary, prefix
-+ set by "-p".
-+ Default: the last frame of its type in the "-d" directory,
-+ where "type" is set by the prefix.
-+
-+Note that either no frames or both first and last frames must be specified.
-+
-+EXAMPLES:
-+
-+Suppose you have restored a LiVES' .lv1 file (in either JPG or PNG format),
-+and that the images are stored in the directory "/tmp/livestmp/991319584/".
-+In this example the movie is assumed to be 16:9. Then, in order to create
-+an OGM file you can simply do the following:
-+
-+ ogm_encoder.py -d /tmp/livestmp/991319584 -o /movies/default.ogm -a 3
-+
-+and the clip "default.ogm" will be created in "/movies/" with the correct
-+aspect ratio.
-+
-+Suppose we want to make a downloadable version of the clip, small in size
-+but of good quality. The following command activates the generic enhancement
-+filter and resizes the images to "352x240". Note that these operations
-+are performed after cropping the originals a bit (using "704x464+5+6").
-+This is done because we are assuming that there is a black border around
-+the original pictures which we want to get rid of (this might distort the
-+images somewhat, so be careful about cropping/resizing, and remember to
-+use dimensions which are multiples of 16):
-+
-+ ogm_encoder.py -v -d /tmp/livestmp/991319584 -w /tmp/tmpogm \\
-+ -o /movies/download.ogm -a 3 -k -e -c "704x464+5+6" -r "352x240"
-+
-+Since we use the "-k" flag the enhanced images are kept (both full-size
-+crops and the resized ones) in "/tmp/tmpogm". Beware that this may consume
-+a lot of disk space (about 10x as much as the originals). The reason we
-+keep them is because the above may take quite a long time and we may want
-+to re-use the enhanced images. So, for example, creating a high-quality
-+clip at full size can be accomplished now as follows:
-+
-+ ogm_encoder.py -d /tmp/tmpogm -t hi -o /movies/archive.ogm \\
-+ -s /tmp/livestmp/991319584/audio -a 3 -k -p eimg
-+
-+If, for example, we only want to encode frames 100 to 150 we can run
-+the following:
-+
-+ ogm_encoder.py -v -d /tmp/tmpogm -o /movies/selection.ogm \\
-+ -a 3 -k -p eimg 100 150
-+
-+Note that no audio has been selected ("-s"). This is because
-+ogm_encoder.py cannot trim the audio to the appropriate length.
-+You would need to use LiVES to do this.
-+
-+To delete all the enhanced images you can just remove "/tmp/tmpogm".
-+
-+If you notice that the video and audio become out of sync so that
-+near the end of the movie the video trails the audio by, say, 0.2s,
-+you can use the "-D" option as follows:
-+
-+ ogm_encoder.py -d /tmp/livestmp/991319584 -o test.ogm -D 200
-+
-+Note that negative time values are also allowed.
-+
-+Suppose that you have "movie1.lv1", "movie2.lv1" and "movie3.lv1".
-+Batch-encoding can be done as follows (zsh-syntax):
-+
-+ for i in movie?.lv1
-+ do
-+ mkdir /tmp/$i:r
-+ ogm_encoder.py -d /tmp/$i:r -o /tmp/$i:r.ogm -L $i
-+ rm -rf /tmp/$i:r
-+ done
-+
-+This will generate the files "movie1.ogm", "movie2.ogm" and
-+"movie3.ogm" in "/tmp". Note that is is not necessary to
-+specify whether the files are stored in JPG or PNG format,
-+and that potentially time-consuming options (e.g. "-e") may
-+be enabled. It is not necessary to have a working LiVES
-+installation to encode .lv1 files.
-+ """ % version
-+
-+def run(command):
-+ """
-+ Run a shell command
-+ """
-+
-+ if verbose:
-+ print 'Running: \n' + command + '\n=== ... ==='
-+ std = ''
-+ else:
-+ std = ' > /dev/null 2>&1'
-+
-+ os.system(command + std)
-+
-+
-+def do_enhance():
-+ """
-+ Image cleanup/crop/resize routine. Generic, but seems to work
-+ well with anime :)
-+ """
-+
-+ if not quiet:
-+ print 'Enhancing images... please wait, this might take long...'
-+
-+ enh_opts = "-enhance -sharpen '0.0x0.5' -gamma 1.2 -contrast -depth 8"
-+
-+ if cgeom:
-+ docrop = ' '.join(['-crop', "'%s!'" % cgeom])
-+ else:
-+ docrop = ''
-+
-+ iframe = first_num
-+ while True:
-+ # File names are padded with zeroes to 8 characters
-+ # (not counting the .ext).
-+ frame = str(iframe).zfill(8)
-+ fname = os.path.join(img_dir, frame + ext)
-+ if not os.path.isfile(fname) or (iframe == last_num + 1):
-+ break
-+ eimg_fname = os.path.join(work_dir, 'eimg' + frame + '.png')
-+ rimg_fname = os.path.join(work_dir, 'rimg' + frame + '.png')
-+ command = ' '.join([convert, docrop, enh_opts, fname, eimg_fname])
-+ run(command)
-+ if rgeom:
-+ if os.path.exists(rimg_fname): os.remove(rimg_fname)
-+ shrink = ' '.join([convert, '-resize', "'%s!'" % rgeom, '-depth 8'])
-+ command = ' '.join([shrink, eimg_fname, rimg_fname])
-+ run(command)
-+ else:
-+ if os.path.exists(rimg_fname): os.remove(rimg_fname)
-+ try:
-+ os.symlink(eimg_fname, rimg_fname)
-+ except (IOError, OSError):
-+ shutil.copy(eimg_fname, rimg_fname)
-+ iframe+=1
-+
-+
-+def do_encode():
-+ """
-+ Encode a series of images into an MPEG-4 stream, multiplexing
-+ audio if necessary
-+ """
-+
-+ if not quiet:
-+ print 'Creating "%s"-quality MPEG-4' % vtype
-+
-+ if verbose:
-+ std = ''
-+ else:
-+ std = ' > /dev/null 2>&1'
-+
-+ common_vopts = '-mf type=%s:fps=%s ' % (ext[1:], fps) + \
-+ '-vf hqdn3d=2:1:3,pp=va:128:8/ha:128:8/dr,dsize=%s -nosound' % aspect
-+
-+ if vtype[-1] == 'd':
-+ codec_vopts = '-ovc lavc -lavcopts ' + \
-+ 'vcodec=mpeg4:trell:mbd=2:vmax_b_frames=1:v4mv' + \
-+ ':cmp=2:subcmp=2:precmp=2:predia=1:autoaspect:vbitrate='
-+ cpass = 'vpass='
-+ else:
-+ codec_vopts = '-ovc xvid -xvidencopts qpel:chroma_me:chroma_opt' + \
-+ ':max_bframes=1:autoaspect:hq_ac:vhq=4:bitrate='
-+ cpass = 'pass='
-+
-+ vqual = vtype[0:-2]
-+ if vqual == 'hi':
-+ if vtype[-1] == 'd': rate = '2000:'
-+ if vtype[-1] == 'x': rate = '2000:'
-+ mencoder_opts = ' '.join([common_vopts, codec_vopts + rate + cpass])
-+ oggenc_opts = '-q 9'
-+ elif vqual == 'mh':
-+ if vtype[-1] == 'd': rate = '1000:'
-+ if vtype[-1] == 'x': rate = '1000:'
-+ mencoder_opts = ' '.join([common_vopts, codec_vopts + rate + cpass])
-+ oggenc_opts = '-q 8'
-+ elif vqual == 'ml':
-+ if vtype[-1] == 'd': rate = '500:'
-+ if vtype[-1] == 'x': rate = '500:'
-+ mencoder_opts = ' '.join([common_vopts, codec_vopts + rate + cpass])
-+ oggenc_opts = '-q 6'
-+ elif vqual == 'lo':
-+ if vtype[-1] == 'd': rate = '200:'
-+ if vtype[-1] == 'x': rate = '200:'
-+ mencoder_opts = ' '.join([common_vopts, codec_vopts + rate + cpass])
-+ oggenc_opts = '-q 4'
-+
-+
-+ if img_dir != work_dir and not enhance:
-+ source_dir = img_dir
-+ else:
-+ source_dir = work_dir
-+ mpegv = tempfile.mkstemp('.mpv', '', work_dir)[1]
-+
-+ if frame_range:
-+ frame_list = [img_pre + str(f).zfill(8) + ext \
-+ for f in range(first_num, last_num + 1)]
-+ syml = 'temporary_symlink_'
-+ for iframe in frame_list:
-+ frfile = os.path.join(source_dir, iframe)
-+ frlink = os.path.join(source_dir, syml + iframe)
-+ if os.path.islink(frlink): os.remove(frlink)
-+ os.symlink(frfile, frlink)
-+ else:
-+ syml = ''
-+
-+ all_vars = {}
-+ all_vars.update(globals())
-+ all_vars.update(locals())
-+
-+ command = """cd %(source_dir)s ; \\
-+%(mencoder)s "mf://%(syml)s%(img_pre)s*%(ext)s" %(mencoder_opts)s1 -o /dev/null %(std)s ; \\
-+%(mencoder)s "mf://%(syml)s%(img_pre)s*%(ext)s" %(mencoder_opts)s2 -o %(mpegv)s %(std)s
-+""" % all_vars
-+ run(command)
-+ if os.path.exists(os.path.join(source_dir, 'divx2pass.log')):
-+ os.remove(os.path.join(source_dir, 'divx2pass.log'))
-+ if os.path.exists(os.path.join(source_dir, 'xvid-twopass.stats')):
-+ os.remove(os.path.join(source_dir, 'xvid-twopass.stats'))
-+
-+ if audio:
-+ if not quiet:
-+ print 'Creating "%s"-quality ogg vorbis file' % vtype
-+
-+ ogg = tempfile.mkstemp('.ogg', '', work_dir)[1]
-+ if rawsndf:
-+ wav = tempfile.mkstemp('.wav', '', work_dir)[1]
-+ sox_opts = '-t raw -r %s -w -c 2 -s' % sndr
-+ command = ' '.join([sox, sox_opts, sndf, wav])
-+ run(command)
-+ else:
-+ wav = sndf
-+ command = ' '.join([oggenc, oggenc_opts, wav, '-o', ogg, std])
-+ run(command)
-+
-+ if delay != '0':
-+ totfr = len(glob.glob(os.path.join(source_dir, syml + img_pre + '*' + ext)))
-+ # "delay" is in ms, transform into s
-+ totfrshift = int(totfr + round((locale.atof(delay)/1000.0)*locale.atof(fps)))
-+ delaysh = ',%s/%s' % (totfrshift, totfr)
-+ else:
-+ delaysh = ''
-+
-+ all_vars.update(locals())
-+
-+ if not quiet: print 'Multiplexing...'
-+ command = """
-+%(ogmplex)s -o "%(vidname)s" %(mpegv)s -s 0%(delaysh)s %(ogg)s %(std)s""" % all_vars
-+ run(command)
-+
-+ if rawsndf and os.path.exists(wav): os.remove(wav)
-+ if os.path.exists(ogg): os.remove(ogg)
-+ else:
-+ if not quiet: print 'Multiplexing...'
-+ command = """
-+%(ogmplex)s -o "%(vidname)s" %(mpegv)s %(std)s""" % all_vars
-+ run(command)
-+
-+ if os.path.exists(mpegv): os.remove(mpegv)
-+
-+ if frame_range:
-+ lframes = os.path.join(source_dir, syml)
-+ for frame in glob.glob(lframes + '*'):
-+ os.remove(frame)
-+
-+
-+def do_clean():
-+ """
-+ Delete enhanced files
-+ """
-+
-+ if not quiet:
-+ print 'Deleting all enhanced images (if any)'
-+
-+ eframes = os.path.join(work_dir, 'eimg')
-+ rframes = os.path.join(work_dir, 'rimg')
-+ for frame in glob.glob(eframes + '*'):
-+ os.remove(frame)
-+ for frame in glob.glob(rframes + '*'):
-+ os.remove(frame)
-+
-+
-+def which(command):
-+ """
-+ Finds (or not) a command a la "which"
-+ """
-+
-+ command_found = False
-+
-+ if command[0] == '/':
-+ if os.path.isfile(command) and \
-+ os.access(command, os.X_OK):
-+ command_found = True
-+ abs_command = command
-+ else:
-+ path = os.environ.get('PATH', '').split(os.pathsep)
-+ for dir in path:
-+ abs_command = os.path.join(dir, command)
-+ if os.path.isfile(abs_command) and \
-+ os.access(abs_command, os.X_OK):
-+ command_found = True
-+ break
-+
-+ if not command_found:
-+ abs_command = ''
-+
-+ return abs_command
-+
-+
-+def is_installed(prog):
-+ """
-+ See whether "prog" is installed
-+ """
-+
-+ wprog = which(prog)
-+
-+ if wprog == '':
-+ print prog + ': command not found'
-+ raise SystemExit
-+ else:
-+ if verbose:
-+ print wprog + ': found'
-+
-+
-+if __name__ == '__main__':
-+
-+ import os
-+ import sys
-+ import getopt
-+ import shutil
-+ import tempfile
-+ import glob
-+ import tarfile
-+
-+ try:
-+ if sys.version_info[0:3] < (2, 3, 0):
-+ raise SystemExit
-+ except:
-+ print 'You need Python 2.3.0 or greater to run me!'
-+ raise SystemExit
-+
-+ try:
-+ (opts, args) = getopt.getopt(sys.argv[1:], \
-+ 'ho:p:d:w:a:qvt:ekc:r:s:b:f:VCD:L:')
-+ except:
-+ print "Something's wrong. Try the '-h' flag."
-+ raise SystemExit
-+
-+ opts = dict(opts)
-+
-+ if not opts and not args:
-+ print usage
-+ raise SystemExit
-+
-+ if '-h' in opts:
-+ print usage + help
-+ raise SystemExit
-+
-+ if '-V' in opts:
-+ print 'ogm_encoder.py version ' + version
-+ raise SystemExit
-+
-+ if ('-v' in opts) or ('-C' in opts):
-+ verbose = True
-+ else:
-+ verbose = False
-+
-+ if '-q' in opts:
-+ quiet = True
-+ verbose = False
-+ else:
-+ quiet = False
-+
-+ for i in [convert, mencoder, oggenc, sox, ogmplex]:
-+ is_installed(i)
-+ if '-C' in opts: raise SystemExit
-+
-+ img_pre = opts.get('-p', '')
-+
-+ if img_pre not in ['', 'eimg', 'rimg']:
-+ print 'Improper image name prefix.'
-+ raise SystemExit
-+
-+ temp_dir = ''
-+ img_dir = opts.get('-d', '.')
-+ img_dir = os.path.abspath(img_dir)
-+ if ' ' in img_dir:
-+ temp_dir = tempfile.mkdtemp('', '.lives-', '/tmp/')
-+ os.symlink(img_dir, temp_dir + '/img_dir')
-+ img_dir = temp_dir + '/img_dir'
-+
-+ if not os.path.isdir(img_dir):
-+ print 'The image source directory: ' + img_dir + \
-+ ' does not exist!'
-+ raise SystemExit
-+
-+ if len(args) not in [0, 2]:
-+ print 'If frames are specified both first and last ' + \
-+ 'image numbers must be chosen.'
-+ raise SystemExit
-+ elif len(args) == 0:
-+ args = [None, None]
-+
-+ frame_range = False
-+ if not args[0]:
-+ first_frame_num = '1'
-+ else:
-+ frame_range = True
-+ first_frame_num = args[0]
-+ first_frame_num = first_frame_num.zfill(8)
-+ first_num = int(first_frame_num)
-+
-+ if not args[1]:
-+ last_frame_num = '99999999'
-+ else:
-+ last_frame_num = args[1]
-+ last_frame_num = last_frame_num.zfill(8)
-+ last_num = int(last_frame_num)
-+
-+ aspectc = opts.get('-a', '2')
-+
-+ if aspectc not in [str(i) for i in xrange(1,5)]:
-+ print 'Invalid aspect ratio.'
-+ raise SystemExit
-+ else:
-+ if aspectc == '1': aspect = '1/1'
-+ elif aspectc == '2': aspect = '4/3'
-+ elif aspectc == '3': aspect = '16/9'
-+ elif aspectc == '4': aspect = '221/100'
-+
-+ vtype = opts.get('-t', 'ml')
-+
-+ out_ogm = opts.get('-o', vtype + '_movie.ogm')
-+
-+ if '_' not in vtype:
-+ vtype = vtype + '_d'
-+
-+ if vtype not in ['hi_d', 'mh_d', 'ml_d', 'lo_d', \
-+ 'hi_x', 'mh_x', 'ml_x', 'lo_x']:
-+ print 'Invalid video type.'
-+ raise SystemExit
-+
-+ fpsc = opts.get('-f', '4')
-+
-+ if fpsc not in [str(i) for i in xrange(1,9)]:
-+ if not quiet: print 'Invalid fps code, attempting float fps.'
-+ foundfps = False
-+ else:
-+ if fpsc == '1': fps = str(24000.0/1001.0)
-+ elif fpsc == '2': fps = str(24.0)
-+ elif fpsc == '3': fps = str(25.0)
-+ elif fpsc == '4': fps = str(30000.0/1001.0)
-+ elif fpsc == '5': fps = str(30.0)
-+ elif fpsc == '6': fps = str(50.0)
-+ elif fpsc == '7': fps = str(60000.0/1001.0)
-+ elif fpsc == '8': fps = str(60.0)
-+ foundfps = True
-+
-+ if not foundfps:
-+ try:
-+ fps = locale.atof(fpsc)
-+ if not quiet: print 'Using fps = %s' % fps
-+ if fps > 0: foundfps = True
-+ except:
-+ pass
-+
-+ if not foundfps:
-+ print 'Invalid fps code or rate.'
-+ raise SystemExit
-+
-+ if '-e' not in opts:
-+ enhance = False
-+ else:
-+ enhance = True
-+
-+ if enhance and img_pre:
-+ print 'Sorry, you cannot enhance already-enhanced images'
-+ raise SystemExit
-+
-+ if '-k' not in opts:
-+ keep = False
-+ else:
-+ keep = True
-+
-+ cgeom = opts.get('-c', '')
-+ rgeom = opts.get('-r', '')
-+
-+ if (cgeom or rgeom) and not enhance:
-+ print 'Missing "-e" option.'
-+ raise SystemExit
-+
-+ lv1file = opts.get('-L', None)
-+ if lv1file:
-+ if not quiet: print 'Opening lv1 file...'
-+ try:
-+ lv1 = tarfile.open(os.path.abspath(lv1file))
-+ except:
-+ print 'This does not appear to be a valid LiVES file!'
-+ raise SystemExit
-+ if 'header.tar' not in lv1.getnames():
-+ print 'This does not appear to be a valid LiVES file!'
-+ raise SystemExit
-+ for tfile in lv1.getmembers():
-+ lv1.extract(tfile, img_dir)
-+ for tfile in glob.glob(os.path.join(img_dir, '*.tar')):
-+ imgtar = tarfile.open(tfile)
-+ for img in imgtar.getmembers():
-+ imgtar.extract(img, img_dir)
-+ os.remove(tfile)
-+
-+ test_file = os.path.join(img_dir, img_pre + first_frame_num)
-+ if os.path.isfile(test_file + '.jpg'):
-+ ext = '.jpg'
-+ elif os.path.isfile(test_file + '.png'):
-+ ext = '.png'
-+ else:
-+ print 'Cannot find any appropriate %s or %s files!' % ('.jpg','.png')
-+ raise SystemExit
-+ first_frame = test_file + ext
-+ last_frame = os.path.join(img_dir, img_pre + last_frame_num + ext)
-+
-+ if not quiet: print 'Found: ' + first_frame
-+
-+ work_dir = opts.get('-w', img_dir)
-+ work_dir = os.path.abspath(work_dir)
-+ if not os.path.isdir(work_dir):
-+ if not quiet: print 'Creating ' + work_dir
-+ try:
-+ os.makedirs(work_dir)
-+ os.chmod(work_dir, 0755)
-+ except:
-+ print 'Could not create the work directory ' + \
-+ work_dir
-+ raise SystemExit
-+ if ' ' in work_dir:
-+ if temp_dir == '':
-+ temp_dir = tempfile.mkdtemp('', '.lives-', '/tmp/')
-+ os.symlink(work_dir, temp_dir + '/work_dir')
-+ work_dir = temp_dir + '/work_dir'
-+
-+ sndf = opts.get('-s', os.path.join(img_dir, 'audio'))
-+# sndf = os.path.abspath(sndf)
-+ rawsndf = True
-+ if not os.path.isfile(sndf):
-+ audio = False
-+ rawsndf = False
-+ else:
-+ audio = True
-+ if sndf[-4:] == '.wav':
-+ rawsndf = False
-+ if not quiet: print 'Found audio file: ' + sndf
-+
-+ sndr = opts.get('-b', '44100')
-+
-+ delay = opts.get('-D', '0')
-+ if verbose and audio: print 'Linear audio delay (ms): ' + delay
-+
-+ if enhance:
-+ do_enhance()
-+ # Note that do_enhance() always creates images prefixed
-+ # with 'rimg'. What's important to note if that if the
-+ # images are resized the 'rimg' are indeed resized, but
-+ # if not the 'rimg' are simply symlinks to (or copies of) the 'eimg'
-+ # (enhanced) images.
-+ img_pre = 'rimg'
-+ ext = '.png'
-+ vidname = os.path.join(work_dir, out_ogm)
-+ # do_encode() acts on images prefixed by img_pre.
-+ do_encode()
-+ if not keep:
-+ do_clean()
-+ if temp_dir != '':
-+ shutil.rmtree(temp_dir)
-+ if not quiet: print "Done!"
-+
-+
-+"""
-+CHANGELOG:
-+
-+21 Jul 2004 : 0.0.2 : added support for ".wav" files.
-+ added '-C' flag.
-+28 Jul 2004 : 0.0.3 : added '-D' flag.
-+ fixed typos.
-+ eliminated some subshell calls.
-+ convert dirs to absolute paths.
-+ fixed frame range detection.
-+ fixed work_dir permissions.
-+30 Jul 2004 : 0.0.4 : added '-L' flag.
-+ encoder is now feature-complete.
-+25 Sep 2004 : 0.0.5 : make sure "rawsndf" is set correctly.
-+ check if files exist before removing.
-+02 Oct 2004 : 0.0.6 : multiplex even if no audio.
-+28 Oct 2004 : 0.0.7 : can handle arbitrary fps values.
-+02 Nov 2004 : 0.0.8 : added XviD encoding.
-+08 Nov 2004 : 0.0.9 : make sure that the enhanced
-+ color depth is 8-bits/channel.
-+ fixed XviD aspect ratio.
-+ added chroma_opt to XviD.
-+02 Jan 2005 : 0.1.0 : updated docs.
-+ added sound rate (-b) option.
-+26 Mar 2005 : 0.1.1 : use env python (hopefully >= 2.3).
-+ replace denoise3d with hqdn3d.
-+24 Aug 2005 : 0.1.2 : Fixed 2.21:1 aspect ratio.
-+ fine-tune mplayer filters.
-+09 Mar 2006 : 0.1.3 : added '-depth 8' to resize, as ImageMagick
-+ keeps changing its damn behaviour.
-+ Fixed bitrate levels.
-+13 Mar 2006 : 0.1.4 : tweaked bitrate levels.
-+28 Jun 2007 : 0.1.5 : handles paths with spaces appropriately
-+ (thanks Gabriel).
-+"""
---- lives.orig/lives-plugins/marcos-encoders/ogm_encoder.py
-+++ /dev/null
-@@ -1,816 +0,0 @@
--#!/usr/bin/env python
--
--"""
--ogm_encoder.py
--
--Front-end to various programs needed to create OGM movies
--with some image-enhancing capabilities through the use of
--ImageMagick. Meant as a companion to LiVES (to possibly call
--from within a plugin, see http://www.xs4all.nl/~salsaman/lives/ )
--but can also be used as a stand-alone program.
--
--Requires MPlayer, ImageMagick (GraphicsMagick might also
--work), sox, Oggenc, OGMtools and Python 2.3.0 or greater.
--
--Copyright (C) 2004-2005 Marco De la Cruz (marco at reimeika.ca)
--It's a trivial program, but might as well GPL it, so see:
--http://www.gnu.org/copyleft/gpl.html for license.
--
--See my vids at http://amv.reimeika.ca !
--"""
--
--version = '0.1.5'
--convert = 'convert'
--mencoder = 'mencoder'
--oggenc = 'oggenc'
--sox = 'sox'
--ogmplex = 'ogmmerge'
--
--usage = \
-- """
--ogm_encoder.py -h
--ogm_encoder.py -V
--ogm_encoder.py -C
--ogm_encoder.py [-o out] [-p pre] [-d dir] [-a aspect] [-D delay]
-- [-q|-v] [-t type] [-k] [-e [[-w dir] [-c geom] [-r geom]]]
-- [-s sndfile] [-b sndrate] [-f fpscode] [-L lv1file]
-- [firstframe lastframe]
-- """
--
--help = \
-- """
--SUMMARY (ver. %s):
--
--Encodes a series of PNG or JPG images into an MPEG-4/Ogg Vorbis
--(OGM) stream and is also capable of performing some simple image
--enhacements using ImageMagick. The images and audio are assumed to
--be in an uncompressed LiVES format, hence making this encoder
--more suitable to be used within a LiVES plugin (but can also
--be used directly on a LiVES temporary directory).
--
--OPTIONS:
--
---h for help.
--
---V shows the version number.
--
---C check external program dependencies and exit.
--
---o out will save the video in file "out".
-- Default: "'type'_movie.ogm". See below for 'type'.
--
---p pre the encoder assumes that sound and images are named using
-- LiVES' conventions i.e. "audio" and "00000001.ext",
-- "00000002.ext"... where "ext" is either "jpg" or "png".
-- However, ogm_encoder.py will create temporary files
-- which can be saved for later use (for example, after
-- enhancing the images with "-e" , which may take a long
-- time). These temporary files will be named
-- "pre_00000001.ext", etc... where "pre" is either "eimg"
-- or "rimg" and will be kept if the "-k" option is used.
-- ogm_encoder.py can then be run over the enhanced images
-- only by selecting the appropriate prefix ("eimg" or
-- "rimg") here. See "-e" to see what each prefix means.
-- Default: "" (an empty string).
--
---d dir "dir" is the directory containing the source image
-- files. These must be of the form "00000001.ext" or
-- "pre_00000001.ext" as explained above.
-- Default: "."
--
---a aspect sets the aspect ratio of the resulting MPEG-4. This can be:
--
-- 1 1:1 display
-- 2 4:3 display
-- 3 16:9 display
-- 4 2.21:1 display
--
-- Default: "2"
--
---D delay linearly delay the audio stream by "delay" ms.
-- Default: "0"
--
---q quiet operation, only complains on error.
--
---v be verbose.
--
---t type type of video created. The options here are:
--
-- "hi": a very high quality DivX 4/5 file, suitable
-- for archiving images of 720x480.
--
-- "mh": medium-high quality DivX 4/5, which still allows
-- to watch small videos (352x240 and below)
-- fullscreen.
--
-- "ml": medium-low quality DivX 4/5, suitable for
-- most videos but in particular small videos
-- (352x240 and below) meant for online
-- distribution.
--
-- "lo": a low quality DivX 4/5 format. Enlarging
-- small videos will result in noticeable
-- artifacts. Good for distributing over slow
-- connections.
--
-- "hi_d", "mh_d", "ml_d", "lo_d": same as above.
--
-- "hi_x", "mh_x", "ml_x", "lo_x": same as above, but
-- using XviD encoding.
--
-- Default: "ml"
--
---e perform some simple filtering/enhancement to improve image
-- quality. The images created by using this option will be
-- stored in the directory specified by the "-w" option (or
-- "-d" if not present, see above) and each filename will be
-- prefixed with "eimg" (see "-p" above). Using this option will
-- take enormous amounts of disk space, and in reality does
-- not do anything that cannot be done within LiVES itself.
-- Using this option enables the following four:
--
-- -w dir "dir" is the working directory where the enhanced
-- images will be saved. Although these can all
-- co-exist with the original LiVES files it is
-- recommended you use a different directory. Note
-- that temporary files may take a huge amount of
-- space, perhaps twice as much as the LiVES files
-- themselves. If this directory does not exist is
-- will be created.
-- Default: same as "-d".
--
-- -k keep the temporary files, useful to experiment
-- with different encoding types without having
-- to repeatedly enhance the images (which can be
-- very time-consuming). See "-p" above.
--
-- -c geom in addition to enhancing the images, crop them
-- to the specified geometry e.g. "688x448+17+11".
-- Filename prefix remains "eimg". Note that the
-- dimensions of the images should both be multiples
-- of "16", otherwise some players may show artifacts
-- (such as garbage or green bars at the borders).
--
-- -r geom this will create a second set of images resulting
-- from resizing the images that have already been
-- enhanced and possibly cropped (if "-c" has been
-- specified). The geometry here is simple a new
-- image size e.g. "352x240!". This second set will have
-- filenames prefixed with the string "rimg" (see "-p"
-- above). Note that the dimensions of the images
-- should both be multiples of "16", otherwise some
-- players may show artifacts (such as garbage or
-- green bars at the borders).
--
---s sndfile name of the audio file. Can be either raw "audio" or
-- "[/path/to/]soundfile.wav".
-- Default: "audio" inside "dir" as specified by "-d".
--
---b sndrate sample rate of the sound file in Hertz.
-- Default: "44100".
--
---f fpscode frame-rate code. Acceptable values are:
--
-- 1 - 24000.0/1001.0 (NTSC 3:2 pulldown converted FILM)
-- 2 - 24.0 (NATIVE FILM)
-- 3 - 25.0 (PAL/SECAM VIDEO / converted FILM)
-- 4 - 30000.0/1001.0 (NTSC VIDEO)
-- 5 - 30.0
-- 6 - 50.0 (PAL FIELD RATE)
-- 7 - 60000.0/1001.0 (NTSC FIELD RATE)
-- 8 - 60.0
--
-- If the input value is a float (e.g. 5.0, 14.555, etc.)
-- the encoder will use that as frame rate.
--
-- Default: "4".
--
---L lv1file use the images stored in the LiVES file "lv1file" (e.g.
-- "movie.lv1"). Files will be extracted inside "dir" as
-- specified by "-d". Using this option allows to encode
-- a movie without having to restore it first with LiVES.
-- Note that the encoder will not delete the extracted
-- files after it has finished, this must be done manually
-- afterwards. If frame code/rate (-f) and/or sound rate (-b)
-- are not specified the defaults will be used (30000/1001 fps
-- and 44100 Hz). These, however, may not be correct, in which
-- case they should be specified explicitly. Furthermore, the
-- .lv1 audio (if present) is always assumed to have a sample
-- data size in 16-bit words with two channels, and to be signed
-- linear (this is usually the case, however). If any of these
-- latter parameters are incorrect the resulting file may be
-- corrupted and encoding will have to be done using LiVES.
--
--firstframe first frame number. If less than eight digits long it will
-- be padded with zeroes e.g. 234 -> 00000234. A prefix can
-- be added using the "-p" option.
-- Default: "00000001"
--
--lastframe last frame number, padded with zeroes if necessary, prefix
-- set by "-p".
-- Default: the last frame of its type in the "-d" directory,
-- where "type" is set by the prefix.
--
--Note that either no frames or both first and last frames must be specified.
--
--EXAMPLES:
--
--Suppose you have restored a LiVES' .lv1 file (in either JPG or PNG format),
--and that the images are stored in the directory "/tmp/livestmp/991319584/".
--In this example the movie is assumed to be 16:9. Then, in order to create
--an OGM file you can simply do the following:
--
-- ogm_encoder.py -d /tmp/livestmp/991319584 -o /movies/default.ogm -a 3
--
--and the clip "default.ogm" will be created in "/movies/" with the correct
--aspect ratio.
--
--Suppose we want to make a downloadable version of the clip, small in size
--but of good quality. The following command activates the generic enhancement
--filter and resizes the images to "352x240". Note that these operations
--are performed after cropping the originals a bit (using "704x464+5+6").
--This is done because we are assuming that there is a black border around
--the original pictures which we want to get rid of (this might distort the
--images somewhat, so be careful about cropping/resizing, and remember to
--use dimensions which are multiples of 16):
--
-- ogm_encoder.py -v -d /tmp/livestmp/991319584 -w /tmp/tmpogm \\
-- -o /movies/download.ogm -a 3 -k -e -c "704x464+5+6" -r "352x240"
--
--Since we use the "-k" flag the enhanced images are kept (both full-size
--crops and the resized ones) in "/tmp/tmpogm". Beware that this may consume
--a lot of disk space (about 10x as much as the originals). The reason we
--keep them is because the above may take quite a long time and we may want
--to re-use the enhanced images. So, for example, creating a high-quality
--clip at full size can be accomplished now as follows:
--
-- ogm_encoder.py -d /tmp/tmpogm -t hi -o /movies/archive.ogm \\
-- -s /tmp/livestmp/991319584/audio -a 3 -k -p eimg
--
--If, for example, we only want to encode frames 100 to 150 we can run
--the following:
--
-- ogm_encoder.py -v -d /tmp/tmpogm -o /movies/selection.ogm \\
-- -a 3 -k -p eimg 100 150
--
--Note that no audio has been selected ("-s"). This is because
--ogm_encoder.py cannot trim the audio to the appropriate length.
--You would need to use LiVES to do this.
--
--To delete all the enhanced images you can just remove "/tmp/tmpogm".
--
--If you notice that the video and audio become out of sync so that
--near the end of the movie the video trails the audio by, say, 0.2s,
--you can use the "-D" option as follows:
--
-- ogm_encoder.py -d /tmp/livestmp/991319584 -o test.ogm -D 200
--
--Note that negative time values are also allowed.
--
--Suppose that you have "movie1.lv1", "movie2.lv1" and "movie3.lv1".
--Batch-encoding can be done as follows (zsh-syntax):
--
-- for i in movie?.lv1
-- do
-- mkdir /tmp/$i:r
-- ogm_encoder.py -d /tmp/$i:r -o /tmp/$i:r.ogm -L $i
-- rm -rf /tmp/$i:r
-- done
--
--This will generate the files "movie1.ogm", "movie2.ogm" and
--"movie3.ogm" in "/tmp". Note that is is not necessary to
--specify whether the files are stored in JPG or PNG format,
--and that potentially time-consuming options (e.g. "-e") may
--be enabled. It is not necessary to have a working LiVES
--installation to encode .lv1 files.
-- """ % version
--
--def run(command):
-- """
-- Run a shell command
-- """
--
-- if verbose:
-- print 'Running: \n' + command + '\n=== ... ==='
-- std = ''
-- else:
-- std = ' > /dev/null 2>&1'
--
-- os.system(command + std)
--
--
--def do_enhance():
-- """
-- Image cleanup/crop/resize routine. Generic, but seems to work
-- well with anime :)
-- """
--
-- if not quiet:
-- print 'Enhancing images... please wait, this might take long...'
--
-- enh_opts = "-enhance -sharpen '0.0x0.5' -gamma 1.2 -contrast -depth 8"
--
-- if cgeom:
-- docrop = ' '.join(['-crop', "'%s!'" % cgeom])
-- else:
-- docrop = ''
--
-- iframe = first_num
-- while True:
-- # File names are padded with zeroes to 8 characters
-- # (not counting the .ext).
-- frame = str(iframe).zfill(8)
-- fname = os.path.join(img_dir, frame + ext)
-- if not os.path.isfile(fname) or (iframe == last_num + 1):
-- break
-- eimg_fname = os.path.join(work_dir, 'eimg' + frame + '.png')
-- rimg_fname = os.path.join(work_dir, 'rimg' + frame + '.png')
-- command = ' '.join([convert, docrop, enh_opts, fname, eimg_fname])
-- run(command)
-- if rgeom:
-- if os.path.exists(rimg_fname): os.remove(rimg_fname)
-- shrink = ' '.join([convert, '-resize', "'%s!'" % rgeom, '-depth 8'])
-- command = ' '.join([shrink, eimg_fname, rimg_fname])
-- run(command)
-- else:
-- if os.path.exists(rimg_fname): os.remove(rimg_fname)
-- try:
-- os.symlink(eimg_fname, rimg_fname)
-- except (IOError, OSError):
-- shutil.copy(eimg_fname, rimg_fname)
-- iframe+=1
--
--
--def do_encode():
-- """
-- Encode a series of images into an MPEG-4 stream, multiplexing
-- audio if necessary
-- """
--
-- if not quiet:
-- print 'Creating "%s"-quality MPEG-4' % vtype
--
-- if verbose:
-- std = ''
-- else:
-- std = ' > /dev/null 2>&1'
--
-- common_vopts = '-mf type=%s:fps=%s ' % (ext[1:], fps) + \
-- '-vf hqdn3d=2:1:3,pp=va:128:8/ha:128:8/dr,dsize=%s -nosound' % aspect
--
-- if vtype[-1] == 'd':
-- codec_vopts = '-ovc lavc -lavcopts ' + \
-- 'vcodec=mpeg4:trell:mbd=2:vmax_b_frames=1:v4mv' + \
-- ':cmp=2:subcmp=2:precmp=2:predia=1:autoaspect:vbitrate='
-- cpass = 'vpass='
-- else:
-- codec_vopts = '-ovc xvid -xvidencopts qpel:chroma_me:chroma_opt' + \
-- ':max_bframes=1:autoaspect:hq_ac:vhq=4:bitrate='
-- cpass = 'pass='
--
-- vqual = vtype[0:-2]
-- if vqual == 'hi':
-- if vtype[-1] == 'd': rate = '2000:'
-- if vtype[-1] == 'x': rate = '2000:'
-- mencoder_opts = ' '.join([common_vopts, codec_vopts + rate + cpass])
-- oggenc_opts = '-q 9'
-- elif vqual == 'mh':
-- if vtype[-1] == 'd': rate = '1000:'
-- if vtype[-1] == 'x': rate = '1000:'
-- mencoder_opts = ' '.join([common_vopts, codec_vopts + rate + cpass])
-- oggenc_opts = '-q 8'
-- elif vqual == 'ml':
-- if vtype[-1] == 'd': rate = '500:'
-- if vtype[-1] == 'x': rate = '500:'
-- mencoder_opts = ' '.join([common_vopts, codec_vopts + rate + cpass])
-- oggenc_opts = '-q 6'
-- elif vqual == 'lo':
-- if vtype[-1] == 'd': rate = '200:'
-- if vtype[-1] == 'x': rate = '200:'
-- mencoder_opts = ' '.join([common_vopts, codec_vopts + rate + cpass])
-- oggenc_opts = '-q 4'
--
--
-- if img_dir != work_dir and not enhance:
-- source_dir = img_dir
-- else:
-- source_dir = work_dir
-- mpegv = tempfile.mkstemp('.mpv', '', work_dir)[1]
--
-- if frame_range:
-- frame_list = [img_pre + str(f).zfill(8) + ext \
-- for f in range(first_num, last_num + 1)]
-- syml = 'temporary_symlink_'
-- for iframe in frame_list:
-- frfile = os.path.join(source_dir, iframe)
-- frlink = os.path.join(source_dir, syml + iframe)
-- if os.path.islink(frlink): os.remove(frlink)
-- os.symlink(frfile, frlink)
-- else:
-- syml = ''
--
-- all_vars = {}
-- all_vars.update(globals())
-- all_vars.update(locals())
--
-- command = """cd %(source_dir)s ; \\
--%(mencoder)s "mf://%(syml)s%(img_pre)s*%(ext)s" %(mencoder_opts)s1 -o /dev/null %(std)s ; \\
--%(mencoder)s "mf://%(syml)s%(img_pre)s*%(ext)s" %(mencoder_opts)s2 -o %(mpegv)s %(std)s
--""" % all_vars
-- run(command)
-- if os.path.exists(os.path.join(source_dir, 'divx2pass.log')):
-- os.remove(os.path.join(source_dir, 'divx2pass.log'))
-- if os.path.exists(os.path.join(source_dir, 'xvid-twopass.stats')):
-- os.remove(os.path.join(source_dir, 'xvid-twopass.stats'))
--
-- if audio:
-- if not quiet:
-- print 'Creating "%s"-quality ogg vorbis file' % vtype
--
-- ogg = tempfile.mkstemp('.ogg', '', work_dir)[1]
-- if rawsndf:
-- wav = tempfile.mkstemp('.wav', '', work_dir)[1]
-- sox_opts = '-t raw -r %s -w -c 2 -s' % sndr
-- command = ' '.join([sox, sox_opts, sndf, wav])
-- run(command)
-- else:
-- wav = sndf
-- command = ' '.join([oggenc, oggenc_opts, wav, '-o', ogg, std])
-- run(command)
--
-- if delay != '0':
-- totfr = len(glob.glob(os.path.join(source_dir, syml + img_pre + '*' + ext)))
-- # "delay" is in ms, transform into s
-- totfrshift = int(totfr + round((locale.atof(delay)/1000.0)*locale.atof(fps)))
-- delaysh = ',%s/%s' % (totfrshift, totfr)
-- else:
-- delaysh = ''
--
-- all_vars.update(locals())
--
-- if not quiet: print 'Multiplexing...'
-- command = """
--%(ogmplex)s -o "%(vidname)s" %(mpegv)s -s 0%(delaysh)s %(ogg)s %(std)s""" % all_vars
-- run(command)
--
-- if rawsndf and os.path.exists(wav): os.remove(wav)
-- if os.path.exists(ogg): os.remove(ogg)
-- else:
-- if not quiet: print 'Multiplexing...'
-- command = """
--%(ogmplex)s -o "%(vidname)s" %(mpegv)s %(std)s""" % all_vars
-- run(command)
--
-- if os.path.exists(mpegv): os.remove(mpegv)
--
-- if frame_range:
-- lframes = os.path.join(source_dir, syml)
-- for frame in glob.glob(lframes + '*'):
-- os.remove(frame)
--
--
--def do_clean():
-- """
-- Delete enhanced files
-- """
--
-- if not quiet:
-- print 'Deleting all enhanced images (if any)'
--
-- eframes = os.path.join(work_dir, 'eimg')
-- rframes = os.path.join(work_dir, 'rimg')
-- for frame in glob.glob(eframes + '*'):
-- os.remove(frame)
-- for frame in glob.glob(rframes + '*'):
-- os.remove(frame)
--
--
--def which(command):
-- """
-- Finds (or not) a command a la "which"
-- """
--
-- command_found = False
--
-- if command[0] == '/':
-- if os.path.isfile(command) and \
-- os.access(command, os.X_OK):
-- command_found = True
-- abs_command = command
-- else:
-- path = os.environ.get('PATH', '').split(os.pathsep)
-- for dir in path:
-- abs_command = os.path.join(dir, command)
-- if os.path.isfile(abs_command) and \
-- os.access(abs_command, os.X_OK):
-- command_found = True
-- break
--
-- if not command_found:
-- abs_command = ''
--
-- return abs_command
--
--
--def is_installed(prog):
-- """
-- See whether "prog" is installed
-- """
--
-- wprog = which(prog)
--
-- if wprog == '':
-- print prog + ': command not found'
-- raise SystemExit
-- else:
-- if verbose:
-- print wprog + ': found'
--
--
--if __name__ == '__main__':
--
-- import os
-- import sys
-- import getopt
-- import shutil
-- import tempfile
-- import glob
-- import tarfile
--
-- try:
-- if sys.version_info[0:3] < (2, 3, 0):
-- raise SystemExit
-- except:
-- print 'You need Python 2.3.0 or greater to run me!'
-- raise SystemExit
--
-- try:
-- (opts, args) = getopt.getopt(sys.argv[1:], \
-- 'ho:p:d:w:a:qvt:ekc:r:s:b:f:VCD:L:')
-- except:
-- print "Something's wrong. Try the '-h' flag."
-- raise SystemExit
--
-- opts = dict(opts)
--
-- if not opts and not args:
-- print usage
-- raise SystemExit
--
-- if '-h' in opts:
-- print usage + help
-- raise SystemExit
--
-- if '-V' in opts:
-- print 'ogm_encoder.py version ' + version
-- raise SystemExit
--
-- if ('-v' in opts) or ('-C' in opts):
-- verbose = True
-- else:
-- verbose = False
--
-- if '-q' in opts:
-- quiet = True
-- verbose = False
-- else:
-- quiet = False
--
-- for i in [convert, mencoder, oggenc, sox, ogmplex]:
-- is_installed(i)
-- if '-C' in opts: raise SystemExit
--
-- img_pre = opts.get('-p', '')
--
-- if img_pre not in ['', 'eimg', 'rimg']:
-- print 'Improper image name prefix.'
-- raise SystemExit
--
-- temp_dir = ''
-- img_dir = opts.get('-d', '.')
-- img_dir = os.path.abspath(img_dir)
-- if ' ' in img_dir:
-- temp_dir = tempfile.mkdtemp('', '.lives-', '/tmp/')
-- os.symlink(img_dir, temp_dir + '/img_dir')
-- img_dir = temp_dir + '/img_dir'
--
-- if not os.path.isdir(img_dir):
-- print 'The image source directory: ' + img_dir + \
-- ' does not exist!'
-- raise SystemExit
--
-- if len(args) not in [0, 2]:
-- print 'If frames are specified both first and last ' + \
-- 'image numbers must be chosen.'
-- raise SystemExit
-- elif len(args) == 0:
-- args = [None, None]
--
-- frame_range = False
-- if not args[0]:
-- first_frame_num = '1'
-- else:
-- frame_range = True
-- first_frame_num = args[0]
-- first_frame_num = first_frame_num.zfill(8)
-- first_num = int(first_frame_num)
--
-- if not args[1]:
-- last_frame_num = '99999999'
-- else:
-- last_frame_num = args[1]
-- last_frame_num = last_frame_num.zfill(8)
-- last_num = int(last_frame_num)
--
-- aspectc = opts.get('-a', '2')
--
-- if aspectc not in [str(i) for i in xrange(1,5)]:
-- print 'Invalid aspect ratio.'
-- raise SystemExit
-- else:
-- if aspectc == '1': aspect = '1/1'
-- elif aspectc == '2': aspect = '4/3'
-- elif aspectc == '3': aspect = '16/9'
-- elif aspectc == '4': aspect = '221/100'
--
-- vtype = opts.get('-t', 'ml')
--
-- out_ogm = opts.get('-o', vtype + '_movie.ogm')
--
-- if '_' not in vtype:
-- vtype = vtype + '_d'
--
-- if vtype not in ['hi_d', 'mh_d', 'ml_d', 'lo_d', \
-- 'hi_x', 'mh_x', 'ml_x', 'lo_x']:
-- print 'Invalid video type.'
-- raise SystemExit
--
-- fpsc = opts.get('-f', '4')
--
-- if fpsc not in [str(i) for i in xrange(1,9)]:
-- if not quiet: print 'Invalid fps code, attempting float fps.'
-- foundfps = False
-- else:
-- if fpsc == '1': fps = str(24000.0/1001.0)
-- elif fpsc == '2': fps = str(24.0)
-- elif fpsc == '3': fps = str(25.0)
-- elif fpsc == '4': fps = str(30000.0/1001.0)
-- elif fpsc == '5': fps = str(30.0)
-- elif fpsc == '6': fps = str(50.0)
-- elif fpsc == '7': fps = str(60000.0/1001.0)
-- elif fpsc == '8': fps = str(60.0)
-- foundfps = True
--
-- if not foundfps:
-- try:
-- fps = locale.atof(fpsc)
-- if not quiet: print 'Using fps = %s' % fps
-- if fps > 0: foundfps = True
-- except:
-- pass
--
-- if not foundfps:
-- print 'Invalid fps code or rate.'
-- raise SystemExit
--
-- if '-e' not in opts:
-- enhance = False
-- else:
-- enhance = True
--
-- if enhance and img_pre:
-- print 'Sorry, you cannot enhance already-enhanced images'
-- raise SystemExit
--
-- if '-k' not in opts:
-- keep = False
-- else:
-- keep = True
--
-- cgeom = opts.get('-c', '')
-- rgeom = opts.get('-r', '')
--
-- if (cgeom or rgeom) and not enhance:
-- print 'Missing "-e" option.'
-- raise SystemExit
--
-- lv1file = opts.get('-L', None)
-- if lv1file:
-- if not quiet: print 'Opening lv1 file...'
-- try:
-- lv1 = tarfile.open(os.path.abspath(lv1file))
-- except:
-- print 'This does not appear to be a valid LiVES file!'
-- raise SystemExit
-- if 'header.tar' not in lv1.getnames():
-- print 'This does not appear to be a valid LiVES file!'
-- raise SystemExit
-- for tfile in lv1.getmembers():
-- lv1.extract(tfile, img_dir)
-- for tfile in glob.glob(os.path.join(img_dir, '*.tar')):
-- imgtar = tarfile.open(tfile)
-- for img in imgtar.getmembers():
-- imgtar.extract(img, img_dir)
-- os.remove(tfile)
--
-- test_file = os.path.join(img_dir, img_pre + first_frame_num)
-- if os.path.isfile(test_file + '.jpg'):
-- ext = '.jpg'
-- elif os.path.isfile(test_file + '.png'):
-- ext = '.png'
-- else:
-- print 'Cannot find any appropriate %s or %s files!' % ('.jpg','.png')
-- raise SystemExit
-- first_frame = test_file + ext
-- last_frame = os.path.join(img_dir, img_pre + last_frame_num + ext)
--
-- if not quiet: print 'Found: ' + first_frame
--
-- work_dir = opts.get('-w', img_dir)
-- work_dir = os.path.abspath(work_dir)
-- if not os.path.isdir(work_dir):
-- if not quiet: print 'Creating ' + work_dir
-- try:
-- os.makedirs(work_dir)
-- os.chmod(work_dir, 0755)
-- except:
-- print 'Could not create the work directory ' + \
-- work_dir
-- raise SystemExit
-- if ' ' in work_dir:
-- if temp_dir == '':
-- temp_dir = tempfile.mkdtemp('', '.lives-', '/tmp/')
-- os.symlink(work_dir, temp_dir + '/work_dir')
-- work_dir = temp_dir + '/work_dir'
--
-- sndf = opts.get('-s', os.path.join(img_dir, 'audio'))
--# sndf = os.path.abspath(sndf)
-- rawsndf = True
-- if not os.path.isfile(sndf):
-- audio = False
-- rawsndf = False
-- else:
-- audio = True
-- if sndf[-4:] == '.wav':
-- rawsndf = False
-- if not quiet: print 'Found audio file: ' + sndf
--
-- sndr = opts.get('-b', '44100')
--
-- delay = opts.get('-D', '0')
-- if verbose and audio: print 'Linear audio delay (ms): ' + delay
--
-- if enhance:
-- do_enhance()
-- # Note that do_enhance() always creates images prefixed
-- # with 'rimg'. What's important to note if that if the
-- # images are resized the 'rimg' are indeed resized, but
-- # if not the 'rimg' are simply symlinks to (or copies of) the 'eimg'
-- # (enhanced) images.
-- img_pre = 'rimg'
-- ext = '.png'
-- vidname = os.path.join(work_dir, out_ogm)
-- # do_encode() acts on images prefixed by img_pre.
-- do_encode()
-- if not keep:
-- do_clean()
-- if temp_dir != '':
-- shutil.rmtree(temp_dir)
-- if not quiet: print "Done!"
--
--
--"""
--CHANGELOG:
--
--21 Jul 2004 : 0.0.2 : added support for ".wav" files.
-- added '-C' flag.
--28 Jul 2004 : 0.0.3 : added '-D' flag.
-- fixed typos.
-- eliminated some subshell calls.
-- convert dirs to absolute paths.
-- fixed frame range detection.
-- fixed work_dir permissions.
--30 Jul 2004 : 0.0.4 : added '-L' flag.
-- encoder is now feature-complete.
--25 Sep 2004 : 0.0.5 : make sure "rawsndf" is set correctly.
-- check if files exist before removing.
--02 Oct 2004 : 0.0.6 : multiplex even if no audio.
--28 Oct 2004 : 0.0.7 : can handle arbitrary fps values.
--02 Nov 2004 : 0.0.8 : added XviD encoding.
--08 Nov 2004 : 0.0.9 : make sure that the enhanced
-- color depth is 8-bits/channel.
-- fixed XviD aspect ratio.
-- added chroma_opt to XviD.
--02 Jan 2005 : 0.1.0 : updated docs.
-- added sound rate (-b) option.
--26 Mar 2005 : 0.1.1 : use env python (hopefully >= 2.3).
-- replace denoise3d with hqdn3d.
--24 Aug 2005 : 0.1.2 : Fixed 2.21:1 aspect ratio.
-- fine-tune mplayer filters.
--09 Mar 2006 : 0.1.3 : added '-depth 8' to resize, as ImageMagick
-- keeps changing its damn behaviour.
-- Fixed bitrate levels.
--13 Mar 2006 : 0.1.4 : tweaked bitrate levels.
--28 Jun 2007 : 0.1.5 : handles paths with spaces appropriately
-- (thanks Gabriel).
--"""
---- /dev/null
-+++ lives/lives-plugins/marcos-encoders/theora_encoder
-@@ -0,0 +1,817 @@
-+#!/usr/bin/env python
-+
-+"""
-+theora_encoder.py
-+
-+Front-end to various programs needed to create Ogg Theora
-+movies with some image-enhancing capabilities through the use of
-+ImageMagick. Meant as a companion to LiVES (to possibly call
-+from within a plugin, see http://www.xs4all.nl/~salsaman/lives/ )
-+but can also be used as a stand-alone program.
-+
-+Requires MPlayer, ImageMagick (GraphicsMagick might also
-+work), sox, libtheora, and Python 2.3.0 or greater.
-+
-+Copyright (C) 2004-2005 Marco De la Cruz (marco at reimeika.ca)
-+It's a trivial program, but might as well GPL it, so see:
-+http://www.gnu.org/copyleft/gpl.html for license.
-+
-+See my vids at http://amv.reimeika.ca !
-+"""
-+
-+version = '0.1.6'
-+convert = 'convert'
-+mplayer = 'mplayer'
-+theora_encoder = 'encoder_example'
-+theora_encoder2 = 'theora_encoder_example'
-+
-+sox = 'sox'
-+identify = 'identify'
-+
-+usage = \
-+ """
-+theora_encoder.py -h
-+theora_encoder.py -V
-+theora_encoder.py -C
-+theora_encoder.py [-o out] [-p pre] [-d dir] [-a aspect] [-D delay*]
-+ [-q|-v] [-t type] [-k] [-e [[-w dir] [-c geom] [-r geom]]]
-+ [-s sndfile] [-b sndrate] [-f fpscode] [-L lv1file]
-+ [firstframe lastframe]
-+ """
-+
-+help = \
-+ """
-+SUMMARY (ver. %s):
-+
-+Encodes a series of PNG or JPG images into an Ogg Theora
-+(.ogg) stream and is also capable of performing some simple image
-+enhacements using ImageMagick. The images and audio are assumed to
-+be in an uncompressed LiVES format, hence making this encoder
-+more suitable to be used within a LiVES plugin (but can also
-+be used directly on a LiVES temporary directory).
-+
-+OPTIONS:
-+
-+-h for help.
-+
-+-V shows the version number.
-+
-+-C check external program dependencies and exit.
-+
-+-o out will save the video in file "out".
-+ Default: "'type'_movie.ogg". See below for 'type'.
-+
-+-p pre the encoder assumes that sound and images are named using
-+ LiVES' conventions i.e. "audio" and "00000001.ext",
-+ "00000002.ext"... where "ext" is either "jpg" or "png".
-+ However, theora_encoder.py will create temporary files
-+ which can be saved for later use (for example, after
-+ enhancing the images with "-e" , which may take a long
-+ time). These temporary files will be named
-+ "pre_00000001.ext", etc... where "pre" is either "eimg"
-+ or "rimg" and will be kept if the "-k" option is used.
-+ theora_encoder.py can then be run over the enhanced images
-+ only by selecting the appropriate prefix ("eimg" or
-+ "rimg") here. See "-e" to see what each prefix means.
-+ Default: "" (an empty string).
-+
-+-d dir "dir" is the directory containing the source image
-+ files. These must be of the form "00000001.ext" or
-+ "pre_00000001.ext" as explained above.
-+ Default: "."
-+
-+-a aspect sets the aspect ratio of the resulting Theora file. This can be:
-+
-+ 1 1:1 display
-+ 2 4:3 display
-+ 3 16:9 display
-+ 4 2.21:1 display
-+
-+ Default: "2"
-+
-+-D delay* linearly delay the audio stream by "delay" ms.
-+ Default: "0"
-+ * = NOT IMPLEMENTED (YET?)
-+
-+-q quiet operation, only complains on error.
-+
-+-v be verbose.
-+
-+-t type type of video created. The options here are:
-+
-+ "hi": a very high quality movie, suitable
-+ for archiving images of 720x480.
-+
-+ "mh": medium-high quality movie, which still allows
-+ to watch small videos (352x240 and below)
-+ fullscreen.
-+
-+ "ml": medium-low quality movie, suitable for
-+ most videos but in particular small videos
-+ (352x240 and below) meant for online
-+ distribution.
-+
-+ "lo": a low quality movie format. Enlarging
-+ small videos will result in noticeable
-+ artifacts. Good for distributing over slow
-+ connections.
-+
-+ Default: "ml"
-+
-+-e perform some simple filtering/enhancement to improve image
-+ quality. The images created by using this option will be
-+ stored in the directory specified by the "-w" option (or
-+ "-d" if not present, see above) and each filename will be
-+ prefixed with "eimg" (see "-p" above). Using this option will
-+ take enormous amounts of disk space, and in reality does
-+ not do anything that cannot be done within LiVES itself.
-+ Using this option enables the following four:
-+
-+ -w dir "dir" is the working directory where the enhanced
-+ images will be saved. Although these can all
-+ co-exist with the original LiVES files it is
-+ recommended you use a different directory. Note
-+ that temporary files may take a huge amount of
-+ space, perhaps twice as much as the LiVES files
-+ themselves. If this directory does not exist is
-+ will be created.
-+ Default: same as "-d".
-+
-+ -k keep the temporary files, useful to experiment
-+ with different encoding types without having
-+ to repeatedly enhance the images (which can be
-+ very time-consuming). See "-p" above.
-+
-+ -c geom in addition to enhancing the images, crop them
-+ to the specified geometry e.g. "688x448+17+11".
-+ Filename prefix remains "eimg". Note that the
-+ dimensions of the images should both be multiples
-+ of "16", otherwise some players may show artifacts
-+ (such as garbage or green bars at the borders).
-+
-+ -r geom this will create a second set of images resulting
-+ from resizing the images that have already been
-+ enhanced and possibly cropped (if "-c" has been
-+ specified). The geometry here is simple a new
-+ image size e.g. "352x240!". This second set will have
-+ filenames prefixed with the string "rimg" (see "-p"
-+ above). Note that the dimensions of the images
-+ should both be multiples of "16", otherwise some
-+ players may show artifacts (such as garbage or
-+ green bars at the borders).
-+
-+-s sndfile name of the audio file. Can be either raw "audio" or
-+ "[/path/to/]soundfile.wav".
-+ Default: "audio" inside "dir" as specified by "-d".
-+
-+-b sndrate sample rate of the sound file in Hertz.
-+ Default: "44100".
-+
-+-f fpscode frame-rate code. Acceptable values are:
-+
-+ 1 - 24000.0/1001.0 (NTSC 3:2 pulldown converted FILM)
-+ 2 - 24.0 (NATIVE FILM)
-+ 3 - 25.0 (PAL/SECAM VIDEO / converted FILM)
-+ 4 - 30000.0/1001.0 (NTSC VIDEO)
-+ 5 - 30.0
-+ 6 - 50.0 (PAL FIELD RATE)
-+ 7 - 60000.0/1001.0 (NTSC FIELD RATE)
-+ 8 - 60.0
-+
-+ If the input value is a float (e.g. 5.0, 14.555, etc.)
-+ the encoder will use that as frame rate.
-+
-+ Default: "4".
-+
-+-L lv1file use the images stored in the LiVES file "lv1file" (e.g.
-+ "movie.lv1"). Files will be extracted inside "dir" as
-+ specified by "-d". Using this option allows to encode
-+ a movie without having to restore it first with LiVES.
-+ Note that the encoder will not delete the extracted
-+ files after it has finished, this must be done manually
-+ afterwards. If frame code/rate (-f) and/or sound rate (-b)
-+ are not specified the defaults will be used (30000/1001 fps
-+ and 44100 Hz). These, however, may not be correct, in which
-+ case they should be specified explicitly. Furthermore, the
-+ .lv1 audio (if present) is always assumed to have a sample
-+ data size in 16-bit words with two channels, and to be signed
-+ linear (this is usually the case, however). If any of these
-+ latter parameters are incorrect the resulting file may be
-+ corrupted and encoding will have to be done using LiVES.
-+
-+firstframe first frame number. If less than eight digits long it will
-+ be padded with zeroes e.g. 234 -> 00000234. A prefix can
-+ be added using the "-p" option.
-+ Default: "00000001"
-+
-+lastframe last frame number, padded with zeroes if necessary, prefix
-+ set by "-p".
-+ Default: the last frame of its type in the "-d" directory,
-+ where "type" is set by the prefix.
-+
-+Note that either no frames or both first and last frames must be specified.
-+
-+EXAMPLES:
-+
-+Suppose you have restored a LiVES' .lv1 file (in either JPG or PNG format),
-+and that the images are stored in the directory "/tmp/livestmp/991319584/".
-+In this example the movie is assumed to be 16:9. Then, in order to create
-+an ogg file you can simply do the following:
-+
-+ theora_encoder.py -d /tmp/livestmp/991319584 -o /movies/default.ogg -a 3
-+
-+and the clip "default.ogg" will be created in "/movies/" with the correct
-+aspect ratio.
-+
-+Suppose we want to make a downloadable version of the clip, small in size
-+but of good quality. The following command activates the generic enhancement
-+filter and resizes the images to "352x240". Note that these operations
-+are performed after cropping the originals a bit (using "704x464+5+6").
-+This is done because we are assuming that there is a black border around
-+the original pictures which we want to get rid of (this might distort the
-+images somewhat, so be careful about cropping/resizing, and remember to
-+use dimensions which are multiples of 16):
-+
-+ theora_encoder.py -v -d /tmp/livestmp/991319584 -w /tmp/tmpogg \\
-+ -o /movies/download.ogg -a 3 -k -e -c "704x464+5+6" -r "352x240"
-+
-+Since we use the "-k" flag the enhanced images are kept (both full-size
-+crops and the resized ones) in "/tmp/tmpogg". Beware that this may consume
-+a lot of disk space (about 10x as much as the originals). The reason we
-+keep them is because the above may take quite a long time and we may want
-+to re-use the enhanced images. So, for example, creating a high-quality
-+clip at full size can be accomplished now as follows:
-+
-+ theora_encoder.py -d /tmp/tmpogg -t hi -o /movies/archive.ogg \\
-+ -s /tmp/livestmp/991319584/audio -a 3 -k -p eimg
-+
-+If, for example, we only want to encode frames 100 to 150 we can run
-+the following:
-+
-+ theora_encoder.py -v -d /tmp/tmpogg -o /movies/selection.ogg \\
-+ -a 3 -k -p eimg 100 150
-+
-+Note that no audio has been selected ("-s"). This is because
-+theora_encoder.py cannot trim the audio to the appropriate length.
-+You would need to use LiVES to do this.
-+
-+To delete all the enhanced images you can just remove "/tmp/tmpogg".
-+
-+If you notice that the video and audio become out of sync so that
-+near the end of the movie the video trails the audio by, say, 0.2s,
-+you can use the "-D" option as follows:
-+
-+ theora_encoder.py -d /tmp/livestmp/991319584 -o test.ogg -D 200
-+
-+Note that negative time values are also allowed ("-D" NOT IMPLEMENTED YET).
-+
-+Suppose that you have "movie1.lv1", "movie2.lv1" and "movie3.lv1".
-+Batch-encoding can be done as follows (zsh-syntax):
-+
-+ for i in movie?.lv1
-+ do
-+ mkdir /tmp/$i:r
-+ theora_encoder.py -d /tmp/$i:r -o /tmp/$i:r.ogg -L $i
-+ rm -rf /tmp/$i:r
-+ done
-+
-+This will generate the files "movie1.ogg", "movie2.ogg" and
-+"movie3.ogg" in "/tmp". Note that is is not necessary to
-+specify whether the files are stored in JPG or PNG format,
-+and that potentially time-consuming options (e.g. "-e") may
-+be enabled. It is not necessary to have a working LiVES
-+installation to encode .lv1 files.
-+ """ % version
-+
-+
-+def gcd(a, b):
-+ """
-+ gcd(a, b) (a,b are integers)
-+ Returns the greatest common divisor of two integers.
-+ """
-+ if b == 0: return a
-+ else: return gcd(b, a%b)
-+
-+
-+def frame2pixel_aspect(size, frame_aspect):
-+ pixel_den = int(frame_aspect[1])*int(size[0])
-+ pixel_num = int(frame_aspect[0])*int(size[1])
-+
-+ divisor = gcd(pixel_num, pixel_den)
-+ if divisor > 1:
-+ pixel_num = pixel_num/divisor
-+ pixel_den = pixel_den/divisor
-+ pixel_aspect = (pixel_num, pixel_den)
-+ return pixel_aspect
-+
-+
-+def run(command):
-+ """
-+ Run a shell command
-+ """
-+
-+ if verbose:
-+ print 'Running: \n' + command + '\n=== ... ==='
-+ std = ''
-+ else:
-+ std = ' > /dev/null 2>&1'
-+
-+ os.system(command + std)
-+
-+
-+def do_enhance():
-+ """
-+ Image cleanup/crop/resize routine. Generic, but seems to work
-+ well with anime :)
-+ """
-+
-+ if not quiet:
-+ print 'Enhancing images... please wait, this might take long...'
-+
-+ enh_opts = "-enhance -sharpen '0.0x0.5' -gamma 1.2 -contrast -depth 8"
-+
-+ if cgeom:
-+ docrop = ' '.join(['-crop', "'%s!'" % cgeom])
-+ else:
-+ docrop = ''
-+
-+ iframe = first_num
-+ while True:
-+ # File names are padded with zeroes to 8 characters
-+ # (not counting the .ext).
-+ frame = str(iframe).zfill(8)
-+ fname = os.path.join(img_dir, frame + ext)
-+ if not os.path.isfile(fname) or (iframe == last_num + 1):
-+ break
-+ eimg_fname = os.path.join(work_dir, 'eimg' + frame + '.png')
-+ rimg_fname = os.path.join(work_dir, 'rimg' + frame + '.png')
-+ command = ' '.join([convert, docrop, enh_opts, fname, eimg_fname])
-+ run(command)
-+ if rgeom:
-+ if os.path.exists(rimg_fname): os.remove(rimg_fname)
-+ shrink = ' '.join([convert, '-resize', "'%s!'" % rgeom, '-depth 8'])
-+ command = ' '.join([shrink, eimg_fname, rimg_fname])
-+ run(command)
-+ else:
-+ if os.path.exists(rimg_fname): os.remove(rimg_fname)
-+ try:
-+ os.symlink(eimg_fname, rimg_fname)
-+ except (IOError, OSError):
-+ shutil.copy(eimg_fname, rimg_fname)
-+ iframe+=1
-+
-+
-+def do_encode():
-+ """
-+ Encode a series of images into a Theora movie.
-+ """
-+
-+ if verbose:
-+ std = ''
-+ std2 = ''
-+ be_verbose = '-verbose'
-+ else:
-+ std = ' > /dev/null 2>&1'
-+ std2 = ' 2> /dev/null'
-+ be_verbose = ''
-+
-+ if which(theora_encoder2) != '':
-+ theora_encoder = theora_encoder2
-+
-+ fpsnum = fps.split('/')[0]
-+ fpsden = fps.split('/')[1]
-+ mplayer_opts = '-mf type=%s:fps=%s ' % (ext[1:],
-+ eval('float('+fpsnum+')/'+fpsden)) + \
-+ '-vf hqdn3d=2:1:3,pp=va:128:8/ha:128:8/dr,dsize=%s -vo yuv4mpeg -ao null -nosound' % aspect
-+
-+ if img_dir != work_dir and not enhance:
-+ source_dir = img_dir
-+ else:
-+ source_dir = work_dir
-+
-+ fgeom = os.popen(' '.join([identify, '-format "%w %h"', \
-+ os.path.join(source_dir, \
-+ img_pre + \
-+ first_frame_num + \
-+ ext)])).read().strip().split()
-+
-+ par = frame2pixel_aspect(fgeom, aspect.split(':'))
-+ theora_opts = '-s %s -S %s -f %s -F %s' % (par[0], par[1], fpsnum, fpsden)
-+ if vtype == 'hi':
-+ theora_opts = ' '.join([theora_opts, '-v 10 -a 10'])
-+ elif vtype == 'mh':
-+ theora_opts = ' '.join([theora_opts, '-v 8 -a 6'])
-+ elif vtype == 'ml':
-+ theora_opts = ' '.join([theora_opts, '-v 6 -a 4'])
-+ elif vtype == 'lo':
-+ theora_opts = ' '.join([theora_opts, '-v 4 -a 2'])
-+
-+ if frame_range:
-+ numframes = str(last_num - first_num + 1)
-+ frame_list = [img_pre + str(f).zfill(8) + ext \
-+ for f in range(first_num, last_num + 1)]
-+ syml = 'temporary_symlink_'
-+ for iframe in frame_list:
-+ frfile = os.path.join(source_dir, iframe)
-+ frlink = os.path.join(source_dir, syml + iframe)
-+ if os.path.islink(frlink): os.remove(frlink)
-+ os.symlink(frfile, frlink)
-+ else:
-+ syml = ''
-+ numframes = len(glob.glob(os.path.join(source_dir, \
-+ img_pre + '*' + ext)))
-+
-+ if audio:
-+ if rawsndf:
-+ wav = tempfile.mkstemp('.wav', '', work_dir)[1]
-+ sox_opts = '-t raw -r %s -w -c 2 -s' % sndr
-+ command = ' '.join([sox, sox_opts, sndf, wav])
-+ run(command)
-+ else:
-+ wav = sndf
-+ else:
-+ wav = ''
-+
-+ all_vars = {}
-+ all_vars.update(globals())
-+ all_vars.update(locals())
-+
-+ if not quiet:
-+ print 'Creating "%s"-quality Theora file' % vtype
-+
-+ # mplayer with "-vo yuv4mpeg" always outputs to "stream.yuv"
-+ # maybe create the pipe pythonically?
-+ command = """cd %(source_dir)s ; \\
-+mkfifo -m 0600 stream.yuv ; \\
-+%(mplayer)s mf://%(syml)s%(img_pre)s*%(ext)s %(mplayer_opts)s %(std)s &
-+""" % all_vars
-+ run(command)
-+ command = """cd %(source_dir)s ; \\
-+%(theora_encoder)s %(theora_opts)s -o "%(vidname)s" %(wav)s stream.yuv %(std)s
-+""" % all_vars
-+ run(command)
-+
-+ if os.path.exists(os.path.join(source_dir, 'stream.yuv')):
-+ os.remove(os.path.join(source_dir, 'stream.yuv'))
-+
-+ if rawsndf and os.path.exists(wav): os.remove(wav)
-+
-+ if frame_range:
-+ lframes = os.path.join(source_dir, syml)
-+ for frame in glob.glob(lframes + '*'):
-+ os.remove(frame)
-+
-+
-+def do_clean():
-+ """
-+ Delete enhanced files
-+ """
-+
-+ if not quiet:
-+ print 'Deleting all enhanced images (if any)'
-+
-+ eframes = os.path.join(work_dir, 'eimg')
-+ rframes = os.path.join(work_dir, 'rimg')
-+ for frame in glob.glob(eframes + '*'):
-+ os.remove(frame)
-+ for frame in glob.glob(rframes + '*'):
-+ os.remove(frame)
-+
-+
-+def which(command):
-+ """
-+ Finds (or not) a command a la "which"
-+ """
-+
-+ command_found = False
-+
-+ if command[0] == '/':
-+ if os.path.isfile(command) and \
-+ os.access(command, os.X_OK):
-+ command_found = True
-+ abs_command = command
-+ else:
-+ path = os.environ.get('PATH', '').split(os.pathsep)
-+ for dir in path:
-+ abs_command = os.path.join(dir, command)
-+ if os.path.isfile(abs_command) and \
-+ os.access(abs_command, os.X_OK):
-+ command_found = True
-+ break
-+
-+ if not command_found:
-+ abs_command = ''
-+
-+ return abs_command
-+
-+
-+def is_installed(prog):
-+ """
-+ See whether "prog" is installed
-+ """
-+
-+ wprog = which(prog)
-+
-+ if wprog == '':
-+ if prog == theora_encoder:
-+ if which(theora_encoder2) == '':
-+ print theora_encoder + ' or ' + theora_encoder2 + ': command not found'
-+ raise SystemExit
-+ else:
-+ if prog != theora_encoder2:
-+ print prog + ': command not found'
-+ raise SystemExit
-+
-+ else:
-+ if verbose:
-+ print wprog + ': found'
-+
-+
-+if __name__ == '__main__':
-+
-+ import os
-+ import sys
-+ import getopt
-+ import shutil
-+ import tempfile
-+ import glob
-+ import tarfile
-+
-+ try:
-+ if sys.version_info[0:3] < (2, 3, 0):
-+ raise SystemExit
-+ except:
-+ print 'You need Python 2.3.0 or greater to run me!'
-+ raise SystemExit
-+
-+ try:
-+ (opts, args) = getopt.getopt(sys.argv[1:], \
-+ 'ho:p:d:w:a:qvt:ekc:r:s:b:f:VCD:L:')
-+ except:
-+ print "Something's wrong. Try the '-h' flag."
-+ raise SystemExit
-+
-+ opts = dict(opts)
-+
-+ if not opts and not args:
-+ print usage
-+ raise SystemExit
-+
-+ if '-h' in opts:
-+ print usage + help
-+ raise SystemExit
-+
-+ if '-V' in opts:
-+ print 'theora_encoder.py version ' + version
-+ raise SystemExit
-+
-+ if ('-v' in opts) or ('-C' in opts):
-+ verbose = True
-+ else:
-+ verbose = False
-+
-+ if '-q' in opts:
-+ quiet = True
-+ verbose = False
-+ else:
-+ quiet = False
-+
-+ for i in [mplayer, theora_encoder, theora_encoder2, sox, convert, identify]:
-+ is_installed(i)
-+ if '-C' in opts: raise SystemExit
-+
-+ img_pre = opts.get('-p', '')
-+
-+ if img_pre not in ['', 'eimg', 'rimg']:
-+ print 'Improper image name prefix.'
-+ raise SystemExit
-+
-+ temp_dir = ''
-+ img_dir = opts.get('-d', '.')
-+ img_dir = os.path.abspath(img_dir)
-+ if ' ' in img_dir:
-+ temp_dir = tempfile.mkdtemp('', '.lives-', '/tmp/')
-+ os.symlink(img_dir, temp_dir + '/img_dir')
-+ img_dir = temp_dir + '/img_dir'
-+
-+ if not os.path.isdir(img_dir):
-+ print 'The image source directory: ' + img_dir + \
-+ ' does not exist!'
-+ raise SystemExit
-+
-+ if len(args) not in [0, 2]:
-+ print 'If frames are specified both first and last ' + \
-+ 'image numbers must be chosen.'
-+ raise SystemExit
-+ elif len(args) == 0:
-+ args = [None, None]
-+
-+ frame_range = False
-+ if not args[0]:
-+ first_frame_num = '1'
-+ else:
-+ frame_range = True
-+ first_frame_num = args[0]
-+ first_frame_num = first_frame_num.zfill(8)
-+ first_num = int(first_frame_num)
-+
-+ if not args[1]:
-+ last_frame_num = '99999999'
-+ else:
-+ last_frame_num = args[1]
-+ last_frame_num = last_frame_num.zfill(8)
-+ last_num = int(last_frame_num)
-+
-+ aspectc = opts.get('-a', '2')
-+
-+ if aspectc not in [str(i) for i in xrange(1,5)]:
-+ print 'Invalid aspect ratio.'
-+ raise SystemExit
-+ else:
-+ if aspectc == '1': aspect = '1:1'
-+ elif aspectc == '2': aspect = '4:3'
-+ elif aspectc == '3': aspect = '16:9'
-+ elif aspectc == '4': aspect = '221:100'
-+
-+ vtype = opts.get('-t', 'ml')
-+
-+ if vtype not in ['hi', 'mh', 'ml', 'lo']:
-+ print 'Invalid video type.'
-+ raise SystemExit
-+
-+ out_ogg = opts.get('-o', vtype + '_movie.ogg')
-+
-+ fpsc = opts.get('-f', '4')
-+
-+ if fpsc not in [str(i) for i in xrange(1,9)]:
-+ if not quiet: print 'Invalid fps code, attempting float fps.'
-+ foundfps = False
-+ else:
-+ if fpsc == '1': fps = '24000/1001'
-+ elif fpsc == '2': fps = '24/1'
-+ elif fpsc == '3': fps = '25/1'
-+ elif fpsc == '4': fps = '30000/1001'
-+ elif fpsc == '5': fps = '30/1'
-+ elif fpsc == '6': fps = '50/1'
-+ elif fpsc == '7': fps = '60000/1001'
-+ elif fpsc == '8': fps = '60/1'
-+ foundfps = True
-+
-+ if not foundfps:
-+ try:
-+ fpsnum = int(locale.atof(fpsc)*10**15)
-+ fpsden = 10**15
-+ divisor = gcd(fpsnum, fpsden)
-+ if divisor > 1:
-+ fpsnum = fpsnum/divisor
-+ fpsden = fpsden/divisor
-+ fps = '%s/%s' % (fpsnum, fpsden)
-+ if not quiet: print 'Using fps = ' + fps
-+ if fpsnum > 0: foundfps = True
-+ except:
-+ pass
-+
-+ if not foundfps:
-+ print 'Invalid fps code or rate.'
-+ raise SystemExit
-+
-+ if '-e' not in opts:
-+ enhance = False
-+ else:
-+ enhance = True
-+
-+ if enhance and img_pre:
-+ print 'Sorry, you cannot enhance already-enhanced images'
-+ raise SystemExit
-+
-+ if '-k' not in opts:
-+ keep = False
-+ else:
-+ keep = True
-+
-+ cgeom = opts.get('-c', '')
-+ rgeom = opts.get('-r', '')
-+
-+ if (cgeom or rgeom) and not enhance:
-+ print 'Missing "-e" option.'
-+ raise SystemExit
-+
-+ delay = opts.get('-D', '0')
-+ if verbose: print 'Linear audio delay (ms): ' + delay
-+
-+ lv1file = opts.get('-L', None)
-+ if lv1file:
-+ if not quiet: print 'Opening lv1 file...'
-+ try:
-+ lv1 = tarfile.open(os.path.abspath(lv1file))
-+ except:
-+ print 'This does not appear to be a valid LiVES file!'
-+ raise SystemExit
-+ if 'header.tar' not in lv1.getnames():
-+ print 'This does not appear to be a valid LiVES file!'
-+ raise SystemExit
-+ for tfile in lv1.getmembers():
-+ lv1.extract(tfile, img_dir)
-+ for tfile in glob.glob(os.path.join(img_dir, '*.tar')):
-+ imgtar = tarfile.open(tfile)
-+ for img in imgtar.getmembers():
-+ imgtar.extract(img, img_dir)
-+ os.remove(tfile)
-+
-+ test_file = os.path.join(img_dir, img_pre + first_frame_num)
-+ if os.path.isfile(test_file + '.jpg'):
-+ ext = '.jpg'
-+ elif os.path.isfile(test_file + '.png'):
-+ ext = '.png'
-+ else:
-+ print 'Cannot find any appropriate %s or %s files!' % ('.jpg','.png')
-+ raise SystemExit
-+ first_frame = test_file + ext
-+ geom = os.popen(identify + ' -format "%w %h" ' + first_frame).read().strip().split()
-+ last_frame = os.path.join(img_dir, img_pre + last_frame_num + ext)
-+
-+ if not quiet: print 'Found: ' + first_frame + ' (%sx%s)' % (geom[0], geom[1])
-+
-+ work_dir = opts.get('-w', img_dir)
-+ work_dir = os.path.abspath(work_dir)
-+ if not os.path.isdir(work_dir):
-+ if not quiet: print 'Creating ' + work_dir
-+ try:
-+ os.makedirs(work_dir)
-+ os.chmod(work_dir, 0755)
-+ except:
-+ print 'Could not create the work directory ' + \
-+ work_dir
-+ raise SystemExit
-+ if ' ' in work_dir:
-+ if temp_dir == '':
-+ temp_dir = tempfile.mkdtemp('', '.lives-', '/tmp/')
-+ os.symlink(work_dir, temp_dir + '/work_dir')
-+ work_dir = temp_dir + '/work_dir'
-+
-+ sndf = opts.get('-s', os.path.join(img_dir, 'audio'))
-+# sndf = os.path.abspath(sndf)
-+ rawsndf = True
-+ if not os.path.isfile(sndf):
-+ audio = False
-+ rawsndf = False
-+ else:
-+ audio = True
-+ if sndf[-4:] == '.wav':
-+ rawsndf = False
-+ if not quiet: print 'Found audio file: ' + sndf
-+
-+ sndr = opts.get('-b', '44100')
-+
-+ if enhance:
-+ do_enhance()
-+ # Note that do_enhance() always creates images prefixed
-+ # with 'rimg'. What's important to note if that if the
-+ # images are resized the 'rimg' are indeed resized, but
-+ # if not the 'rimg' are simply symlinks to the 'eimg'
-+ # (enhanced) images.
-+ img_pre = 'rimg'
-+ ext = '.png'
-+ vidname = os.path.join(work_dir, out_ogg)
-+ # do_encode() acts on images prefixed by img_pre.
-+ do_encode()
-+ if not keep:
-+ do_clean()
-+ if temp_dir != '':
-+ shutil.rmtree(temp_dir)
-+ if not quiet: print "Done!"
-+
-+
-+"""
-+CHANGELOG:
-+
-+25 Sep 2004 : 0.0.1 : first release.
-+01 Oct 2004 : 0.0.2 : made all fps fractions.
-+13 Oct 2004 : 0.0.3 : fix aspect ratio by using
-+ pixel aspect ratio instead of
-+ frame aspect ratio (j at v2v.cc).
-+ calculate frame size to do the above.
-+ fixed extension from ".ogv" to ".ogg".
-+14 Oct 2004 : 0.0.4 : "size" is (width, height) (original
-+ patch had assumed it switched).
-+26 Oct 2004 : 0.0.5 : can handle arbitrary fps values.
-+02 Nov 2004 : 0.0.6 : tweaked encoding quality levels.
-+08 Nov 2004 : 0.0.7 : make sure that the enhanced
-+ color depth is 8-bits/channel.
-+ tweaked encoding quality levels.
-+02 Jan 2005 : 0.0.8 : updated docs.
-+ added sound rate (-b) option.
-+22 Jan 2005 : 0.0.9 : fixed stream.yuv fps calculation.
-+11 Feb 2005 : 0.1.0 : fixed aspect ratio error (my bad :( )
-+26 Mar 2005 : 0.1.1 : use env python (hopefully >= 2.3).
-+ replace denoise3d with hqdn3d.
-+24 Aug 2005 : 0.1.2 : fine-tune mplayer filters (thanks to
-+ zikzak at tele2.fr).
-+ Fixed 2.21:1 aspect ratio.
-+09 Mar 2006 : 0.1.3 : added '-depth 8' to resize, as ImageMagick
-+ keeps changing its damn behaviour.
-+02 Apr 2006 : 0.1.4 : small aspect ratio bug fixed.
-+ tweaked audio quality settings.
-+28 Jun 2007 : 0.1.5 : handles paths with spaces appropriately
-+ (thanks Gabriel).
-+"""
---- lives.orig/lives-plugins/marcos-encoders/theora_encoder.py
-+++ /dev/null
-@@ -1,817 +0,0 @@
--#!/usr/bin/env python
--
--"""
--theora_encoder.py
--
--Front-end to various programs needed to create Ogg Theora
--movies with some image-enhancing capabilities through the use of
--ImageMagick. Meant as a companion to LiVES (to possibly call
--from within a plugin, see http://www.xs4all.nl/~salsaman/lives/ )
--but can also be used as a stand-alone program.
--
--Requires MPlayer, ImageMagick (GraphicsMagick might also
--work), sox, libtheora, and Python 2.3.0 or greater.
--
--Copyright (C) 2004-2005 Marco De la Cruz (marco at reimeika.ca)
--It's a trivial program, but might as well GPL it, so see:
--http://www.gnu.org/copyleft/gpl.html for license.
--
--See my vids at http://amv.reimeika.ca !
--"""
--
--version = '0.1.6'
--convert = 'convert'
--mplayer = 'mplayer'
--theora_encoder = 'encoder_example'
--theora_encoder2 = 'theora_encoder_example'
--
--sox = 'sox'
--identify = 'identify'
--
--usage = \
-- """
--theora_encoder.py -h
--theora_encoder.py -V
--theora_encoder.py -C
--theora_encoder.py [-o out] [-p pre] [-d dir] [-a aspect] [-D delay*]
-- [-q|-v] [-t type] [-k] [-e [[-w dir] [-c geom] [-r geom]]]
-- [-s sndfile] [-b sndrate] [-f fpscode] [-L lv1file]
-- [firstframe lastframe]
-- """
--
--help = \
-- """
--SUMMARY (ver. %s):
--
--Encodes a series of PNG or JPG images into an Ogg Theora
--(.ogg) stream and is also capable of performing some simple image
--enhacements using ImageMagick. The images and audio are assumed to
--be in an uncompressed LiVES format, hence making this encoder
--more suitable to be used within a LiVES plugin (but can also
--be used directly on a LiVES temporary directory).
--
--OPTIONS:
--
---h for help.
--
---V shows the version number.
--
---C check external program dependencies and exit.
--
---o out will save the video in file "out".
-- Default: "'type'_movie.ogg". See below for 'type'.
--
---p pre the encoder assumes that sound and images are named using
-- LiVES' conventions i.e. "audio" and "00000001.ext",
-- "00000002.ext"... where "ext" is either "jpg" or "png".
-- However, theora_encoder.py will create temporary files
-- which can be saved for later use (for example, after
-- enhancing the images with "-e" , which may take a long
-- time). These temporary files will be named
-- "pre_00000001.ext", etc... where "pre" is either "eimg"
-- or "rimg" and will be kept if the "-k" option is used.
-- theora_encoder.py can then be run over the enhanced images
-- only by selecting the appropriate prefix ("eimg" or
-- "rimg") here. See "-e" to see what each prefix means.
-- Default: "" (an empty string).
--
---d dir "dir" is the directory containing the source image
-- files. These must be of the form "00000001.ext" or
-- "pre_00000001.ext" as explained above.
-- Default: "."
--
---a aspect sets the aspect ratio of the resulting Theora file. This can be:
--
-- 1 1:1 display
-- 2 4:3 display
-- 3 16:9 display
-- 4 2.21:1 display
--
-- Default: "2"
--
---D delay* linearly delay the audio stream by "delay" ms.
-- Default: "0"
-- * = NOT IMPLEMENTED (YET?)
--
---q quiet operation, only complains on error.
--
---v be verbose.
--
---t type type of video created. The options here are:
--
-- "hi": a very high quality movie, suitable
-- for archiving images of 720x480.
--
-- "mh": medium-high quality movie, which still allows
-- to watch small videos (352x240 and below)
-- fullscreen.
--
-- "ml": medium-low quality movie, suitable for
-- most videos but in particular small videos
-- (352x240 and below) meant for online
-- distribution.
--
-- "lo": a low quality movie format. Enlarging
-- small videos will result in noticeable
-- artifacts. Good for distributing over slow
-- connections.
--
-- Default: "ml"
--
---e perform some simple filtering/enhancement to improve image
-- quality. The images created by using this option will be
-- stored in the directory specified by the "-w" option (or
-- "-d" if not present, see above) and each filename will be
-- prefixed with "eimg" (see "-p" above). Using this option will
-- take enormous amounts of disk space, and in reality does
-- not do anything that cannot be done within LiVES itself.
-- Using this option enables the following four:
--
-- -w dir "dir" is the working directory where the enhanced
-- images will be saved. Although these can all
-- co-exist with the original LiVES files it is
-- recommended you use a different directory. Note
-- that temporary files may take a huge amount of
-- space, perhaps twice as much as the LiVES files
-- themselves. If this directory does not exist is
-- will be created.
-- Default: same as "-d".
--
-- -k keep the temporary files, useful to experiment
-- with different encoding types without having
-- to repeatedly enhance the images (which can be
-- very time-consuming). See "-p" above.
--
-- -c geom in addition to enhancing the images, crop them
-- to the specified geometry e.g. "688x448+17+11".
-- Filename prefix remains "eimg". Note that the
-- dimensions of the images should both be multiples
-- of "16", otherwise some players may show artifacts
-- (such as garbage or green bars at the borders).
--
-- -r geom this will create a second set of images resulting
-- from resizing the images that have already been
-- enhanced and possibly cropped (if "-c" has been
-- specified). The geometry here is simple a new
-- image size e.g. "352x240!". This second set will have
-- filenames prefixed with the string "rimg" (see "-p"
-- above). Note that the dimensions of the images
-- should both be multiples of "16", otherwise some
-- players may show artifacts (such as garbage or
-- green bars at the borders).
--
---s sndfile name of the audio file. Can be either raw "audio" or
-- "[/path/to/]soundfile.wav".
-- Default: "audio" inside "dir" as specified by "-d".
--
---b sndrate sample rate of the sound file in Hertz.
-- Default: "44100".
--
---f fpscode frame-rate code. Acceptable values are:
--
-- 1 - 24000.0/1001.0 (NTSC 3:2 pulldown converted FILM)
-- 2 - 24.0 (NATIVE FILM)
-- 3 - 25.0 (PAL/SECAM VIDEO / converted FILM)
-- 4 - 30000.0/1001.0 (NTSC VIDEO)
-- 5 - 30.0
-- 6 - 50.0 (PAL FIELD RATE)
-- 7 - 60000.0/1001.0 (NTSC FIELD RATE)
-- 8 - 60.0
--
-- If the input value is a float (e.g. 5.0, 14.555, etc.)
-- the encoder will use that as frame rate.
--
-- Default: "4".
--
---L lv1file use the images stored in the LiVES file "lv1file" (e.g.
-- "movie.lv1"). Files will be extracted inside "dir" as
-- specified by "-d". Using this option allows to encode
-- a movie without having to restore it first with LiVES.
-- Note that the encoder will not delete the extracted
-- files after it has finished, this must be done manually
-- afterwards. If frame code/rate (-f) and/or sound rate (-b)
-- are not specified the defaults will be used (30000/1001 fps
-- and 44100 Hz). These, however, may not be correct, in which
-- case they should be specified explicitly. Furthermore, the
-- .lv1 audio (if present) is always assumed to have a sample
-- data size in 16-bit words with two channels, and to be signed
-- linear (this is usually the case, however). If any of these
-- latter parameters are incorrect the resulting file may be
-- corrupted and encoding will have to be done using LiVES.
--
--firstframe first frame number. If less than eight digits long it will
-- be padded with zeroes e.g. 234 -> 00000234. A prefix can
-- be added using the "-p" option.
-- Default: "00000001"
--
--lastframe last frame number, padded with zeroes if necessary, prefix
-- set by "-p".
-- Default: the last frame of its type in the "-d" directory,
-- where "type" is set by the prefix.
--
--Note that either no frames or both first and last frames must be specified.
--
--EXAMPLES:
--
--Suppose you have restored a LiVES' .lv1 file (in either JPG or PNG format),
--and that the images are stored in the directory "/tmp/livestmp/991319584/".
--In this example the movie is assumed to be 16:9. Then, in order to create
--an ogg file you can simply do the following:
--
-- theora_encoder.py -d /tmp/livestmp/991319584 -o /movies/default.ogg -a 3
--
--and the clip "default.ogg" will be created in "/movies/" with the correct
--aspect ratio.
--
--Suppose we want to make a downloadable version of the clip, small in size
--but of good quality. The following command activates the generic enhancement
--filter and resizes the images to "352x240". Note that these operations
--are performed after cropping the originals a bit (using "704x464+5+6").
--This is done because we are assuming that there is a black border around
--the original pictures which we want to get rid of (this might distort the
--images somewhat, so be careful about cropping/resizing, and remember to
--use dimensions which are multiples of 16):
--
-- theora_encoder.py -v -d /tmp/livestmp/991319584 -w /tmp/tmpogg \\
-- -o /movies/download.ogg -a 3 -k -e -c "704x464+5+6" -r "352x240"
--
--Since we use the "-k" flag the enhanced images are kept (both full-size
--crops and the resized ones) in "/tmp/tmpogg". Beware that this may consume
--a lot of disk space (about 10x as much as the originals). The reason we
--keep them is because the above may take quite a long time and we may want
--to re-use the enhanced images. So, for example, creating a high-quality
--clip at full size can be accomplished now as follows:
--
-- theora_encoder.py -d /tmp/tmpogg -t hi -o /movies/archive.ogg \\
-- -s /tmp/livestmp/991319584/audio -a 3 -k -p eimg
--
--If, for example, we only want to encode frames 100 to 150 we can run
--the following:
--
-- theora_encoder.py -v -d /tmp/tmpogg -o /movies/selection.ogg \\
-- -a 3 -k -p eimg 100 150
--
--Note that no audio has been selected ("-s"). This is because
--theora_encoder.py cannot trim the audio to the appropriate length.
--You would need to use LiVES to do this.
--
--To delete all the enhanced images you can just remove "/tmp/tmpogg".
--
--If you notice that the video and audio become out of sync so that
--near the end of the movie the video trails the audio by, say, 0.2s,
--you can use the "-D" option as follows:
--
-- theora_encoder.py -d /tmp/livestmp/991319584 -o test.ogg -D 200
--
--Note that negative time values are also allowed ("-D" NOT IMPLEMENTED YET).
--
--Suppose that you have "movie1.lv1", "movie2.lv1" and "movie3.lv1".
--Batch-encoding can be done as follows (zsh-syntax):
--
-- for i in movie?.lv1
-- do
-- mkdir /tmp/$i:r
-- theora_encoder.py -d /tmp/$i:r -o /tmp/$i:r.ogg -L $i
-- rm -rf /tmp/$i:r
-- done
--
--This will generate the files "movie1.ogg", "movie2.ogg" and
--"movie3.ogg" in "/tmp". Note that is is not necessary to
--specify whether the files are stored in JPG or PNG format,
--and that potentially time-consuming options (e.g. "-e") may
--be enabled. It is not necessary to have a working LiVES
--installation to encode .lv1 files.
-- """ % version
--
--
--def gcd(a, b):
-- """
-- gcd(a, b) (a,b are integers)
-- Returns the greatest common divisor of two integers.
-- """
-- if b == 0: return a
-- else: return gcd(b, a%b)
--
--
--def frame2pixel_aspect(size, frame_aspect):
-- pixel_den = int(frame_aspect[1])*int(size[0])
-- pixel_num = int(frame_aspect[0])*int(size[1])
--
-- divisor = gcd(pixel_num, pixel_den)
-- if divisor > 1:
-- pixel_num = pixel_num/divisor
-- pixel_den = pixel_den/divisor
-- pixel_aspect = (pixel_num, pixel_den)
-- return pixel_aspect
--
--
--def run(command):
-- """
-- Run a shell command
-- """
--
-- if verbose:
-- print 'Running: \n' + command + '\n=== ... ==='
-- std = ''
-- else:
-- std = ' > /dev/null 2>&1'
--
-- os.system(command + std)
--
--
--def do_enhance():
-- """
-- Image cleanup/crop/resize routine. Generic, but seems to work
-- well with anime :)
-- """
--
-- if not quiet:
-- print 'Enhancing images... please wait, this might take long...'
--
-- enh_opts = "-enhance -sharpen '0.0x0.5' -gamma 1.2 -contrast -depth 8"
--
-- if cgeom:
-- docrop = ' '.join(['-crop', "'%s!'" % cgeom])
-- else:
-- docrop = ''
--
-- iframe = first_num
-- while True:
-- # File names are padded with zeroes to 8 characters
-- # (not counting the .ext).
-- frame = str(iframe).zfill(8)
-- fname = os.path.join(img_dir, frame + ext)
-- if not os.path.isfile(fname) or (iframe == last_num + 1):
-- break
-- eimg_fname = os.path.join(work_dir, 'eimg' + frame + '.png')
-- rimg_fname = os.path.join(work_dir, 'rimg' + frame + '.png')
-- command = ' '.join([convert, docrop, enh_opts, fname, eimg_fname])
-- run(command)
-- if rgeom:
-- if os.path.exists(rimg_fname): os.remove(rimg_fname)
-- shrink = ' '.join([convert, '-resize', "'%s!'" % rgeom, '-depth 8'])
-- command = ' '.join([shrink, eimg_fname, rimg_fname])
-- run(command)
-- else:
-- if os.path.exists(rimg_fname): os.remove(rimg_fname)
-- try:
-- os.symlink(eimg_fname, rimg_fname)
-- except (IOError, OSError):
-- shutil.copy(eimg_fname, rimg_fname)
-- iframe+=1
--
--
--def do_encode():
-- """
-- Encode a series of images into a Theora movie.
-- """
--
-- if verbose:
-- std = ''
-- std2 = ''
-- be_verbose = '-verbose'
-- else:
-- std = ' > /dev/null 2>&1'
-- std2 = ' 2> /dev/null'
-- be_verbose = ''
--
-- if which(theora_encoder2) != '':
-- theora_encoder = theora_encoder2
--
-- fpsnum = fps.split('/')[0]
-- fpsden = fps.split('/')[1]
-- mplayer_opts = '-mf type=%s:fps=%s ' % (ext[1:],
-- eval('float('+fpsnum+')/'+fpsden)) + \
-- '-vf hqdn3d=2:1:3,pp=va:128:8/ha:128:8/dr,dsize=%s -vo yuv4mpeg -ao null -nosound' % aspect
--
-- if img_dir != work_dir and not enhance:
-- source_dir = img_dir
-- else:
-- source_dir = work_dir
--
-- fgeom = os.popen(' '.join([identify, '-format "%w %h"', \
-- os.path.join(source_dir, \
-- img_pre + \
-- first_frame_num + \
-- ext)])).read().strip().split()
--
-- par = frame2pixel_aspect(fgeom, aspect.split(':'))
-- theora_opts = '-s %s -S %s -f %s -F %s' % (par[0], par[1], fpsnum, fpsden)
-- if vtype == 'hi':
-- theora_opts = ' '.join([theora_opts, '-v 10 -a 10'])
-- elif vtype == 'mh':
-- theora_opts = ' '.join([theora_opts, '-v 8 -a 6'])
-- elif vtype == 'ml':
-- theora_opts = ' '.join([theora_opts, '-v 6 -a 4'])
-- elif vtype == 'lo':
-- theora_opts = ' '.join([theora_opts, '-v 4 -a 2'])
--
-- if frame_range:
-- numframes = str(last_num - first_num + 1)
-- frame_list = [img_pre + str(f).zfill(8) + ext \
-- for f in range(first_num, last_num + 1)]
-- syml = 'temporary_symlink_'
-- for iframe in frame_list:
-- frfile = os.path.join(source_dir, iframe)
-- frlink = os.path.join(source_dir, syml + iframe)
-- if os.path.islink(frlink): os.remove(frlink)
-- os.symlink(frfile, frlink)
-- else:
-- syml = ''
-- numframes = len(glob.glob(os.path.join(source_dir, \
-- img_pre + '*' + ext)))
--
-- if audio:
-- if rawsndf:
-- wav = tempfile.mkstemp('.wav', '', work_dir)[1]
-- sox_opts = '-t raw -r %s -w -c 2 -s' % sndr
-- command = ' '.join([sox, sox_opts, sndf, wav])
-- run(command)
-- else:
-- wav = sndf
-- else:
-- wav = ''
--
-- all_vars = {}
-- all_vars.update(globals())
-- all_vars.update(locals())
--
-- if not quiet:
-- print 'Creating "%s"-quality Theora file' % vtype
--
-- # mplayer with "-vo yuv4mpeg" always outputs to "stream.yuv"
-- # maybe create the pipe pythonically?
-- command = """cd %(source_dir)s ; \\
--mkfifo -m 0600 stream.yuv ; \\
--%(mplayer)s mf://%(syml)s%(img_pre)s*%(ext)s %(mplayer_opts)s %(std)s &
--""" % all_vars
-- run(command)
-- command = """cd %(source_dir)s ; \\
--%(theora_encoder)s %(theora_opts)s -o "%(vidname)s" %(wav)s stream.yuv %(std)s
--""" % all_vars
-- run(command)
--
-- if os.path.exists(os.path.join(source_dir, 'stream.yuv')):
-- os.remove(os.path.join(source_dir, 'stream.yuv'))
--
-- if rawsndf and os.path.exists(wav): os.remove(wav)
--
-- if frame_range:
-- lframes = os.path.join(source_dir, syml)
-- for frame in glob.glob(lframes + '*'):
-- os.remove(frame)
--
--
--def do_clean():
-- """
-- Delete enhanced files
-- """
--
-- if not quiet:
-- print 'Deleting all enhanced images (if any)'
--
-- eframes = os.path.join(work_dir, 'eimg')
-- rframes = os.path.join(work_dir, 'rimg')
-- for frame in glob.glob(eframes + '*'):
-- os.remove(frame)
-- for frame in glob.glob(rframes + '*'):
-- os.remove(frame)
--
--
--def which(command):
-- """
-- Finds (or not) a command a la "which"
-- """
--
-- command_found = False
--
-- if command[0] == '/':
-- if os.path.isfile(command) and \
-- os.access(command, os.X_OK):
-- command_found = True
-- abs_command = command
-- else:
-- path = os.environ.get('PATH', '').split(os.pathsep)
-- for dir in path:
-- abs_command = os.path.join(dir, command)
-- if os.path.isfile(abs_command) and \
-- os.access(abs_command, os.X_OK):
-- command_found = True
-- break
--
-- if not command_found:
-- abs_command = ''
--
-- return abs_command
--
--
--def is_installed(prog):
-- """
-- See whether "prog" is installed
-- """
--
-- wprog = which(prog)
--
-- if wprog == '':
-- if prog == theora_encoder:
-- if which(theora_encoder2) == '':
-- print theora_encoder + ' or ' + theora_encoder2 + ': command not found'
-- raise SystemExit
-- else:
-- if prog != theora_encoder2:
-- print prog + ': command not found'
-- raise SystemExit
--
-- else:
-- if verbose:
-- print wprog + ': found'
--
--
--if __name__ == '__main__':
--
-- import os
-- import sys
-- import getopt
-- import shutil
-- import tempfile
-- import glob
-- import tarfile
--
-- try:
-- if sys.version_info[0:3] < (2, 3, 0):
-- raise SystemExit
-- except:
-- print 'You need Python 2.3.0 or greater to run me!'
-- raise SystemExit
--
-- try:
-- (opts, args) = getopt.getopt(sys.argv[1:], \
-- 'ho:p:d:w:a:qvt:ekc:r:s:b:f:VCD:L:')
-- except:
-- print "Something's wrong. Try the '-h' flag."
-- raise SystemExit
--
-- opts = dict(opts)
--
-- if not opts and not args:
-- print usage
-- raise SystemExit
--
-- if '-h' in opts:
-- print usage + help
-- raise SystemExit
--
-- if '-V' in opts:
-- print 'theora_encoder.py version ' + version
-- raise SystemExit
--
-- if ('-v' in opts) or ('-C' in opts):
-- verbose = True
-- else:
-- verbose = False
--
-- if '-q' in opts:
-- quiet = True
-- verbose = False
-- else:
-- quiet = False
--
-- for i in [mplayer, theora_encoder, theora_encoder2, sox, convert, identify]:
-- is_installed(i)
-- if '-C' in opts: raise SystemExit
--
-- img_pre = opts.get('-p', '')
--
-- if img_pre not in ['', 'eimg', 'rimg']:
-- print 'Improper image name prefix.'
-- raise SystemExit
--
-- temp_dir = ''
-- img_dir = opts.get('-d', '.')
-- img_dir = os.path.abspath(img_dir)
-- if ' ' in img_dir:
-- temp_dir = tempfile.mkdtemp('', '.lives-', '/tmp/')
-- os.symlink(img_dir, temp_dir + '/img_dir')
-- img_dir = temp_dir + '/img_dir'
--
-- if not os.path.isdir(img_dir):
-- print 'The image source directory: ' + img_dir + \
-- ' does not exist!'
-- raise SystemExit
--
-- if len(args) not in [0, 2]:
-- print 'If frames are specified both first and last ' + \
-- 'image numbers must be chosen.'
-- raise SystemExit
-- elif len(args) == 0:
-- args = [None, None]
--
-- frame_range = False
-- if not args[0]:
-- first_frame_num = '1'
-- else:
-- frame_range = True
-- first_frame_num = args[0]
-- first_frame_num = first_frame_num.zfill(8)
-- first_num = int(first_frame_num)
--
-- if not args[1]:
-- last_frame_num = '99999999'
-- else:
-- last_frame_num = args[1]
-- last_frame_num = last_frame_num.zfill(8)
-- last_num = int(last_frame_num)
--
-- aspectc = opts.get('-a', '2')
--
-- if aspectc not in [str(i) for i in xrange(1,5)]:
-- print 'Invalid aspect ratio.'
-- raise SystemExit
-- else:
-- if aspectc == '1': aspect = '1:1'
-- elif aspectc == '2': aspect = '4:3'
-- elif aspectc == '3': aspect = '16:9'
-- elif aspectc == '4': aspect = '221:100'
--
-- vtype = opts.get('-t', 'ml')
--
-- if vtype not in ['hi', 'mh', 'ml', 'lo']:
-- print 'Invalid video type.'
-- raise SystemExit
--
-- out_ogg = opts.get('-o', vtype + '_movie.ogg')
--
-- fpsc = opts.get('-f', '4')
--
-- if fpsc not in [str(i) for i in xrange(1,9)]:
-- if not quiet: print 'Invalid fps code, attempting float fps.'
-- foundfps = False
-- else:
-- if fpsc == '1': fps = '24000/1001'
-- elif fpsc == '2': fps = '24/1'
-- elif fpsc == '3': fps = '25/1'
-- elif fpsc == '4': fps = '30000/1001'
-- elif fpsc == '5': fps = '30/1'
-- elif fpsc == '6': fps = '50/1'
-- elif fpsc == '7': fps = '60000/1001'
-- elif fpsc == '8': fps = '60/1'
-- foundfps = True
--
-- if not foundfps:
-- try:
-- fpsnum = int(locale.atof(fpsc)*10**15)
-- fpsden = 10**15
-- divisor = gcd(fpsnum, fpsden)
-- if divisor > 1:
-- fpsnum = fpsnum/divisor
-- fpsden = fpsden/divisor
-- fps = '%s/%s' % (fpsnum, fpsden)
-- if not quiet: print 'Using fps = ' + fps
-- if fpsnum > 0: foundfps = True
-- except:
-- pass
--
-- if not foundfps:
-- print 'Invalid fps code or rate.'
-- raise SystemExit
--
-- if '-e' not in opts:
-- enhance = False
-- else:
-- enhance = True
--
-- if enhance and img_pre:
-- print 'Sorry, you cannot enhance already-enhanced images'
-- raise SystemExit
--
-- if '-k' not in opts:
-- keep = False
-- else:
-- keep = True
--
-- cgeom = opts.get('-c', '')
-- rgeom = opts.get('-r', '')
--
-- if (cgeom or rgeom) and not enhance:
-- print 'Missing "-e" option.'
-- raise SystemExit
--
-- delay = opts.get('-D', '0')
-- if verbose: print 'Linear audio delay (ms): ' + delay
--
-- lv1file = opts.get('-L', None)
-- if lv1file:
-- if not quiet: print 'Opening lv1 file...'
-- try:
-- lv1 = tarfile.open(os.path.abspath(lv1file))
-- except:
-- print 'This does not appear to be a valid LiVES file!'
-- raise SystemExit
-- if 'header.tar' not in lv1.getnames():
-- print 'This does not appear to be a valid LiVES file!'
-- raise SystemExit
-- for tfile in lv1.getmembers():
-- lv1.extract(tfile, img_dir)
-- for tfile in glob.glob(os.path.join(img_dir, '*.tar')):
-- imgtar = tarfile.open(tfile)
-- for img in imgtar.getmembers():
-- imgtar.extract(img, img_dir)
-- os.remove(tfile)
--
-- test_file = os.path.join(img_dir, img_pre + first_frame_num)
-- if os.path.isfile(test_file + '.jpg'):
-- ext = '.jpg'
-- elif os.path.isfile(test_file + '.png'):
-- ext = '.png'
-- else:
-- print 'Cannot find any appropriate %s or %s files!' % ('.jpg','.png')
-- raise SystemExit
-- first_frame = test_file + ext
-- geom = os.popen(identify + ' -format "%w %h" ' + first_frame).read().strip().split()
-- last_frame = os.path.join(img_dir, img_pre + last_frame_num + ext)
--
-- if not quiet: print 'Found: ' + first_frame + ' (%sx%s)' % (geom[0], geom[1])
--
-- work_dir = opts.get('-w', img_dir)
-- work_dir = os.path.abspath(work_dir)
-- if not os.path.isdir(work_dir):
-- if not quiet: print 'Creating ' + work_dir
-- try:
-- os.makedirs(work_dir)
-- os.chmod(work_dir, 0755)
-- except:
-- print 'Could not create the work directory ' + \
-- work_dir
-- raise SystemExit
-- if ' ' in work_dir:
-- if temp_dir == '':
-- temp_dir = tempfile.mkdtemp('', '.lives-', '/tmp/')
-- os.symlink(work_dir, temp_dir + '/work_dir')
-- work_dir = temp_dir + '/work_dir'
--
-- sndf = opts.get('-s', os.path.join(img_dir, 'audio'))
--# sndf = os.path.abspath(sndf)
-- rawsndf = True
-- if not os.path.isfile(sndf):
-- audio = False
-- rawsndf = False
-- else:
-- audio = True
-- if sndf[-4:] == '.wav':
-- rawsndf = False
-- if not quiet: print 'Found audio file: ' + sndf
--
-- sndr = opts.get('-b', '44100')
--
-- if enhance:
-- do_enhance()
-- # Note that do_enhance() always creates images prefixed
-- # with 'rimg'. What's important to note if that if the
-- # images are resized the 'rimg' are indeed resized, but
-- # if not the 'rimg' are simply symlinks to the 'eimg'
-- # (enhanced) images.
-- img_pre = 'rimg'
-- ext = '.png'
-- vidname = os.path.join(work_dir, out_ogg)
-- # do_encode() acts on images prefixed by img_pre.
-- do_encode()
-- if not keep:
-- do_clean()
-- if temp_dir != '':
-- shutil.rmtree(temp_dir)
-- if not quiet: print "Done!"
--
--
--"""
--CHANGELOG:
--
--25 Sep 2004 : 0.0.1 : first release.
--01 Oct 2004 : 0.0.2 : made all fps fractions.
--13 Oct 2004 : 0.0.3 : fix aspect ratio by using
-- pixel aspect ratio instead of
-- frame aspect ratio (j at v2v.cc).
-- calculate frame size to do the above.
-- fixed extension from ".ogv" to ".ogg".
--14 Oct 2004 : 0.0.4 : "size" is (width, height) (original
-- patch had assumed it switched).
--26 Oct 2004 : 0.0.5 : can handle arbitrary fps values.
--02 Nov 2004 : 0.0.6 : tweaked encoding quality levels.
--08 Nov 2004 : 0.0.7 : make sure that the enhanced
-- color depth is 8-bits/channel.
-- tweaked encoding quality levels.
--02 Jan 2005 : 0.0.8 : updated docs.
-- added sound rate (-b) option.
--22 Jan 2005 : 0.0.9 : fixed stream.yuv fps calculation.
--11 Feb 2005 : 0.1.0 : fixed aspect ratio error (my bad :( )
--26 Mar 2005 : 0.1.1 : use env python (hopefully >= 2.3).
-- replace denoise3d with hqdn3d.
--24 Aug 2005 : 0.1.2 : fine-tune mplayer filters (thanks to
-- zikzak at tele2.fr).
-- Fixed 2.21:1 aspect ratio.
--09 Mar 2006 : 0.1.3 : added '-depth 8' to resize, as ImageMagick
-- keeps changing its damn behaviour.
--02 Apr 2006 : 0.1.4 : small aspect ratio bug fixed.
-- tweaked audio quality settings.
--28 Jun 2007 : 0.1.5 : handles paths with spaces appropriately
-- (thanks Gabriel).
--"""
--- lives.orig/lives-plugins/plugins/encoders/multi_encoder
+++ lives/lives-plugins/plugins/encoders/multi_encoder
@@ -10,14 +10,14 @@ multi_encoder
diff --git a/debian/rules b/debian/rules
index 4b78134..25394fe 100755
--- a/debian/rules
+++ b/debian/rules
@@ -2,5 +2,16 @@
LDFLAGS:=
CFLAGS:=
+override_dh_auto_configure:
+ mv lives-plugins/marcos-plugins/avi_encoder.py lives-plugins/marcos-plugins/avi_encoder
+ mv lives-plugins/marcos-plugins/dirac_encoder.py lives-plugins/marcos-plugins/lives_dirac_encoder
+ mv lives-plugins/marcos-plugins/gif_encoder.py lives-plugins/marcos-plugins/gif_encoder
+ mv lives-plugins/marcos-plugins/mkv_encoder.py lives-plugins/marcos-plugins/mkv_encoder
+ mv lives-plugins/marcos-plugins/mng_encoder.py lives-plugins/marcos-plugins/mng_encoder
+ mv lives-plugins/marcos-plugins/mpeg_encoder.py lives-plugins/marcos-plugins/mpeg_encoder
+ mv lives-plugins/marcos-plugins/ogm_encoder.py lives-plugins/marcos-plugins/ogm_encoder
+ mv lives-plugins/marcos-plugins/theora_encoder.py lives-plugins/marcos-plugins/theora_encoder
+ dh_auto_configure
+
%:
dh --with quilt $@
--
lives packaging
More information about the pkg-multimedia-commits
mailing list