From 1ecd98629dede6f2bfce8e098e029955c8d623c0 Mon Sep 17 00:00:00 2001 From: yomguy Date: Thu, 17 Feb 2011 14:44:53 +0000 Subject: [PATCH] bugfix mp3_stream, add ogg_stream, bugfix max_level --- timeside/analyzer/max_level.py | 2 +- timeside/encoder/__init__.py | 3 +- timeside/encoder/mp3_stream.py | 5 +- timeside/encoder/ogg_stream.py | 115 +++++++++++++++++++++++++++++++++ 4 files changed, 119 insertions(+), 6 deletions(-) create mode 100644 timeside/encoder/ogg_stream.py diff --git a/timeside/analyzer/max_level.py b/timeside/analyzer/max_level.py index 58ea322..b97c9e2 100644 --- a/timeside/analyzer/max_level.py +++ b/timeside/analyzer/max_level.py @@ -32,7 +32,7 @@ class MaxLevel(Processor): @interfacedoc def setup(self, channels=None, samplerate=None, nframes=None): super(MaxLevel, self).setup(channels, samplerate, nframes) - self.value = 0 + self.value = -120 @staticmethod @interfacedoc diff --git a/timeside/encoder/__init__.py b/timeside/encoder/__init__.py index 28d1c4d..e53e088 100644 --- a/timeside/encoder/__init__.py +++ b/timeside/encoder/__init__.py @@ -4,7 +4,8 @@ from core import * from ogg import * from wav import * from mp3 import * -from mp3_stream import * from m4a import * +from mp3_stream import * +from ogg_stream import * #from timeside.encoder.flac import * diff --git a/timeside/encoder/mp3_stream.py b/timeside/encoder/mp3_stream.py index e343520..8b3de51 100644 --- a/timeside/encoder/mp3_stream.py +++ b/timeside/encoder/mp3_stream.py @@ -37,15 +37,13 @@ class Mp3EncoderStream(Processor): implements(IEncoder) def __init__(self, output=None): -# self.file = None self.filename = output @interfacedoc def setup(self, channels=None, samplerate=None, nframes=None): super(Mp3EncoderStream, self).setup(channels, samplerate, nframes) #TODO: open file for writing - # the output data format we want - + # the output data format we want pipe = '''appsrc name=src ! audioconvert ! lame name=enc vbr=0 bitrate=256 ! id3v2mux ''' @@ -117,4 +115,3 @@ class Mp3EncoderStream(Processor): """ gstreamer buffer to numpy array conversion """ buf = gst.Buffer(getbuffer(frames)) return buf - diff --git a/timeside/encoder/ogg_stream.py b/timeside/encoder/ogg_stream.py new file mode 100644 index 0000000..7978f46 --- /dev/null +++ b/timeside/encoder/ogg_stream.py @@ -0,0 +1,115 @@ +# -*- coding: utf-8 -*- +# +# Copyright (c) 2010 Paul Brossier +# Copyright (c) 2010 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 . + + +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 VorbisEncoderStream(Processor): + """ gstreamer-based vorbis encoder """ + implements(IEncoder) + + def __init__(self, output=None): + self.filename = output + + @interfacedoc + def setup(self, channels=None, samplerate=None, nframes=None): + super(VorbisEncoderStream, self).setup(channels, samplerate, nframes) + # TODO open file for writing + # the output data format we want + pipe = '''appsrc name=src ! audioconvert + ! vorbisenc ! oggmux + ''' + if self.filename: + pipe += ''' + ! queue2 name=q0 ! tee name=tee + tee. ! queue name=q1 ! appsink name=app + tee. ! queue name=q2 ! filesink location=%s + ''' % self.filename + else: + pipe += '! appsink name=app' + + pipeline = gst.parse_launch(pipe) + # store a pointer to appsrc in our encoder object + self.src = pipeline.get_by_name('src') + # store a pointer to appsink in our encoder object + self.app = pipeline.get_by_name('app') + + 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_vorbis_enc_stream" + + @staticmethod + @interfacedoc + def description(): + return "Vorbis GStreamer based encoder and streamer" + + @staticmethod + @interfacedoc + def format(): + return "OGG" + + @staticmethod + @interfacedoc + def file_extension(): + return "ogg" + + @staticmethod + @interfacedoc + def mime_type(): + return "application/ogg" + + @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) + appbuffer = self.app.emit('pull-buffer') + if eod: self.src.emit('end-of-stream') + return appbuffer, eod + + def numpy_array_to_gst_buffer(self, frames): + """ gstreamer buffer to numpy array conversion """ + buf = gst.Buffer(getbuffer(frames)) + return buf -- 2.39.5