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
|
import subprocess, tempfile, threading, os
from config import config
decoders = {}
encoders = {}
class DecoderMeta(type):
def __init__(cls, name, bases, dict):
if not name in ('Decoder', 'Codec'):
decoders[cls.decoder_name] = cls
class Decoder(object):
__metaclass__ = DecoderMeta
class EncoderMeta(type):
def __init__(cls, name, bases, dict):
if not name in ('Encoder', 'Codec'):
encoders[cls.encoder_name] = cls
class Encoder(object):
__metaclass__ = EncoderMeta
class CodecMeta(DecoderMeta, EncoderMeta):
def __init__(cls, name, bases, dict):
DecoderMeta.__init__(cls, name, bases, dict)
EncoderMeta.__init__(cls, name, bases, dict)
class Codec(object):
__metaclass__ = CodecMeta
# end of metastuff
class FFmpeg(Decoder):
decoder_name = 'ffmpeg'
def decode(self, source, dest, *args, **kwargs):
cmd = 'ffmpeg -loglevel quiet'.split()
if 'start_time' in kwargs and kwargs['start_time']:
cmd += ['-ss', str(kwargs['start_time'])]
if 'end_time' in kwargs and kwargs['end_time']:
cmd += ['-t', str(kwargs['end_time'] - kwargs['start_time'])]
cmd += ['-i', source, '-y', dest]
p = subprocess.Popen(cmd, stderr = subprocess.PIPE, close_fds = True)
p.stderr.close()
p.wait()
class Ogg(Encoder):
encoder_name = 'ogg'
def encode(self, source, dest, *args, **kwargs):
options = config.get('options', 'encoder/ogg', '')
cmd = ['oggenc', '-Q'] + options.split() + [source, '-o', dest]
subprocess.call(cmd)
class Recoder(object):
def __init__(self, decoder, encoder):
self.decoder = decoder
self.encoder = encoder
def recode(self, source, dest, **kwargs):
if self.decoder.__class__ == self.encoder.__class__ and hasattr(self.decoder, 'recode'):
self.decoder.recode(source, dest)
else:
with tempfile.NamedTemporaryFile(mode = 'wb', prefix = 'ongaku-', suffix = '.wav', delete = True) as temp:
self.decoder.decode(source, temp.name, **kwargs)
self.encoder.encode(temp.name, dest, **kwargs)
class RecodeThread(threading.Thread):
lock = threading.Lock()
queue = []
running = False
def get_job(self):
return self.queue.pop(0) if len(self.queue) else None
def run(self):
self.lock.acquire()
job = self.get_job()
while job:
self.lock.release()
func, decoder, encoder, sessionid = job
func(decoder, encoder, sessionid)
self.lock.acquire()
job = self.get_job()
RecodeThread.running = False
self.lock.release()
@classmethod
def add(cls, job):
cls.lock.acquire()
cls.queue.append(job)
if not cls.running:
cls.running = True
RecodeThread().start()
cls.lock.release()
if __name__ == '__main__':
import sys
ffmpeg = FFmpeg()
print ffmpeg
r = Recoder(ffmpeg, ffmpeg)
r.recode(sys.argv[1], sys.argv[2])
|