From: yomguy Date: Fri, 5 Oct 2012 22:36:07 +0000 (+0200) Subject: keep old encoder subprocess X-Git-Tag: 0.4.2~26 X-Git-Url: https://git.parisson.com/?a=commitdiff_plain;h=88a5f0ebe106b604bf40957f0ffffac8e0d5cb0d;p=timeside.git keep old encoder subprocess --- diff --git a/timeside/encoder/subprocess.py b/timeside/encoder/subprocess.py new file mode 100644 index 0000000..0260fe1 --- /dev/null +++ b/timeside/encoder/subprocess.py @@ -0,0 +1,188 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# +# Copyright (c) 2007-2009 Guillaume Pellerin + +# This file is part of TimeSide. + +# TimeSide is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. + +# TimeSide is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with TimeSide. If not, see . + +# Author: Guillaume Pellerin + +from timeside.core import * +import subprocess + +class SubProcessPipe(object): + """Read media and stream data through a generator. + Taken from Telemeta (see http://telemeta.org)""" + + def __init__(self, command, stdin=None): + self.buffer_size = 0xFFFF + if not stdin: + stdin = subprocess.PIPE + + self.proc = subprocess.Popen(command.encode('utf-8'), + shell = True, + bufsize = self.buffer_size, + stdin = stdin, + stdout = subprocess.PIPE, + close_fds = True) + + self.input = self.proc.stdin + self.output = self.proc.stdout + + +class EncoderSubProcessCore(Processor): + """Defines the main parts of the encoding tools : + paths, metadata parsing, data streaming thru system command""" + + def core_process(self, command, stdin): + """Encode and stream audio data through a generator""" + + proc = SubProcessPipe(command, stdin) + + while True: + __chunk = proc.output.read(proc.buffer_size) + #status = proc.poll() + #if status != None and status != 0: + #raise EncodeProcessError('Command failure:', command, proc) + if len(__chunk) == 0: + break + yield __chunk + + +class Mp3EncoderSubprocess(object): + """MP3 encoder in a subprocess pipe""" + +# implements(IEncoder) + + def __init__(self): + import os + import string + import subprocess + self.bitrate_default = '192' + self.dub2id3_dict = {'title': 'TIT2', #title2 + 'creator': 'TCOM', #composer + 'creator': 'TPE1', #lead + 'identifier': 'UFID', #Unique ID... + 'identifier': 'TALB', #album + 'type': 'TCON', #genre + 'publisher': 'TPUB', #comment + #'date': 'TYER', #year + } + self.dub2args_dict = {'title': 'tt', #title2 + 'creator': 'ta', #composerS + 'relation': 'tl', #album + #'type': 'tg', #genre + 'publisher': 'tc', #comment + 'date': 'ty', #year + } + + @interfacedoc + def setup(self, channels=None, samplerate=None, nframes=None): + self.channels = channels + super(Mp3EncoderSubprocess, self).setup(channels, samplerate, nframes) + + @staticmethod + @interfacedoc + def id(): + return "subprocess_mp3_enc" + + @staticmethod + @interfacedoc + def description(): + return "MP3 subprocess based encoder" + + @staticmethod + @interfacedoc + def format(): + return "MP3" + + @staticmethod + @interfacedoc + def file_extension(): + return "mp3" + + @staticmethod + @interfacedoc + def mime_type(): + return "audio/mpeg" + + @interfacedoc + def set_metadata(self, metadata): + self.metadata = metadata + + def get_file_info(self): + try: + file_out1, file_out2 = os.popen4('mp3info "'+self.dest+'"') + info = [] + for line in file_out2.readlines(): + info.append(clean_word(line[:-1])) + self.info = info + return self.info + except: + raise IOError('EncoderError: file does not exist.') + + def write_tags(self): + """Write all ID3v2.4 tags by mapping dub2id3_dict dictionnary with the + respect of mutagen classes and methods""" + from mutagen import id3 + id3 = id3.ID3(self.dest) + for tag in self.metadata.keys(): + if tag in self.dub2id3_dict.keys(): + frame_text = self.dub2id3_dict[tag] + value = self.metadata[tag] + frame = mutagen.id3.Frames[frame_text](3,value) + try: + id3.add(frame) + except: + raise IOError('EncoderError: cannot tag "'+tag+'"') + try: + id3.save() + except: + raise IOError('EncoderError: cannot write tags') + + def get_args(self): + """Get process options and return arguments for the encoder""" + args = [] + if not self.options is None: + if not ( 'verbose' in self.options and self.options['verbose'] != '0' ): + args.append('-S') + if 'mp3_bitrate' in self.options: + args.append('-b ' + self.options['mp3_bitrate']) + else: + args.append('-b '+self.bitrate_default) + #Copyrights, etc.. + args.append('-c -o') + else: + args.append('-S -c --tt "unknown" -o') + + for tag in self.metadata: + name = tag[0] + value = clean_word(tag[1]) + if name in self.dub2args_dict.keys(): + arg = self.dub2args_dict[name] + args.append('--' + arg + ' "' + value + '"') + return args + + def process(self, source, metadata, options=None): + self.metadata = metadata + self.options = options + args = self.get_args() + args = ' '.join(args) + command = 'lame %s - -' % args + + stream = self.core_process(command, source) + for __chunk in stream: + yield __chunk