From 14e04d783175d10ec82a4e6f4cf618ce1e9ed88c Mon Sep 17 00:00:00 2001 From: yomguy Date: Fri, 27 Aug 2010 22:57:55 +0000 Subject: [PATCH] add MP3 gst encoder, change filenames in batch --- timeside/encoder/__init__.py | 2 +- timeside/encoder/mp3.py | 101 ++++++++++++++++++++++++++++--- timeside/encoder/ogg.py | 7 ++- timeside/encoder/wav.py | 7 ++- timeside/tools/waveform_batch.py | 16 +++-- 5 files changed, 115 insertions(+), 18 deletions(-) diff --git a/timeside/encoder/__init__.py b/timeside/encoder/__init__.py index 67ee689..169d959 100644 --- a/timeside/encoder/__init__.py +++ b/timeside/encoder/__init__.py @@ -3,5 +3,5 @@ from core import * from ogg import * from wav import * -#from timeside.encoder.mp3 import * +from mp3 import * #from timeside.encoder.flac import * diff --git a/timeside/encoder/mp3.py b/timeside/encoder/mp3.py index 70f6dfb..2fd5104 100644 --- a/timeside/encoder/mp3.py +++ b/timeside/encoder/mp3.py @@ -1,4 +1,4 @@ -# -*- coding: utf-8 -*- + # -*- coding: utf-8 -*- # # Copyright (C) 2007 Parisson SARL # Copyright (c) 2006-2007 Guillaume Pellerin @@ -18,22 +18,105 @@ # You should have received a copy of the GNU General Public License # along with TimeSide. If not, see . -# Author: Guillaume Pellerin +# Authors: Guillaume Pellerin +# Paul Brossier -import os -import string -import subprocess - -from timeside.encoder.core import * +from timeside.core import Processor, implements, interfacedoc from timeside.api import IEncoder +from numpy import array, frombuffer, getbuffer, float32 +import pygst +pygst.require('0.10') +import gst +import gobject +gobject.threads_init () -class Mp3Encoder(EncoderCore): - """Defines methods to encode to MP3""" +class Mp3Encoder(Processor): + """ gstreamer-based mp3 encoder """ implements(IEncoder) + def __init__(self, output): + self.file = None + if isinstance(output, basestring): + self.filename = output + else: + raise Exception("Streaming not supported") + + @interfacedoc + def setup(self, channels=None, samplerate=None, nframes=None): + super(Mp3Encoder, self).setup(channels, samplerate, nframes) + #TODO: open file for writing + # the output data format we want + pipeline = gst.parse_launch(''' appsrc name=src + ! audioconvert + ! lame + ! filesink location=%s ''' % self.filename) + # store a pointer to appsink in our encoder object + self.src = pipeline.get_by_name('src') + srccaps = gst.Caps("""audio/x-raw-float, + endianness=(int)1234, + channels=(int)%s, + width=(int)32, + rate=(int)%d""" % (int(channels), int(samplerate))) + self.src.set_property("caps", srccaps) + + # start pipeline + pipeline.set_state(gst.STATE_PLAYING) + self.pipeline = pipeline + + @staticmethod + @interfacedoc + def id(): + return "gst_mp3_enc" + + @staticmethod + @interfacedoc + def description(): + return "MP3 GStreamer 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): + #TODO: + pass + + @interfacedoc + def process(self, frames, eod=False): + buf = self.numpy_array_to_gst_buffer(frames) + self.src.emit('push-buffer', buf) + if eod: self.src.emit('end-of-stream') + return frames, eod + + def numpy_array_to_gst_buffer(self, frames): + """ gstreamer buffer to numpy array conversion """ + buf = gst.Buffer(getbuffer(frames)) + return buf + + +class Mp3EncoderOld: + """Defines methods to encode to MP3""" + +# implements(IEncoder) + def __init__(self): + import os + import string + import subprocess self.bitrate_default = '192' self.dub2id3_dict = {'title': 'TIT2', #title2 'creator': 'TCOM', #composer diff --git a/timeside/encoder/ogg.py b/timeside/encoder/ogg.py index fb89fd3..b120e4f 100644 --- a/timeside/encoder/ogg.py +++ b/timeside/encoder/ogg.py @@ -51,7 +51,7 @@ class VorbisEncoder(Processor): ! vorbisenc ! oggmux ! filesink location=%s ''' % self.filename) - # store a pointer to appsink in our encoder object + # store a pointer to appsink in our encoder object self.src = pipeline.get_by_name('src') srccaps = gst.Caps("""audio/x-raw-float, endianness=(int)1234, @@ -74,6 +74,11 @@ class VorbisEncoder(Processor): def description(): return "Vorbis GStreamer based encoder" + @staticmethod + @interfacedoc + def format(): + return "OGG" + @staticmethod @interfacedoc def file_extension(): diff --git a/timeside/encoder/wav.py b/timeside/encoder/wav.py index 786564a..026d6b9 100644 --- a/timeside/encoder/wav.py +++ b/timeside/encoder/wav.py @@ -51,7 +51,7 @@ class WavEncoder(Processor): ! audioconvert ! wavenc ! filesink location=%s ''' % self.filename) - # store a pointer to appsink in our encoder object + # store a pointer to appsink in our encoder object self.src = pipeline.get_by_name('src') srccaps = gst.Caps("""audio/x-raw-float, endianness=(int)1234, @@ -74,6 +74,11 @@ class WavEncoder(Processor): def description(): return "Wav GStreamer based encoder" + @staticmethod + @interfacedoc + def format(): + return "WAV" + @staticmethod @interfacedoc def file_extension(): diff --git a/timeside/tools/waveform_batch.py b/timeside/tools/waveform_batch.py index 8bc8fe0..1827524 100644 --- a/timeside/tools/waveform_batch.py +++ b/timeside/tools/waveform_batch.py @@ -82,23 +82,27 @@ class Media2Waveform(object): for media in self.media_list: filename = media.split(os.sep)[-1] name, ext = os.path.splitext(filename) - path_dict[media] = self.img_dir + os.sep + filename + '.png' + path_dict[media] = self.img_dir + os.sep + filename.replace('.', '_') + '.png' return path_dict def process(self): for source, image in self.path_dict.iteritems(): if not os.path.exists(image) or self.force: - print 'Rendering ', source, ' to ', image, '...' + print 'Processing ', source audio = os.path.join(os.path.dirname(__file__), source) decoder = timeside.decoder.FileDecoder(audio) - + analyzer = timeside.analyzer.Duration() waveform = timeside.grapher.WaveformJoyDiv(width=self.width, height=self.height, output=image, bg_color=self.bg_color, color_scheme=self.color_scheme) - - (decoder | waveform).run() + (decoder | analyzer | waveform).run() + duration = analyzer.result() + img_name = os.path.split(image)[1] + image = os.path.split(image)[0]+os.sep+os.path.splitext(img_name)[0]+'_'+str(int(duration))+os.path.splitext(img_name)[1] + waveform.graph.filename = image + print 'Rendering ', source, ' to ', waveform.graph.filename, '...' print 'frames per pixel = ', waveform.graph.samples_per_pixel waveform.render() - + if __name__ == '__main__': if len(sys.argv) <= 2: -- 2.39.5