public
Last active

Convert and video to ipod viewable using ffmpeg capturing the output to a display the encoding progress.

  • Download Gist
to_ipod.py
Python
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
#!/usr/bin/python
 
import fcntl
import optparse
import os
import progressbar
import re
import select
import shlex
import subprocess
import sys
import time
 
class ElapsedWidget(progressbar.ProgressBarWidget):
def update(self, pbar):
return time.strftime('Elapsed: %H:%M:%S', time.gmtime(pbar.seconds_elapsed))
 
class EncodingProgressBar(object):
 
def __init__(self, filename):
self.filename = filename
self.maxval = self.duration
widgets = [
filename[:20], ' ',
progressbar.Percentage(), ' ',
progressbar.Bar(marker=progressbar.RotatingMarker()), ' ',
progressbar.ETA(), ' ', ElapsedWidget(),
]
self.pbar = progressbar.ProgressBar(
widgets=widgets,
maxval=self.maxval,
).start()
 
def update(self, args):
time = float(args['time'])
if time > self.maxval:
time = self.maxval
self.pbar.update(time)
 
@staticmethod
def time_to_secs(duration, total=0):
total = 0
hours, mins, secs = duration.split(':')
total += int(hours) * 3600
total += int(mins) * 60
total += float(secs)
return total
 
@property
def duration(self):
cmd = '/usr/bin/ffmpeg -i "%s"' % (self.filename)
pipe = subprocess.Popen(
shlex.split(cmd),
stderr=subprocess.PIPE,
close_fds=True
)
chunk = pipe.stderr.read()
duration = re.search(r'Duration: (?P<duration>\S+),', chunk)
if duration:
return self.time_to_secs(duration.group('duration'))
return None
 
def encode(filename, callback=None):
 
cmd = 'ffmpeg -i "%s" -acodec libfaac -ab 128kb ' + \
'-vcodec mpeg4 -b 1200kb -mbd 2 -flags +4mv ' + \
'-trellis 2 -cmp 2 -subcmp 2 -s 320x180 "%s.mp4"'
pipe = subprocess.Popen(
shlex.split(cmd % (filename, os.path.splitext(filename)[0])),
stderr=subprocess.PIPE,
close_fds=True
)
fcntl.fcntl(
pipe.stderr.fileno(),
fcntl.F_SETFL,
fcntl.fcntl(pipe.stderr.fileno(), fcntl.F_GETFL) | os.O_NONBLOCK,
)
 
# frame= 29 fps= 0 q=2.6 size= 114kB time=0.79 bitrate=1181.0kbits/s
reo = re.compile(r"""\S+\s+(?P<frame>\d+) # frame
\s\S+\s+(?P<fps>\d+) # fps
\sq=(?P<q>\S+) # q
\s\S+\s+(?P<size>\S+) # size
\stime=(?P<time>\S+) # time
\sbitrate=(?P<bitrate>[\d\.]+) # bitrate
""", re.X)
while True:
readx = select.select([pipe.stderr.fileno()], [], [])[0]
if readx:
chunk = pipe.stderr.read()
if chunk == '':
break
 
m = reo.match(chunk)
if m and callback:
callback(m.groupdict())
time.sleep(.1)
 
if __name__ == '__main__':
 
parser = optparse.OptionParser()
(options, args) = parser.parse_args()
 
for arg in args:
root, ext = os.path.splitext(arg)
if os.path.exists(root + '.mp4'):
val = raw_input('File exists. Overwrite [N/y]: ')
if val != 'y':
sys.exit(1)
os.unlink(root + '.mp4')
pbar = EncodingProgressBar(arg)
encode(arg, pbar.update)

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.