From f761f43c0f755b0c755842ddebf44300255fd96b Mon Sep 17 00:00:00 2001 From: yomguy Date: Sat, 6 Oct 2012 14:37:38 +0200 Subject: [PATCH] rm duration since value is available through decoder.setup, cleanup --- setup.py | 2 +- timeside/analyzer/__init__.py | 2 +- timeside/analyzer/duration.py | 61 --------------- timeside/api.py | 2 +- timeside/core.py | 8 +- timeside/encoder/core.py | 40 ---------- timeside/encoder/mp3.py | 131 ++------------------------------- timeside/encoder/subprocess.py | 1 + 8 files changed, 15 insertions(+), 232 deletions(-) delete mode 100644 timeside/analyzer/duration.py diff --git a/setup.py b/setup.py index 41e3f8b..603205c 100644 --- a/setup.py +++ b/setup.py @@ -21,7 +21,7 @@ setup( long_description = open('README.rst').read(), author = ["Guillaume Pellerin", "Olivier Guilyardi", "Riccardo Zaccarelli", "Paul Brossier"], author_email = ["yomguy@parisson.com","olivier@samalyse.com", "riccardo.zaccarelli@gmail.com", "piem@piem.org"], - version = '0.4.1', + version = '0.4.2', install_requires = [ 'setuptools', 'numpy', diff --git a/timeside/analyzer/__init__.py b/timeside/analyzer/__init__.py index 02c0119..0d05ae7 100644 --- a/timeside/analyzer/__init__.py +++ b/timeside/analyzer/__init__.py @@ -3,5 +3,5 @@ from max_level import * from mean_level import * from dc import * -#from duration import * + diff --git a/timeside/analyzer/duration.py b/timeside/analyzer/duration.py deleted file mode 100644 index 89d2cf6..0000000 --- a/timeside/analyzer/duration.py +++ /dev/null @@ -1,61 +0,0 @@ -# -*- 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 Processor, implements, interfacedoc, FixedSizeInputAdapter -from timeside.analyzer.core import * -from timeside.api import IValueAnalyzer - - -class Duration(Processor): - """A rather useless duration analyzer. Its only purpose is to test the - nframes characteristic.""" - implements(IValueAnalyzer) - - @interfacedoc - def setup(self, channels, samplerate, blocksize=None, totalframes=None): - super(Duration, self).setup(channels, samplerate, blocksize, totalframes) - if not totalframes: - raise Exception("nframes argument required") - - @staticmethod - @interfacedoc - def id(): - return "duration" - - @staticmethod - @interfacedoc - def name(): - return "Duration" - - @staticmethod - @interfacedoc - def unit(): - return "seconds" - - def __str__(self): - return "%s %s" % (str(self.value), unit()) - - def process(self, frames, eod=False): - return frames, eod - - def result(self): - return self.input_nframes / float(self.input_samplerate) - diff --git a/timeside/api.py b/timeside/api.py index ab877e2..9832360 100644 --- a/timeside/api.py +++ b/timeside/api.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # -# Copyright (C) 2007-2009 Parisson +# Copyright (C) 2007-2012 Parisson SARL # Copyright (c) 2007 Olivier Guilyardi # Copyright (c) 2007-2009 Guillaume Pellerin # diff --git a/timeside/core.py b/timeside/core.py index b0040dd..2e1f496 100644 --- a/timeside/core.py +++ b/timeside/core.py @@ -30,6 +30,7 @@ __all__ = ['Processor', 'MetaProcessor', 'implements', 'abstract', _processors = {} + class MetaProcessor(MetaComponent): """Metaclass of the Processor class, used mainly for ensuring that processor id's are wellformed and unique""" @@ -51,6 +52,7 @@ class MetaProcessor(MetaComponent): return new_class + class Processor(Component): """Base component class of all processors""" __metaclass__ = MetaProcessor @@ -98,6 +100,7 @@ class Processor(Component): def __or__(self, other): return ProcessPipe(self, other) + class FixedSizeInputAdapter(object): """Utility to make it easier to write processors which require fixed-sized input buffers.""" @@ -174,6 +177,7 @@ def get_processor(processor_id): return _processors[processor_id] + class ProcessPipe(object): """Handle a pipe of processors""" @@ -206,13 +210,13 @@ class ProcessPipe(object): source = self.processors[0] items = self.processors[1:] - - # setup/reset processors and configure channels and samplerate throughout the pipe source.setup() + #FIXME: wait for decoder mainloop time.sleep(0.1) last = source + # setup/reset processors and configure properties throughout the pipe for item in items: item.setup(channels = last.channels(), samplerate = last.samplerate(), diff --git a/timeside/encoder/core.py b/timeside/encoder/core.py index dc2d68c..1703aa7 100644 --- a/timeside/encoder/core.py +++ b/timeside/encoder/core.py @@ -74,43 +74,3 @@ class GstEncoder(Processor): self.chunk = self.app.emit('pull-buffer') return frames, eod -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 diff --git a/timeside/encoder/mp3.py b/timeside/encoder/mp3.py index d549ee8..2c44b09 100644 --- a/timeside/encoder/mp3.py +++ b/timeside/encoder/mp3.py @@ -1,7 +1,10 @@ # -*- coding: utf-8 -*- # -# Copyright (C) 2007 Parisson SARL -# Copyright (c) 2006-2007 Guillaume Pellerin +# Copyright (C) 2007-2012 Parisson SARL +# Copyright (c) 2006-2012 Guillaume Pellerin +# Copyright (c) 2010-2012 Paul Brossier +# Copyright (c) 2009-2010 Olivier Guilyardi + # This file is part of TimeSide. @@ -110,127 +113,3 @@ class Mp3Encoder(GstEncoder): except: raise IOError('EncoderError: cannot write tags') -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 diff --git a/timeside/encoder/subprocess.py b/timeside/encoder/subprocess.py index 0260fe1..de6c709 100644 --- a/timeside/encoder/subprocess.py +++ b/timeside/encoder/subprocess.py @@ -23,6 +23,7 @@ from timeside.core import * import subprocess + class SubProcessPipe(object): """Read media and stream data through a generator. Taken from Telemeta (see http://telemeta.org)""" -- 2.39.5