ffmpeg target file sizes (again)

As a bit of a revision to a previous entry, I have converted the combination bash/python scripts I gave earlier into a single large python script.

This can now be used without editing any files to set sizes. An example of use is:
$ ./enc.py -s 700 -a 192 -o '-deinterlace' da_*.VOB
All of these flags are optional except the file list, where at least 1 file must be specified.

enc.tar.gz:

#!/usr/bin/python
 
from getopt import getopt, GetoptError
from sys import argv, exit
from subprocess import Popen, PIPE
from re import search
 
def secs(h, m, s):
  return (((h*60)+m)*60)+s
 
def calc_video_bitrate(target_bytes, ab, time):
  audio_bytes = (ab * 1000 / 8) * time
  return (target_bytes - audio_bytes) / time * 8
 
def get_duration(file):
  ffmpeg = Popen(("ffmpeg", "-i", file), stderr=PIPE)
  match = search("(\\d+):(\\d+):(\\d+)\\.\\d+", ffmpeg.communicate()[1])
  ffmpeg.stderr.close()
 
  if match == None: return 0
  dur = match.groups()
  return secs(int(dur[0]), int(dur[1]), int(dur[2]))
 
def encode(source, dest, opts, vbr, abr=128):
  command1 = "ffmpeg -i %s -pass 1 -an -vcodec libx264 -vpre fastfirstpass -b %d -bt %d -threads 0 %s -y pass1.mp4" % (source, vbr, vbr, opts)
  command2 = "ffmpeg -i %s -pass 2 -acodec libfaac -ac 2 -ab %dk -vcodec libx264 -vpre hq -b %d -bt %d -threads 0 %s -y %s" % (source, abr, vbr, vbr, opts, dest)
 
  pass1 = Popen(command1.split())
  pass1.wait()
 
  pass2 = Popen(command2.split())
  pass2.wait()
 
 
target_size = 350 #MiB
ab = 128 #kbps
extra_options = ""
 
# Parse args
try:
  opts, args = getopt(argv[1:], "s:a:o:", ["size=", "ab=", "opts="])
except GetoptError, err:
  print str(err)
  exit(2)
 
for o, a in opts:
  if o in ("-s", "--size"):
    target_size = int(a) * 1024 * 1024
  elif o in ("-a", "--ab"):
    ab = int(a)
  elif o in ("-o", "--opts"):
    extra_options = a
 
if len(args) < 1:
  print "Usage: " + argv[0] + \
    " [-s <size (MiB)>] [-a <audio bit rate (kbps)>] [-o <additional options>] <file list>"
  exit(2)
 
# Loop through files
for file in args:
  duration = get_duration(file)
  if duration <= 0:
    print "Unable to get length of", file
    continue
 
  bitrate = calc_video_bitrate(target_size, ab, duration)
 
  encode(file, file + ".mp4", extra_options, bitrate, ab)

Tags: ,

Leave a Reply