]> git.parisson.com Git - timeside.git/commitdiff
add MP3 gst encoder, change filenames in batch
authoryomguy <yomguy@parisson.com>
Fri, 27 Aug 2010 22:57:55 +0000 (22:57 +0000)
committeryomguy <yomguy@parisson.com>
Fri, 27 Aug 2010 22:57:55 +0000 (22:57 +0000)
timeside/encoder/__init__.py
timeside/encoder/mp3.py
timeside/encoder/ogg.py
timeside/encoder/wav.py
timeside/tools/waveform_batch.py

index 67ee689711fa9a66596ddd1a7f8af0f31c0deaa0..169d95980a244a6c6ef878030c6e0a54d812fd33 100644 (file)
@@ -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 *
index 70f6dfb5ff6098e32588a3aba33f5aa36d210f5b..2fd5104fd8f7e1b7908322046d371a45f882687a 100644 (file)
@@ -1,4 +1,4 @@
-# -*- coding: utf-8 -*-
+    # -*- coding: utf-8 -*-
 #
 # Copyright (C) 2007 Parisson SARL
 # Copyright (c) 2006-2007 Guillaume Pellerin <pellerin@parisson.com>
 # You should have received a copy of the GNU General Public License
 # along with TimeSide.  If not, see <http://www.gnu.org/licenses/>.
 
-# Author: Guillaume Pellerin <yomguy@parisson.com>
+# Authors: Guillaume Pellerin <yomguy@parisson.com>
+#          Paul Brossier <piem@piem.org>
 
-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
index fb89fd35e2f908be239c3e0140a6b4d313590981..b120e4fdeac92546ec28c0b5b6cd68bcb1db4dfb 100644 (file)
@@ -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():
index 786564aef8596eca33e21f3547465da899b40b2f..026d6b9f1f32233874d5fc403ef5be3b09c7f858 100644 (file)
@@ -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():
index 8bc8fe07a9b9ff03391f00a2454544c295acb25a..1827524d8c32a316dbc10bd6810c11fd5b5b7bc7 100644 (file)
@@ -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: