Movie encoder “daemon”

I sometimes have incoming high-def video in formats that are not directly compatible with AppleTV.  I had been using iFlicks and an El Gato Turbo.264 HD encoder (a USB dongle with H.264 hardware innit), but lately that started producing bad output – I think the hardware was going bad as even the official software had the same results.  It was great while it lasted, it allowed the poor overworked Mac Mini that was doing the encoding to do 720p transcodes faster than real-time.  I should note that iFlicks’ author has actually recommended not using the El Gato thing, he mentions audio sync problems, but I never saw that, just frequent badly encoded video after mine started to go bad.

I’ve now switched back to software encoding using Handbrake.  To that end, I wrote a tiny little daemon that watches for files in one directory, encodes them, then moves them to the folder that iFlicks is watching and trashes the original.  iFlicks will then add meta-data (it searches thetvdb.com based on the file name), and finally send the file off to iTunes (which will then sync it to AppleTV.  WHEW that’s a lot of steps, you see why I need to write myself things to help?)

iFlicks can do software encoding itself, but it just uses Quicktime, which is a whole hell of a lot slower than Handbrake. Handbrake still doesn’t do 720p at real-time on a Mac Mini, but it’s only about half real-time, as opposed to Quicktime, which was taking 4-8 hours to encode an hour of video.

The script also gives me Growl notifications, and I have the Prowl app on my phone, so I get push notifications when encodings start and finish too.

Code after the jump.

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
#!/usr/bin/env python
 
# Normal usage: movieconverter /Users/ogre/HDDownloads
 
HANDBRAKE='/Users/ogre/bin/HandBrakeCLI'
DESTDIR='/Users/ogre/SBDownloads'
TRASH='/Users/ogre/.Trash'
ERRORS='/Users/ogre/Movies/Errors'
 
import sys
import os
import shutil
import time
import glob
 
ENCODING_DONE = 'Encoding Done'
ENCODING_STARTED = 'Encoding Started'
 
try:
    import Growl
    useGrowl = True
    print 'Using growl for notifications'
except:
    print 'NOT using growl for notifications, could not import Growl'
    useGrowl = False
 
if useGrowl:
    growl = Growl.GrowlNotifier(applicationName="Movie Encoder",
                                notifications=[ENCODING_DONE, ENCODING_STARTED])
    growl.register()
 
print 'Watching %s for movies' %( sys.argv[1])
 
while 1:
    files = glob.glob('%s/*.mkv' % (sys.argv[1]))
    for f in files:
        (name,ext) = os.path.splitext(f)
        output = name + '.m4v'
        cmd = '%s -i "%s" -o "%s" --preset=AppleTV' %(HANDBRAKE, f, output)
        print 'Found %s, running %s' % (f, cmd)
        if useGrowl:
            growl.notify(ENCODING_STARTED, ENCODING_STARTED,
                         'Starting encode: %s => %s' % (f, output))
        result = os.system(cmd)
        if result == 0:
            print 'Handbrake complete, moving %s to %s' % (output, DESTDIR)
            # iFlicks gets stuck when moving the file this way??
            #shutil.move(output, DESTDIR)
            os.system('mv "%s" "%s/"' % (output, DESTDIR))
            print 'Moving %s to trash' % (f)
            shutil.move(f, TRASH)
            if useGrowl:
                growl.notify(ENCODING_DONE, ENCODING_DONE,
                             'Finished encoding %s => %s' % (f, output))
        else:
            print 'Handbrake returned error code %d, moving file %s to %s' % (result)
            shutil.move(f, ERRORS)
 
    time.sleep(10)

1 Comment »

  1. Chuck Stehlin Said,

    October 17, 2013 @ 2:25 pm

    I love the valuable data you offer in your articles. I am going to bookmark your blog post and look again here often. I will be really certain I am going to understand a lot of new stuff the following! Best of luck for the next!

RSS feed for comments on this post · TrackBack URI

Leave a Comment