CIS FFmpeg API implemented
[living-lab-site.git] / cis / api / ffmpeg.py
1 #!/usr/bin/env python
2
3 """
4 Classes derived from BaseTranscoder and BaseThumbExtractor for transcoding of
5 videos and thumbnail extraction from videos using FFmpeg CLI program.
6 """
7
8 import base
9 import cis_exceptions
10 import subprocess
11 import os
12
13 class FFmpegTranscoder(base.BaseTranscoder):
14     """
15     FFmpeg CLI API for video transcoding.
16     """
17
18     prog_bin = "ffmpeg"
19
20     log_file = 'log/ffmpeg.log'
21
22     containers = {
23         "avi": "avi",
24         "flv": "flv",
25         "mp4": "mp4",
26         "ogg": "ogg",
27         "webm": "webm",
28         "mpegts": "mpegts"
29     }
30     a_codecs = {
31         "mp3": "libmp3lame",
32         "vorbis": "libvorbis"
33     }
34     v_codecs = {
35         "h264": "libx264",
36         "theora": "libtheora",
37         "vp8": "libvpx"
38     }
39
40     def _transcode(self, container, a_codec=None, v_codec=None,
41             a_bitrate=None, a_samplingrate=None, a_channels=None,
42             v_bitrate=None, v_framerate=None, v_resolution=None, v_dar=None):
43
44         args = self.prog_bin + ' -i "' + self.input_file + '" -f ' + container
45         
46         # Audio
47         if a_codec != None:
48             args += ' -acodec ' + a_codec
49             if a_bitrate != None:
50                 args += ' -ab ' + str(a_bitrate)
51             if a_samplingrate != None:
52                 args += ' -ar ' + str(a_samplingrate)
53             if a_channels != None:
54                 args += ' -ac ' + str(a_channels)
55         
56         # Video
57         if v_codec != None:
58             args += ' -vcodec ' + v_codec
59             # Video codec specific options.
60             if v_codec == 'libx264':
61                 args += ' -vpre normal'
62             if v_bitrate != None:
63                 args += ' -b ' + str(v_bitrate)
64             if v_framerate != None:
65                 args += ' -r ' + str(v_framerate)
66             if v_resolution != None:
67                 args += ' -s ' + v_resolution
68             if v_dar != None:
69                 args += ' -aspect ' + v_dar
70         
71         # Output file.
72         args += ' "' + self.output_file + '"'
73         try:
74             os.unlink(self.output_file)
75         except OSError:
76             pass
77             
78         # READ handler for process's output.
79         p = subprocess.Popen(args, shell=True, 
80                 stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
81         pipe = p.stdout
82
83         # WRITE handler for logging.
84         log = open(self.log_file, 'w')
85
86         while True:
87             line = pipe.readline()
88             if len(line) == 0:
89                 break
90             log.write(line)
91
92         if p.poll() > 0:
93             raise cis_exceptions.TranscodingException
94
95         log.close()