Campcaster to Icecast patch
  • Hello my friends.

    In a desesperated way to make my virtual private server running Campsite without an audio board, I was tried to made some changes to link CS directly to Icecast vis shot2send gstreamer plugin. This modification has hard coded values only for testing purposes, and play only mp3 files. Anyway this modification not work. Campcaster simple hang. Please, can you help me?

    The folowing code is made in the file /src/modules/playlistExecutor/src/GstreamerPlayContext.h.

    Original code:
        /*------------------------------------------------------------------------------
        *  Prepare audio device from the name provided previously.
        *----------------------------------------------------------------------------*/
        bool prepareAudioDevice() throw() {
            if(m_sink != NULL){
                gst_object_unref(GST_OBJECT(m_sink));
                m_sink=NULL;
            }
    
            GstPad *audiopad;
    
            // this constant checks if the audio device configuration contains the string
            // "/dev", if so the below pipeline definition uses oss.
            // Perhaps the logic can go three ways and check if the device is labled jack.
            // Or keep the if-else logic and eliminate OSS as an option as it is obsolete anyway
            // and ALSA can emulate it.
            // const bool oss = m_audioDevice.find("/dev") == 0;
            const bool autosink = m_audioDevice.find("auto") == 0;
    
            m_sink = gst_bin_new ("audiobin");
            if(m_sink == NULL){
                return false;
            }
            GstElement *conv = gst_element_factory_make ("audioconvert", "aconv");
            audiopad = gst_element_get_pad (conv, "sink");
    
            // set the string to be sent to gstreamer. the option here is to set it to autoaudiosink.
            GstElement *sink = (autosink ? gst_element_factory_make("autoaudiosink", NULL) : gst_element_factory_make("alsasink", NULL));
            if(sink == NULL){
                return false;
            }
            g_object_set(G_OBJECT(sink), "device", m_audioDevice.c_str(), NULL);
    
            m_volume = gst_element_factory_make("volume", NULL);
            g_object_set(G_OBJECT(m_volume), "volume", 0.0, NULL);
    
            gst_bin_add_many (GST_BIN (m_sink), conv, m_volume, sink, NULL);
            gst_element_link (conv, m_volume);
            gst_element_link (m_volume, sink);
            gst_element_add_pad (m_sink, gst_ghost_pad_new ("sink", audiopad));
            gst_object_unref (audiopad);
            return true;
        }
    


    Modified code:
        /*------------------------------------------------------------------------------
        *  Prepare audio device from the name provided previously.
        *----------------------------------------------------------------------------*/
        bool prepareAudioDevice() throw() {
            if(m_sink != NULL){
                gst_object_unref(GST_OBJECT(m_sink));
                m_sink=NULL;
            }
    
            GstPad *audiopad;
    
            //gst-launch filesrc location=/root/pepe.mp3 ! mad ! audioconvert ! volume volume=1 !
            //lame bitrate=192 ! shout2send ip=127.0.0.1 port=8000 password=mypass mount=test.mp3
    
            m_sink = gst_bin_new ("audiobin");
            if(m_sink == NULL){
                return false;
            }
            GstElement *conv = gst_element_factory_make ("mad", "conv");
            GstElement *aconv = gst_element_factory_make ("audioconvert", "aconv");
            GstElement *lconv = gst_element_factory_make ("lame", "lconv");
            g_object_set(G_OBJECT(lconv), "bitrate", 128, NULL);
    
            audiopad = gst_element_get_pad (conv, "sink");
    
            // set the string to be sent to gstreamer. the option here is to set it to autoaudiosink.
            GstElement *sink = gst_element_factory_make("shout2send", NULL);
            if(sink == NULL){
                return false;
            }
            g_object_set(G_OBJECT(sink), "ip", "127.0.0.1", NULL);
            g_object_set(G_OBJECT(sink), "port", 8000, NULL);
            g_object_set(G_OBJECT(sink), "password", "mypass", NULL);
            g_object_set(G_OBJECT(sink), "mount", "vivo", NULL);
    
            m_volume = gst_element_factory_make("volume", NULL);
            g_object_set(G_OBJECT(m_volume), "volume", 0.0, NULL);
    
            gst_bin_add_many (GST_BIN (m_sink), conv, aconv, m_volume, lconv, sink, NULL);
            gst_element_link (conv, aconv);
            gst_element_link (aconv, m_volume);
            gst_element_link (m_volume, lconv);
            gst_element_link (lconv, sink);
            gst_element_add_pad (m_sink, gst_ghost_pad_new ("sink", audiopad));
            gst_object_unref (audiopad);
            return true;
        }
    


    Unified diff code:
    --- 1   2010-09-30 04:02:11.000000000 -0300
    +++ 2   2010-09-30 04:02:32.000000000 -0300
    @@ -9,34 +9,38 @@
    
             GstPad *audiopad;
    
    -        // this constant checks if the audio device configuration contains the string
    -        // "/dev", if so the below pipeline definition uses oss.
    -        // Perhaps the logic can go three ways and check if the device is labled jack.
    -        // Or keep the if-else logic and eliminate OSS as an option as it is obsolete anyway
    -        // and ALSA can emulate it.
    -        // const bool oss = m_audioDevice.find("/dev") == 0;
    -        const bool autosink = m_audioDevice.find("auto") == 0;
    +       //gst-launch filesrc location=/root/pepe.mp3 ! mad ! audioconvert ! volume volume=1 !
    +       //lame bitrate=192 ! shout2send ip=127.0.0.1 port=8000 password=mypass mount=test.mp3
    
             m_sink = gst_bin_new ("audiobin");
             if(m_sink == NULL){
                 return false;
             }
    -        GstElement *conv = gst_element_factory_make ("audioconvert", "aconv");
    +        GstElement *conv = gst_element_factory_make ("mad", "conv");
    +        GstElement *aconv = gst_element_factory_make ("audioconvert", "aconv");
    +        GstElement *lconv = gst_element_factory_make ("lame", "lconv");
    +        g_object_set(G_OBJECT(lconv), "bitrate", 128, NULL);
    +
             audiopad = gst_element_get_pad (conv, "sink");
    
             // set the string to be sent to gstreamer. the option here is to set it to autoaudiosink.
    -        GstElement *sink = (autosink ? gst_element_factory_make("autoaudiosink", NULL) : gst_element_factory_make("alsasink", NULL));
    +        GstElement *sink = gst_element_factory_make("shout2send", NULL);
             if(sink == NULL){
                 return false;
             }
    -        g_object_set(G_OBJECT(sink), "device", m_audioDevice.c_str(), NULL);
    -
    +        g_object_set(G_OBJECT(sink), "ip", "127.0.0.1", NULL);
    +        g_object_set(G_OBJECT(sink), "port", 8000, NULL);
    +        g_object_set(G_OBJECT(sink), "password", "mypass", NULL);
    +        g_object_set(G_OBJECT(sink), "mount", "vivo", NULL);
    +
             m_volume = gst_element_factory_make("volume", NULL);
             g_object_set(G_OBJECT(m_volume), "volume", 0.0, NULL);
    
    -        gst_bin_add_many (GST_BIN (m_sink), conv, m_volume, sink, NULL);
    -        gst_element_link (conv, m_volume);
    -        gst_element_link (m_volume, sink);
    +        gst_bin_add_many (GST_BIN (m_sink), conv, aconv, m_volume, lconv, sink, NULL);
    +        gst_element_link (conv, aconv);
    +        gst_element_link (aconv, m_volume);
    +        gst_element_link (m_volume, lconv);
    +        gst_element_link (lconv, sink);
             gst_element_add_pad (m_sink, gst_ghost_pad_new ("sink", audiopad));
             gst_object_unref (audiopad);
             return true;
    


    So, this code produce campcaster-scheduler binary.

    Thank you very much.
  • 14 Comments sorted by
  • Hello again. I don't know how work this forum or mailing list, but every time I send a message or write directly here on the forum, I not receive my own messages. It is normal?
  • Vote Up0Vote Down Andrey PodshivalovAndrey Podshivalov
    Posts: 1,526Member, Administrator, Sourcefabric Team
    Normando Hall wrote on Thu, 30 September 2010 23:30
    Hello again. I don't know how work this forum or mailing list, but every time I send a message or write directly here on the forum, I not receive my own messages. It is normal?

    Yes, it's a normal behavior for mailing lists and forums. Don't spam own mailbox Wink
  • haa, right. Thank you, and sorry for this "spam" :)

    El 30/09/2010 05:37 p.m., Andrey Podshivalov escribió:
    > Normando Hall wrote on Thu, 30 September 2010 23:30
    >
    > Hello again. I don't know how work this forum or mailing list, but
    > every time I send a message or write directly here on the forum, I
    > not receive my own messages. It is normal?
    >
    >
    > Yes, it's a normal behavior for mailing lists and forums. Don't spam
    > own mailbox Wink
    >
    >

  • Vote Up0Vote Down Paul BaranowskiPaul Baranowski
    Posts: 389Member, Administrator, Sourcefabric Team
    Hi Normando -
    We are working hard on the next version - Campcaster 1.6, which will be
    web-only. We are transitioning to using Liquidsoap as the backend player
    which will solve all the playout problems. We should have a working beta by
    the end of October. If you know PHP and would like to help us out let me
    know. The C++ stuff is all going away. And if you know anyone who might be
    interested in working on Campcaster full-time let me know :).

    Paul Baranowski
    Chief Technology Officer, Sourcefabric

    paul.baranowski@sourcefabric.org
    +1 (416) 832-6436 (Cell)
    Toronto, ON, Canada

    http://sourcefabric.org
    Skype: paulbaranowski


    On Thu, Sep 30, 2010 at 3:11 AM, Normando Hall <
    campcaster-dev@lists.sourcefabric.org> wrote:

    > Hello my friends.
    >
    > In a desesperated way to make my virtual private server running Campsite
    > without an audio board, I was tried to made some changes to link CS directly
    > to Icecast vis shot2send gstreamer plugin. This modification has hard coded
    > values only for testing purposes, and play only mp3 files. Anyway this
    > modification not work. Campcaster simple hang. Please, can you help me?
    >
    > The folowing code is made in the file
    > /src/modules/playlistExecutor/src/GstreamerPlayContext.h.
    >
    > *Original code:*
    >
    > /*---------------------------------------------------------- --------------------
    > * Prepare audio device from the name provided previously.
    > *----------------------------------------------------------- -----------------*/
    > bool prepareAudioDevice() throw() {
    > if(m_sink != NULL){
    > gst_object_unref(GST_OBJECT(m_sink));
    > m_sink=NULL;
    > }
    >
    > GstPad *audiopad;
    >
    > // this constant checks if the audio device configuration contains the string
    > // "/dev", if so the below pipeline definition uses oss.
    > // Perhaps the logic can go three ways and check if the device is labled jack.
    > // Or keep the if-else logic and eliminate OSS as an option as it is obsolete anyway
    > // and ALSA can emulate it.
    > // const bool oss = m_audioDevice.find("/dev") == 0;
    > const bool autosink = m_audioDevice.find("auto") == 0;
    >
    > m_sink = gst_bin_new ("audiobin");
    > if(m_sink == NULL){
    > return false;
    > }
    > GstElement *conv = gst_element_factory_make ("audioconvert", "aconv");
    > audiopad = gst_element_get_pad (conv, "sink");
    >
    > // set the string to be sent to gstreamer. the option here is to set it to autoaudiosink.
    > GstElement *sink = (autosink ? gst_element_factory_make("autoaudiosink", NULL) : gst_element_factory_make("alsasink", NULL));
    > if(sink == NULL){
    > return false;
    > }
    > g_object_set(G_OBJECT(sink), "device", m_audioDevice.c_str(), NULL);
    >
    > m_volume = gst_element_factory_make("volume", NULL);
    > g_object_set(G_OBJECT(m_volume), "volume", 0.0, NULL);
    >
    > gst_bin_add_many (GST_BIN (m_sink), conv, m_volume, sink, NULL);
    > gst_element_link (conv, m_volume);
    > gst_element_link (m_volume, sink);
    > gst_element_add_pad (m_sink, gst_ghost_pad_new ("sink", audiopad));
    > gst_object_unref (audiopad);
    > return true;
    > }
    >
    >
    >
    > *Modified code:*
    >
    > /*---------------------------------------------------------- --------------------
    > * Prepare audio device from the name provided previously.
    > *----------------------------------------------------------- -----------------*/
    > bool prepareAudioDevice() throw() {
    > if(m_sink != NULL){
    > gst_object_unref(GST_OBJECT(m_sink));
    > m_sink=NULL;
    > }
    >
    > GstPad *audiopad;
    >
    > //gst-launch filesrc location=/root/pepe.mp3 ! mad ! audioconvert ! volume volume=1 !
    > //lame bitrate=192 ! shout2send ip=127.0.0.1 port=8000 password=norman162 mount=test.mp3
    >
    > m_sink = gst_bin_new ("audiobin");
    > if(m_sink == NULL){
    > return false;
    > }
    > GstElement *conv = gst_element_factory_make ("mad", "conv");
    > GstElement *aconv = gst_element_factory_make ("audioconvert", "aconv");
    > GstElement *lconv = gst_element_factory_make ("lame", "lconv");
    > g_object_set(G_OBJECT(lconv), "bitrate", 128, NULL);
    >
    > audiopad = gst_element_get_pad (conv, "sink");
    >
    > // set the string to be sent to gstreamer. the option here is to set it to autoaudiosink.
    > GstElement *sink = gst_element_factory_make("shout2send", NULL);
    > if(sink == NULL){
    > return false;
    > }
    > g_object_set(G_OBJECT(sink), "ip", "127.0.0.1", NULL);
    > g_object_set(G_OBJECT(sink), "port", 8000, NULL);
    > g_object_set(G_OBJECT(sink), "password", "norman162", NULL);
    > g_object_set(G_OBJECT(sink), "mount", "vivo", NULL);
    >
    > m_volume = gst_element_factory_make("volume", NULL);
    > g_object_set(G_OBJECT(m_volume), "volume", 0.0, NULL);
    >
    > gst_bin_add_many (GST_BIN (m_sink), conv, aconv, m_volume, lconv, sink, NULL);
    > gst_element_link (conv, aconv);
    > gst_element_link (aconv, m_volume);
    > gst_element_link (m_volume, lconv);
    > gst_element_link (lconv, sink);
    > gst_element_add_pad (m_sink, gst_ghost_pad_new ("sink", audiopad));
    > gst_object_unref (audiopad);
    > return true;
    > }
    >
    >
    >
    > *Unified diff code:*
    >
    > --- 1 2010-09-30 04:02:11.000000000 -0300
    > +++ 2 2010-09-30 04:02:32.000000000 -0300
    > @@ -9,34 +9,38 @@
    >
    > GstPad *audiopad;
    >
    > - // this constant checks if the audio device configuration contains the string
    > - // "/dev", if so the below pipeline definition uses oss.
    > - // Perhaps the logic can go three ways and check if the device is labled jack.
    > - // Or keep the if-else logic and eliminate OSS as an option as it is obsolete anyway
    > - // and ALSA can emulate it.
    > - // const bool oss = m_audioDevice.find("/dev") == 0;
    > - const bool autosink = m_audioDevice.find("auto") == 0;
    > + //gst-launch filesrc location=/root/pepe.mp3 ! mad ! audioconvert ! volume volume=1 !
    > + //lame bitrate=192 ! shout2send ip=127.0.0.1 port=8000 password=norman162 mount=test.mp3
    >
    > m_sink = gst_bin_new ("audiobin");
    > if(m_sink == NULL){
    > return false;
    > }
    > - GstElement *conv = gst_element_factory_make ("audioconvert", "aconv");
    > + GstElement *conv = gst_element_factory_make ("mad", "conv");
    > + GstElement *aconv = gst_element_factory_make ("audioconvert", "aconv");
    > + GstElement *lconv = gst_element_factory_make ("lame", "lconv");
    > + g_object_set(G_OBJECT(lconv), "bitrate", 128, NULL);
    > +
    > audiopad = gst_element_get_pad (conv, "sink");
    >
    > // set the string to be sent to gstreamer. the option here is to set it to autoaudiosink.
    > - GstElement *sink = (autosink ? gst_element_factory_make("autoaudiosink", NULL) : gst_element_factory_make("alsasink", NULL));
    > + GstElement *sink = gst_element_factory_make("shout2send", NULL);
    > if(sink == NULL){
    > return false;
    > }
    > - g_object_set(G_OBJECT(sink), "device", m_audioDevice.c_str(), NULL);
    > -
    > + g_object_set(G_OBJECT(sink), "ip", "127.0.0.1", NULL);
    > + g_object_set(G_OBJECT(sink), "port", 8000, NULL);
    > + g_object_set(G_OBJECT(sink), "password", "norman162", NULL);
    > + g_object_set(G_OBJECT(sink), "mount", "vivo", NULL);
    > +
    > m_volume = gst_element_factory_make("volume", NULL);
    > g_object_set(G_OBJECT(m_volume), "volume", 0.0, NULL);
    >
    > - gst_bin_add_many (GST_BIN (m_sink), conv, m_volume, sink, NULL);
    > - gst_element_link (conv, m_volume);
    > - gst_element_link (m_volume, sink);
    > + gst_bin_add_many (GST_BIN (m_sink), conv, aconv, m_volume, lconv, sink, NULL);
    > + gst_element_link (conv, aconv);
    > + gst_element_link (aconv, m_volume);
    > + gst_element_link (m_volume, lconv);
    > + gst_element_link (lconv, sink);
    > gst_element_add_pad (m_sink, gst_ghost_pad_new ("sink", audiopad));
    > gst_object_unref (audiopad);
    > return true;
    >
    >
    >
    > So, this code produce campcaster-scheduler binary.
    >
    > Thank you very much.
    >

  • Hi Paul.

    Thank you for your reply. If C++ code gone away sound brilliant! :)
    I know php and it is a pleasure collaborate with the project. I have no
    time to work full nor half time, but I can made collaboration, like
    fixing the code, search for bugs, testing, make rpms, etc.
    So I think the best is to begin after you have released 1.6 beta to get
    the code and start my work.

    Meanwhile I need to fix the issue with shout2send in 1.4.

    Thanks Paul and all developer for this high end software.

    --
    Normando Hall
    Rosario - Argentina

    El 01/10/2010 09:57 a.m., Paul Baranowski escribió:
    > Hi Normando -
    > We are working hard on the next version - Campcaster 1.6, which will be
    > web-only. We are transitioning to using Liquidsoap as the backend player
    > which will solve all the playout problems. We should have a working
    > beta by
    > the end of October. If you know PHP and would like to help us out let me
    > know. The C++ stuff is all going away. And if you know anyone who might be
    > interested in working on Campcaster full-time let me know :).
    >
    > Paul Baranowski
    > Chief Technology Officer, Sourcefabric
    >
    > paul.baranowski@sourcefabric.org <mailto:paul.baranowski@sourcefabric.org>
    > +1 (416) 832-6436 (Cell)
    > Toronto, ON, Canada
    >
    > http://sourcefabric.org
    > Skype: paulbaranowski
    >
    >
    > On Thu, Sep 30, 2010 at 3:11 AM, Normando Hall <
    > campcaster-dev@lists.sourcefabric.org
    > <mailto:campcaster-dev@lists.sourcefabric.org>> wrote:
    >
    > > Hello my friends.
    > >
    > > In a desesperated way to make my virtual private server running Campsite
    > > without an audio board, I was tried to made some changes to link CS
    > directly
    > > to Icecast vis shot2send gstreamer plugin. This modification has
    > hard coded
    > > values only for testing purposes, and play only mp3 files. Anyway this
    > > modification not work. Campcaster simple hang. Please, can you help me?
    > >
    > > The folowing code is made in the file
    > > /src/modules/playlistExecutor/src/GstreamerPlayContext.h.
    > >
    > > *Original code:*
    > >
    > > /*----------------------------------------------------------
    > --------------------
    > > * Prepare audio device from the name provided previously.
    > > *-----------------------------------------------------------
    > -----------------*/
    > > bool prepareAudioDevice() throw() {
    > > if(m_sink != NULL){
    > > gst_object_unref(GST_OBJECT(m_sink));
    > > m_sink=NULL;
    > > }
    > >
    > > GstPad *audiopad;
    > >
    > > // this constant checks if the audio device configuration contains
    > the string
    > > // "/dev", if so the below pipeline definition uses oss.
    > > // Perhaps the logic can go three ways and check if the device is
    > labled jack.
    > > // Or keep the if-else logic and eliminate OSS as an option as it is
    > obsolete anyway
    > > // and ALSA can emulate it.
    > > // const bool oss = m_audioDevice.find("/dev") == 0;
    > > const bool autosink = m_audioDevice.find("auto") == 0;
    > >
    > > m_sink = gst_bin_new ("audiobin");
    > > if(m_sink == NULL){
    > > return false;
    > > }
    > > GstElement *conv = gst_element_factory_make ("audioconvert", "aconv");
    > > audiopad = gst_element_get_pad (conv, "sink");
    > >
    > > // set the string to be sent to gstreamer. the option here is to set
    > it to autoaudiosink.
    > > GstElement *sink = (autosink ?
    > gst_element_factory_make("autoaudiosink", NULL) :
    > gst_element_factory_make("alsasink", NULL));
    > > if(sink == NULL){
    > > return false;
    > > }
    > > g_object_set(G_OBJECT(sink), "device", m_audioDevice.c_str(), NULL);
    > >
    > > m_volume = gst_element_factory_make("volume", NULL);
    > > g_object_set(G_OBJECT(m_volume), "volume", 0.0, NULL);
    > >
    > > gst_bin_add_many (GST_BIN (m_sink), conv, m_volume, sink, NULL);
    > > gst_element_link (conv, m_volume);
    > > gst_element_link (m_volume, sink);
    > > gst_element_add_pad (m_sink, gst_ghost_pad_new ("sink", audiopad));
    > > gst_object_unref (audiopad);
    > > return true;
    > > }
    > >
    > >
    > >
    > > *Modified code:*
    > >
    > > /*----------------------------------------------------------
    > --------------------
    > > * Prepare audio device from the name provided previously.
    > > *-----------------------------------------------------------
    > -----------------*/
    > > bool prepareAudioDevice() throw() {
    > > if(m_sink != NULL){
    > > gst_object_unref(GST_OBJECT(m_sink));
    > > m_sink=NULL;
    > > }
    > >
    > > GstPad *audiopad;
    > >
    > > //gst-launch filesrc location=/root/pepe.mp3 ! mad ! audioconvert !
    > volume volume=1 !
    > > //lame bitrate=192 ! shout2send ip=127.0.0.1 port=8000
    > password=norman162 mount=test.mp3
    > >
    > > m_sink = gst_bin_new ("audiobin");
    > > if(m_sink == NULL){
    > > return false;
    > > }
    > > GstElement *conv = gst_element_factory_make ("mad", "conv");
    > > GstElement *aconv = gst_element_factory_make ("audioconvert", "aconv");
    > > GstElement *lconv = gst_element_factory_make ("lame", "lconv");
    > > g_object_set(G_OBJECT(lconv), "bitrate", 128, NULL);
    > >
    > > audiopad = gst_element_get_pad (conv, "sink");
    > >
    > > // set the string to be sent to gstreamer. the option here is to set
    > it to autoaudiosink.
    > > GstElement *sink = gst_element_factory_make("shout2send", NULL);
    > > if(sink == NULL){
    > > return false;
    > > }
    > > g_object_set(G_OBJECT(sink), "ip", "127.0.0.1", NULL);
    > > g_object_set(G_OBJECT(sink), "port", 8000, NULL);
    > > g_object_set(G_OBJECT(sink), "password", "norman162", NULL);
    > > g_object_set(G_OBJECT(sink), "mount", "vivo", NULL);
    > >
    > > m_volume = gst_element_factory_make("volume", NULL);
    > > g_object_set(G_OBJECT(m_volume), "volume", 0.0, NULL);
    > >
    > > gst_bin_add_many (GST_BIN (m_sink), conv, aconv, m_volume, lconv,
    > sink, NULL);
    > > gst_element_link (conv, aconv);
    > > gst_element_link (aconv, m_volume);
    > > gst_element_link (m_volume, lconv);
    > > gst_element_link (lconv, sink);
    > > gst_element_add_pad (m_sink, gst_ghost_pad_new ("sink", audiopad));
    > > gst_object_unref (audiopad);
    > > return true;
    > > }
    > >
    > >
    > >
    > > *Unified diff code:*
    > >
    > > --- 1 2010-09-30 04:02:11.000000000 -0300
    > > +++ 2 2010-09-30 04:02:32.000000000 -0300
    > > @@ -9,34 +9,38 @@
    > >
    > > GstPad *audiopad;
    > >
    > > - // this constant checks if the audio device configuration contains
    > the string
    > > - // "/dev", if so the below pipeline definition uses oss.
    > > - // Perhaps the logic can go three ways and check if the device is
    > labled jack.
    > > - // Or keep the if-else logic and eliminate OSS as an option as it
    > is obsolete anyway
    > > - // and ALSA can emulate it.
    > > - // const bool oss = m_audioDevice.find("/dev") == 0;
    > > - const bool autosink = m_audioDevice.find("auto") == 0;
    > > + //gst-launch filesrc location=/root/pepe.mp3 ! mad ! audioconvert
    > ! volume volume=1 !
    > > + //lame bitrate=192 ! shout2send ip=127.0.0.1 port=8000
    > password=norman162 mount=test.mp3
    > >
    > > m_sink = gst_bin_new ("audiobin");
    > > if(m_sink == NULL){
    > > return false;
    > > }
    > > - GstElement *conv = gst_element_factory_make ("audioconvert", "aconv");
    > > + GstElement *conv = gst_element_factory_make ("mad", "conv");
    > > + GstElement *aconv = gst_element_factory_make ("audioconvert",
    > "aconv");
    > > + GstElement *lconv = gst_element_factory_make ("lame", "lconv");
    > > + g_object_set(G_OBJECT(lconv), "bitrate", 128, NULL);
    > > +
    > > audiopad = gst_element_get_pad (conv, "sink");
    > >
    > > // set the string to be sent to gstreamer. the option here is to set
    > it to autoaudiosink.
    > > - GstElement *sink = (autosink ?
    > gst_element_factory_make("autoaudiosink", NULL) :
    > gst_element_factory_make("alsasink", NULL));
    > > + GstElement *sink = gst_element_factory_make("shout2send", NULL);
    > > if(sink == NULL){
    > > return false;
    > > }
    > > - g_object_set(G_OBJECT(sink), "device", m_audioDevice.c_str(), NULL);
    > > -
    > > + g_object_set(G_OBJECT(sink), "ip", "127.0.0.1", NULL);
    > > + g_object_set(G_OBJECT(sink), "port", 8000, NULL);
    > > + g_object_set(G_OBJECT(sink), "password", "norman162", NULL);
    > > + g_object_set(G_OBJECT(sink), "mount", "vivo", NULL);
    > > +
    > > m_volume = gst_element_factory_make("volume", NULL);
    > > g_object_set(G_OBJECT(m_volume), "volume", 0.0, NULL);
    > >
    > > - gst_bin_add_many (GST_BIN (m_sink), conv, m_volume, sink, NULL);
    > > - gst_element_link (conv, m_volume);
    > > - gst_element_link (m_volume, sink);
    > > + gst_bin_add_many (GST_BIN (m_sink), conv, aconv, m_volume, lconv,
    > sink, NULL);
    > > + gst_element_link (conv, aconv);
    > > + gst_element_link (aconv, m_volume);
    > > + gst_element_link (m_volume, lconv);
    > > + gst_element_link (lconv, sink);
    > > gst_element_add_pad (m_sink, gst_ghost_pad_new ("sink", audiopad));
    > > gst_object_unref (audiopad);
    > > return true;
    > >
    > >
    > >
    > > So, this code produce campcaster-scheduler binary.
    > >
    > > Thank you very much.
    > >
    >
    >
    >

  • I saw about Liquidsoap and it is an impressive framework. Excellent choice Paul! With that we can make a great scheduller and live streamer.
  • I am very happy. Now we can stream directly to Icecast! Forget darkice, jack, virtual alsa boards, etc. This is the code. Replace the entire prepareAudioDevice function with this:

        /*------------------------------------------------------------------------------
        *  Prepare audio device from the name provided previously.
        *----------------------------------------------------------------------------*/
        bool prepareAudioDevice() throw() {
            if(m_sink != NULL){
                gst_object_unref(GST_OBJECT(m_sink));
                m_sink=NULL;
            }
    
            GstPad *audiopad;
    
            //gst-launch filesrc location=/root/pepe.mp3 ! audioconvert ! volume volume=1 !
            //lame bitrate=192 ! shout2send ip=127.0.0.1 port=8000 password=mypass mount=test.mp3
    
            m_sink = gst_bin_new ("audiobin");
            if(m_sink == NULL){
                return false;
            }
            GstElement *conv = gst_element_factory_make ("audioconvert", "aconv");
            GstElement *lconv = gst_element_factory_make ("lame", "lconv");
            g_object_set(G_OBJECT(lconv), "bitrate", 128, NULL);
    
            audiopad = gst_element_get_static_pad (conv, "sink");
    
            // set the string to be sent to gstreamer. the option here is to set it to autoaudiosink.
            GstElement *sink = gst_element_factory_make("shout2send", NULL);
            if(sink == NULL){
                return false;
            }
            g_object_set(G_OBJECT(sink), "ip", "127.0.0.1", NULL);
            g_object_set(G_OBJECT(sink), "port", 8000, NULL);
            g_object_set(G_OBJECT(sink), "password", "mypass", NULL);
            g_object_set(G_OBJECT(sink), "mount", "vivo", NULL);
    
            m_volume = gst_element_factory_make("volume", NULL);
            g_object_set(G_OBJECT(m_volume), "volume", 0.0, NULL);
    
            gst_bin_add_many (GST_BIN (m_sink), conv, m_volume, lconv, sink, NULL);
            gst_element_link_many (conv, m_volume, lconv, sink);
            gst_element_add_pad (m_sink, gst_ghost_pad_new ("sink", audiopad));
            gst_object_unref (GST_OBJECT (audiopad));
            return true;
        }
    


    TODO:
    Move the hardcoded settings to the xml conf file
    Made the changes need it to make an auto selecction based on the source (alsasink, autoaudiosink, shout2send).
    In the case of shout2send we need to leave (mounted) online between playlists and between playlist songs.
  • has anyone else tried this?

    sounds interesting!

    would it work on an icecast setup on a different server?
  • Yes, and work like a charm. The only issue I have now is avoid stream
    goes down between playlist songs, so I am using now icecast with a
    "fallback" set and run ok.

    El 03/10/2010 03:17 p.m., mickfuzz escribió:
    > has anyone else tried this?
    >
    > sounds interesting!
    >
    > would it work on an icecast setup on a different server?
    >
    >

  • hi there,

    could you tell me what level of knowledge would you need to do this?

    would you need to change the source code and compile the application?
  • Vote Up0Vote Down Paul BaranowskiPaul Baranowski
    Posts: 389Member, Administrator, Sourcefabric Team
    Hi Normando -
    Thanks for the patch, that's fantastic!


    On Fri, Oct 1, 2010 at 2:57 PM, Normando Hall <
    campcaster-dev@lists.sourcefabric.org> wrote:

    > I am very happy. Now we can stream directly to Icecast! Forget darkice,
    > jack, virtual alsa boards, etc. This is the code. Replace the entire
    > prepareAudioDevice function with this:
    >
    > /*---------------------------------------------------------- --------------------
    > * Prepare audio device from the name provided previously.
    > *----------------------------------------------------------- -----------------*/
    > bool prepareAudioDevice() throw() {
    > if(m_sink != NULL){
    > gst_object_unref(GST_OBJECT(m_sink));
    > m_sink=NULL;
    > }
    >
    > GstPad *audiopad;
    >
    > //gst-launch filesrc location=/root/pepe.mp3 ! audioconvert ! volume volume=1 !
    > //lame bitrate=192 ! shout2send ip=127.0.0.1 port=8000 password=mypass mount=test.mp3
    >
    > m_sink = gst_bin_new ("audiobin");
    > if(m_sink == NULL){
    > return false;
    > }
    > GstElement *conv = gst_element_factory_make ("audioconvert", "aconv");
    > GstElement *lconv = gst_element_factory_make ("lame", "lconv");
    > g_object_set(G_OBJECT(lconv), "bitrate", 128, NULL);
    >
    > audiopad = gst_element_get_static_pad (conv, "sink");
    >
    > // set the string to be sent to gstreamer. the option here is to set it to autoaudiosink.
    > GstElement *sink = gst_element_factory_make("shout2send", NULL);
    > if(sink == NULL){
    > return false;
    > }
    > g_object_set(G_OBJECT(sink), "ip", "127.0.0.1", NULL);
    > g_object_set(G_OBJECT(sink), "port", 8000, NULL);
    > g_object_set(G_OBJECT(sink), "password", "mypass", NULL);
    > g_object_set(G_OBJECT(sink), "mount", "vivo", NULL);
    >
    > m_volume = gst_element_factory_make("volume", NULL);
    > g_object_set(G_OBJECT(m_volume), "volume", 0.0, NULL);
    >
    > gst_bin_add_many (GST_BIN (m_sink), conv, m_volume, lconv, sink, NULL);
    > gst_element_link_many (conv, m_volume, lconv, sink);
    > gst_element_add_pad (m_sink, gst_ghost_pad_new ("sink", audiopad));
    > gst_object_unref (GST_OBJECT (audiopad));
    > return true;
    > }
    >
    >
    >
    > TODO:
    > Move the hardcoded settings to the xml conf file
    > Made the changes need it to make an auto selecction based on the source
    > (alsasink, autoaudiosink, shout2send).
    > In the case of shout2send we need to leave (mounted) online between
    > playlists and between playlist songs.
    >
    >

  • Paul, can we add this to the trunk, or can we at least document the process of using this to set up streams?
    Douglas Arellanes
    Director of Innovation
    Sourcefabric, o.p.s.

    Find a way or make one.
  • With a litle of work, can send id3tags for metadata stream via shout2send. This is the output of gst_inspect shout2send

    gst-inspect shout2send
    Factory Details:
      Long name:    Icecast network sink
      Class:        Sink/Network
      Description:  Sends data to an icecast server
      Author(s):    Wim Taymans <wim.taymans@chello.be>
    Pedro Corte-Real <typo@netcabo.pt>
    Zaheer Abbas Merali <zaheerabbas at merali dot org>
      Rank:         none (0)
    
    Plugin Details:
      Name:                 shout2send
      Description:          Sends data to an icecast server using libshout2
      Filename:             /usr/lib/gstreamer-0.10/libgstshout2.so
      Version:              0.10.9
      License:              LGPL
      Source module:        gst-plugins-good
      Binary package:       libshout2
      Origin URL:           http://www.icecast.org/download.html
    
    GObject
     +----GstObject
           +----GstElement
                 +----GstBaseSink
                       +----GstShout2send
    
    Implemented Interfaces:
      GstTagSetter
    
    Pad Templates:
      SINK template: 'sink'
        Availability: Always
        Capabilities:
          application/ogg
          audio/mpeg
                mpegversion: 1
                      layer: [ 1, 3 ]
    
    
    Element Flags:
      no flags set
    
    Element Implementation:
      Has change_state() function: gst_base_sink_change_state
      Has custom save_thyself() function: gst_element_save_thyself
      Has custom restore_thyself() function: gst_element_restore_thyself
    
    Element has no clocking capabilities.
    Element has no indexing capabilities.
    Element has no URI handling capabilities.
    
    Pads:
      SINK: 'sink'
        Implementation:
          Has chainfunc(): gst_base_sink_chain
          Has custom eventfunc(): gst_base_sink_event
          Has bufferallocfunc(): gst_base_sink_pad_buffer_alloc
        Pad Template: 'sink'
    
    Element Properties:
      name                : The name of the object
                            flags: readable, writable
                            String. Default: null Current: "shout2send0"
      preroll-queue-len   : Number of buffers to queue during preroll
                            flags: readable, writable
                            Unsigned Integer. Range: 0 - 4294967295 Default: 0 Current: 0
      sync                : Sync on the clock
                            flags: readable, writable
                            Boolean. Default: true Current: false
      max-lateness        : Maximum number of nanoseconds that a buffer can be late before it is dropped (-1 unlimited)
                            flags: readable, writable
                            Integer64. Range: -1 - 9223372036854775807 Default: -1 Current: -1
      qos                 : Generate Quality-of-Service events upstream
                            flags: readable, writable
                            Boolean. Default: false Current: false
      async               : Go asynchronously to PAUSED
                            flags: readable, writable
                            Boolean. Default: true Current: true
      ts-offset           : Timestamp offset in nanoseconds
                            flags: readable, writable
                            Integer64. Range: -9223372036854775808 - 9223372036854775807 Default: 0 Current: 0
      last-buffer         : The last buffer received in the sink
                            flags: readable
                            MiniObject of type "GstBuffer"
      ip                  : ip
                            flags: readable, writable
                            String. Default: "127.0.0.1" Current: "127.0.0.1"
      port                : port
                            flags: readable, writable
                            Integer. Range: 1 - 65535 Default: 8000 Current: 8000
      password            : password
                            flags: readable, writable
                            String. Default: "hackme" Current: "hackme"
      username            : username
                            flags: readable, writable
                            String. Default: "source" Current: "source"
      streamname          : name of the stream
                            flags: readable, writable
                            String. Default: "" Current: ""
      description         : description
                            flags: readable, writable
                            String. Default: "" Current: ""
      genre               : genre
                            flags: readable, writable
                            String. Default: "" Current: ""
      protocol            : Connection Protocol to use
                            flags: readable, writable
                            Enum "GstShout2SendProtocol" Default: 3, "http" Current: 3, "http"
                               (1): xaudiocast       - Xaudiocast Protocol (icecast 1.3.x)
                               (2): icy              - Icy Protocol (ShoutCast)
                               (3): http             - Http Protocol (icecast 2.x)
      mount               : mount
                            flags: readable, writable
                            String. Default: "" Current: ""
      url                 : url
                            flags: readable, writable
                            String. Default: "" Current: ""
    
    Element Signals:
      "connection-problem" :  void user_function (GstElement* object,
                                                  gint arg0,
                                                  gpointer user_data);