Beispiel #1
0
void Shouter::start() {
    char buffer[4096];
    size_t read,ret;

    stop_requested=false;
    refresh_metadata();

    if (shout_open(shout) == SHOUTERR_SUCCESS) {
        printf("Connected to server...\n");
        while (!stop_requested) {

            if(refresh_metadata_requested) {
                refresh_metadata_requested=false;
                log(0,"Refreshing metadata.....");
                do_refresh_metadata();
            }

            read = source->get_data(buffer, 4096);

            if (read > 0) {
                ret = shout_send(shout, (unsigned char*)buffer, read);
                if (ret != SHOUTERR_SUCCESS) {
                    printf("DEBUG: Send error: %s\n", shout_get_error(shout));
                    break;
                }
            } else {
                break;
            }

            shout_sync(shout);
        }
    } else {
        printf("Error connecting: %s\n", shout_get_error(shout));
    }
}
static gboolean
gst_shout2send_connect (GstShout2send * sink)
{
  const char *format =
      (sink->audio_format == SHOUT_FORMAT_VORBIS) ? "vorbis" :
      ((sink->audio_format == SHOUT_FORMAT_MP3) ? "mp3" : "unknown");
#ifdef SHOUT_FORMAT_WEBM
  if (sink->audio_format == SHOUT_FORMAT_WEBM)
    format = "webm";
#endif
  GST_DEBUG_OBJECT (sink, "Connection format is: %s", format);

  if (shout_set_format (sink->conn, sink->audio_format) != SHOUTERR_SUCCESS)
    goto could_not_set_format;

  if (shout_open (sink->conn) != SHOUTERR_SUCCESS)
    goto could_not_connect;

  GST_DEBUG_OBJECT (sink, "connected to server");
  sink->connected = TRUE;

  /* let's set metadata */
  if (sink->songmetadata) {
    shout_metadata_t *pmetadata;

    GST_DEBUG_OBJECT (sink, "shout metadata now: %s", sink->songmetadata);
    pmetadata = shout_metadata_new ();
    shout_metadata_add (pmetadata, "song", sink->songmetadata);
    shout_set_metadata (sink->conn, pmetadata);
    shout_metadata_free (pmetadata);
  }

  return TRUE;

/* ERRORS */
could_not_set_format:
  {
    GST_ELEMENT_ERROR (sink, LIBRARY, SETTINGS, (NULL),
        ("Error setting connection format: %s", shout_get_error (sink->conn)));
    return FALSE;
  }

could_not_connect:
  {
    GST_ELEMENT_ERROR (sink, RESOURCE, OPEN_WRITE,
        (_("Could not connect to server")),
        ("shout_open() failed: err=%s", shout_get_error (sink->conn)));
    g_signal_emit (sink, gst_shout2send_signals[SIGNAL_CONNECTION_PROBLEM], 0,
        shout_get_errno (sink->conn));
    return FALSE;
  }
}
Beispiel #3
0
void EngineShoutcast::write(unsigned char *header, unsigned char *body,
                            int headerLen, int bodyLen) {
    int ret;

    if (!m_pShout)
        return;

    if (m_iShoutStatus == SHOUTERR_CONNECTED) {
        // Send header if there is one
        if ( headerLen > 0 ) {
            ret = shout_send(m_pShout, header, headerLen);
            if (ret != SHOUTERR_SUCCESS) {
                qDebug() << "DEBUG: Send error: " << shout_get_error(m_pShout);
                if ( m_iShoutFailures > 3 ){
                    if(!serverConnect())
                        errorDialog(tr("Lost connection to streaming server"), tr("Please check your connection to the Internet and verify that your username and password are correct."));
                }
                else{
                    m_iShoutFailures++;
                }

                return;
            } else {
                //qDebug() << "yea I kinda sent header";
            }
        }

        ret = shout_send(m_pShout, body, bodyLen);
        if (ret != SHOUTERR_SUCCESS) {
            qDebug() << "DEBUG: Send error: " << shout_get_error(m_pShout);
            if ( m_iShoutFailures > 3 ){
                if(!serverConnect())
                    errorDialog(tr("Lost connection to streaming server"), tr("Please check your connection to the Internet and verify that your username and password are correct."));
            }
            else{
                m_iShoutFailures++;
            }

            return;
        } else {
            //qDebug() << "yea I kinda sent footer";
        }
        if (shout_queuelen(m_pShout) > 0) {
            qDebug() << "DEBUG: queue length:" << (int)shout_queuelen(m_pShout);
        }
    } else {
        qDebug() << "Error connecting to Shoutcast server:" << shout_get_error(m_pShout);
        // errorDialog(tr("Shoutcast aborted connect after 3 tries"), tr("Please check your connection to the Internet and verify that your username and password are correct."));
    }
}
Beispiel #4
0
VideoEncoder::VideoEncoder()
    : Entry(), JSyncThread() {

    initialized = false;
    encbuf = NULL;
    use_audio = false;

    write_to_disk   = false;
    write_to_stream = false;

    filedump_fd = NULL;

    status = NULL;
    audio_kbps = 0;
    video_kbps = 0;
    bytes_encoded = 0;
    m_ElapsedTime = 0;
    m_Streamed = 0;
    enc_y = enc_u = enc_v = NULL;

    fps = new FPS();
    fps->init(25); // default FPS
    // initialize the encoded data pipe
    // TODO: set the size to width * height * 4 * nframes (3-4)
    ringbuffer = ringbuffer_create(1048 * 2096);

    shout_init();
    if((ice = shout_new()) != NULL) {

        if(shout_set_protocol(ice, SHOUT_PROTOCOL_HTTP))
            error("shout_set_protocol: %s", shout_get_error(ice));

        if(shout_set_format(ice, SHOUT_FORMAT_OGG))
            error("shout_set_format: %s", shout_get_error(ice));

        if(shout_set_agent(ice, "FreeJ - freej.dyne.org"))
            error("shout_set_agent: %s", shout_get_error(ice));

        if(shout_set_public(ice, 1))
            error("shout_set_public: %s", shout_get_error(ice));
    }

    func("init picture_yuv for colorspace conversion (avcodec)");
    gettimeofday(&m_OldTime, NULL);

    //uncomment this and beyond to see how long it takes between two frames
    /*  m_OldTime.tv_sec = m_lastTime.tv_sec;
       m_OldTime.tv_usec = m_lastTime.tv_usec;*/
}
Beispiel #5
0
void *shout_thread(void *data) {
	STREAM_HDR *stream;
	size_t n;
	int ret;
	struct timespec nap;
	stream = (STREAM_HDR *)data;
	stream->streaming = 1;
	while (stream->streaming) {
		shout_sync(stream->shout);
		n = jack_ringbuffer_read_space(stream->ringbuf);
		if (n < 1) {
			nap.tv_sec = shout_wait.tv_sec;
			nap.tv_nsec = shout_wait.tv_nsec;
			while (nanosleep(&nap, &nap) != 0);
			continue;
			}
		if (n > stream->shoutbuf_size) {
			if (stream->shoutbuf != NULL) free(stream->shoutbuf);
			stream->shoutbuf = (char *)my_plain_malloc(n, "shout_thread");
			stream->shoutbuf_size = n;
			}
		jack_ringbuffer_read(stream->ringbuf, stream->shoutbuf, n);
		ret = shout_send(stream->shout,
				(const unsigned char *)stream->shoutbuf, n);
		if (ret != SHOUTERR_SUCCESS) {
			log_msg("send err: %s\n",
				shout_get_error(stream->shout));
			}
		}
	return NULL;
	}
Beispiel #6
0
void OutputIceCast::connectStream()
{
    if (getState() != READY && getState() != DISCONNECTED)
        return;

    // if(_shout)
    shout_close(_shout);

    emit stateChanged("connecting");
    int r = shout_open(_shout);
    usleep(1000);
    if (r == SHOUTERR_SUCCESS) {
        _state = CONNECTED;
        emit stateChanged(CONNECTED);
        emit stateChanged("online");
        emit message(QString("Connected to ") + _c.address);
        if (_timer->isActive())
            _timer->stop();
    }
    else {
        if (_timer->isActive()) {
            ++_trial;
        }
        emit warn(shout_get_error(_shout));
        _state = DISCONNECTED;
        emit stateChanged(DISCONNECTED);
        emit stateChanged("offline");
    }
}
Beispiel #7
0
static void reinit_stream() {
    int err;
    int nbTries; 

    if (shout_get_connected(shout) == SHOUTERR_CONNECTED) {
        printf ("Disconnecting the stream\n");
        shout_close(shout);
    }
    
    nbTries = 0; 

    do {
        err = shout_open(shout);
        if ( err != SHOUTERR_SUCCESS) {
            printf ("Failed to connect to server [%s]\n",
                    shout_get_error(shout));
            nbTries++; 

/*             if (nbTries < 10) { */
                printf ("Retrying ... [%d]\n", nbTries);
                sleep(2);
/*             } else { */
/*                 printf("Too many retries. Exiting ...\n"); */
/*                 exit(1); */
/*             } */
        }
    } while (err != SHOUTERR_SUCCESS);

    _setSong(); 

    printf("Connected to server\n");
}
Beispiel #8
0
/*****************************************************************************
 * Write: standard write
 *****************************************************************************/
static int Write( sout_access_out_t *p_access, block_t *p_buffer )
{
    size_t i_write = 0;

    shout_sync( p_access->p_sys->p_shout );
    while( p_buffer )
    {
        block_t *p_next = p_buffer->p_next;

        if( shout_send( p_access->p_sys->p_shout,
                        p_buffer->p_buffer, p_buffer->i_buffer )
             == SHOUTERR_SUCCESS )
        {
            i_write += p_buffer->i_buffer;
        }
        else
        {
            msg_Err( p_access, "cannot write to stream: %s",
                     shout_get_error(p_access->p_sys->p_shout) );
        }
        block_Release( p_buffer );

        /* XXX: Unsure if that's the cause for some audio trouble... */

        p_buffer = p_next;
    }

    return i_write;
}
Beispiel #9
0
static PyObject* pshoutobj_close(ShoutObject* self) {
  if (shout_close(self->conn) != SHOUTERR_SUCCESS) {
    PyErr_SetString(ShoutError, shout_get_error(self->conn));

    return NULL;
  }

  return Py_BuildValue("i", 1);
}
Beispiel #10
0
EngineShoutcast::EngineShoutcast(ConfigObject<ConfigValue>* _config)
        : m_pTextCodec(NULL),
          m_pMetaData(),
          m_pShout(NULL),
          m_pShoutMetaData(NULL),
          m_iMetaDataLife(0),
          m_iShoutStatus(0),
          m_iShoutFailures(0),
          m_pConfig(_config),
          m_encoder(NULL),
          m_pShoutcastNeedUpdateFromPrefs(NULL),
          m_pUpdateShoutcastFromPrefs(NULL),
          m_pMasterSamplerate(new ControlObjectSlave("[Master]", "samplerate")),
          m_pShoutcastStatus(new ControlObject(ConfigKey(SHOUTCAST_PREF_KEY, "status"))),
          m_bQuit(false),
          m_custom_metadata(false),
          m_firstCall(false),
          m_format_is_mp3(false),
          m_format_is_ov(false),
          m_protocol_is_icecast1(false),
          m_protocol_is_icecast2(false),
          m_protocol_is_shoutcast(false),
          m_ogg_dynamic_update(false) {

#ifndef __WINDOWS__
    // Ignore SIGPIPE signals that we get when the remote streaming server
    // disconnects.
    signal(SIGPIPE, SIG_IGN);
#endif

    m_pShoutcastStatus->set(SHOUTCAST_DISCONNECTED);
    m_pShoutcastNeedUpdateFromPrefs = new ControlObject(
            ConfigKey(SHOUTCAST_PREF_KEY,"update_from_prefs"));
    m_pUpdateShoutcastFromPrefs = new ControlObjectSlave(
            m_pShoutcastNeedUpdateFromPrefs->getKey());

    // Initialize libshout
    shout_init();

    if (!(m_pShout = shout_new())) {
        errorDialog(tr("Mixxx encountered a problem"), tr("Could not allocate shout_t"));
        return;
    }

    if (!(m_pShoutMetaData = shout_metadata_new())) {
        errorDialog(tr("Mixxx encountered a problem"), tr("Could not allocate shout_metadata_t"));
        return;
    }
    if (shout_set_nonblocking(m_pShout, 1) != SHOUTERR_SUCCESS) {
        errorDialog(tr("Error setting non-blocking mode:"), shout_get_error(m_pShout));
        return;
    }
}
Beispiel #11
0
void OutputIceCast::applyStreamInfo()
{
    int r;
    r = shout_set_name(_shout, _csi.name.toStdString().c_str());
    if (r != SHOUTERR_SUCCESS) {
        emit error(QString("unable to set name: ") + shout_get_error(_shout));
    }
    r = shout_set_genre(_shout, _csi.genre.toStdString().c_str());
    if (r != SHOUTERR_SUCCESS) {
        emit error(QString("unable to set genre: ") + shout_get_error(_shout));
    }
    r = shout_set_url(_shout, _csi.url.toStdString().c_str());
    if (r != SHOUTERR_SUCCESS) {
        emit error(QString("unable to set url: ") + shout_get_error(_shout));
    }
    r = shout_set_agent(_shout, _csi.agent.toStdString().c_str());
    if (r != SHOUTERR_SUCCESS) {
        emit error(QString("unable to set agent: ") + shout_get_error(_shout));
    }
    r = shout_set_description(_shout, _csi.description.toStdString().c_str());
    if (r != SHOUTERR_SUCCESS) {
        emit error(QString("unable to set description: ") + shout_get_error(_shout));
    }
    r = shout_set_public(_shout, static_cast<int>(_csi.isPublic));
    if (r != SHOUTERR_SUCCESS) {
        emit error(QString("unable to set description: ") + shout_get_error(_shout));
    }
    // TODO set metadata
    //shout_set_metadata
}
static GstFlowReturn
gst_shout2send_render (GstBaseSink * basesink, GstBuffer * buf)
{
  GstShout2send *sink;
  glong ret;
  gint delay;
  GstFlowReturn fret;
  GstMapInfo map;

  sink = GST_SHOUT2SEND (basesink);

  /* presumably we connect here because we need to know the format before
   * we can set up the connection, which we don't know yet in _start() */
  if (!sink->connected) {
    if (!gst_shout2send_connect (sink))
      return GST_FLOW_ERROR;
  }

  delay = shout_delay (sink->conn);

  if (delay > 0) {
    GST_LOG_OBJECT (sink, "waiting %d msec", delay);
    if (gst_poll_wait (sink->timer, GST_MSECOND * delay) == -1) {
      GST_LOG_OBJECT (sink, "unlocked");

      fret = gst_base_sink_wait_preroll (basesink);
      if (fret != GST_FLOW_OK)
        return fret;
    }
  } else {
    GST_LOG_OBJECT (sink, "we're %d msec late", -delay);
  }

  gst_buffer_map (buf, &map, GST_MAP_READ);
  GST_LOG_OBJECT (sink, "sending %u bytes of data", (guint) map.size);
  ret = shout_send (sink->conn, map.data, map.size);
  gst_buffer_unmap (buf, &map);
  if (ret != SHOUTERR_SUCCESS)
    goto send_error;

  return GST_FLOW_OK;

/* ERRORS */
send_error:
  {
    GST_ELEMENT_ERROR (sink, RESOURCE, WRITE, (NULL),
        ("shout_send() failed: %s", shout_get_error (sink->conn)));
    g_signal_emit (sink, gst_shout2send_signals[SIGNAL_CONNECTION_PROBLEM], 0,
        shout_get_errno (sink->conn));
    return GST_FLOW_ERROR;
  }
}
Beispiel #13
0
static PyObject* pshoutobj_open(ShoutObject* self) {
  int ret;
  Py_BEGIN_ALLOW_THREADS
  ret=shout_open(self->conn);
  Py_END_ALLOW_THREADS
  if (!((ret == SHOUTERR_SUCCESS)||
        ((ret==SHOUTERR_BUSY) && shout_get_nonblocking(self->conn)))) {
    PyErr_SetString(ShoutError, shout_get_error(self->conn));

    return NULL;
  }

  return Py_BuildValue("i", 1);
}
Beispiel #14
0
bool Shouter::initialize() {

    source->initialize();

    shout_init();

    if (!(shout = shout_new())) {
        printf("Could not allocate shout_t\n");
        return 0;
    }

    if (shout_set_host(shout, hostname.c_str()) != SHOUTERR_SUCCESS) {
        printf("Error setting hostname: %s\n", shout_get_error(shout));
        return 0;
    }

    if (shout_set_protocol(shout, protocol) != SHOUTERR_SUCCESS) {
        printf("Error setting protocol: %s\n", shout_get_error(shout));
        return 0;
    }

    if (shout_set_port(shout, port) != SHOUTERR_SUCCESS) {
        printf("Error setting port: %s\n", shout_get_error(shout));
        return 0;
    }

    if (shout_set_password(shout, password.c_str()) != SHOUTERR_SUCCESS) {
        printf("Error setting password: %s\n", shout_get_error(shout));
        return 0;
    }
    if (shout_set_mount(shout, mountpoint.c_str()) != SHOUTERR_SUCCESS) {
        printf("Error setting mount: %s\n", shout_get_error(shout));
        return 0;
    }

    if (shout_set_user(shout, user_name.c_str()) != SHOUTERR_SUCCESS) {
        printf("Error setting user: %s\n", shout_get_error(shout));
        return 0;
    }

    if (shout_set_format(shout, format) != SHOUTERR_SUCCESS) {
        printf("Error setting user: %s\n", shout_get_error(shout));
        return 0;
    }
    
    shout_set_agent(shout,"Shouter");
    shout_set_description(shout, stream_description.c_str());
    shout_set_genre(shout, stream_genre.c_str());
    shout_set_name(shout, stream_name.c_str());
    shout_set_url(shout, stream_url.c_str());
    
}
Beispiel #15
0
/*****************************************************************************
 * Write: standard write
 *****************************************************************************/
static ssize_t Write( sout_access_out_t *p_access, block_t *p_buffer )
{
    sout_access_out_sys_t *p_sys = p_access->p_sys;
    size_t i_write = 0;

    shout_sync( p_sys->p_shout );
    while( p_buffer )
    {
        block_t *p_next = p_buffer->p_next;

        if( shout_send( p_sys->p_shout, p_buffer->p_buffer, p_buffer->i_buffer )
             == SHOUTERR_SUCCESS )
        {
            i_write += p_buffer->i_buffer;
        }
        else
        {
            msg_Err( p_access, "cannot write to stream: %s",
                     shout_get_error( p_sys->p_shout ) );

            /* The most common cause seems to be a server disconnect, resulting in a
               Socket Error which can only be fixed by closing and reconnecting.
               Since we already began with a working connection, the most feasable
               approach to get out of this error status is a (timed) reconnect approach. */
            shout_close( p_sys->p_shout );
            msg_Warn( p_access, "server unavailable? trying to reconnect..." );
            /* Re-open the connection (protocol params have already been set) and re-sync */
            if( shout_open( p_sys->p_shout ) == SHOUTERR_SUCCESS )
            {
                shout_sync( p_sys->p_shout );
                msg_Warn( p_access, "reconnected to server" );
            }
            else
            {
                msg_Err( p_access, "failed to reconnect to server" );
                block_ChainRelease( p_buffer );
                return VLC_EGENERIC;
            }

        }
        block_Release( p_buffer );

        /* XXX: Unsure if that's the cause for some audio trouble... */

        p_buffer = p_next;
    }

    return i_write;
}
Beispiel #16
0
static PyObject* pshoutobj_send(ShoutObject* self, PyObject* args) {
  const unsigned char* data;
  size_t len;

  if (!PyArg_ParseTuple(args, "s#", &data, &len))
    return NULL;

  if (shout_send(self->conn, data, len) != SHOUTERR_SUCCESS) {
    PyErr_SetString(ShoutError, shout_get_error(self->conn));

    return NULL;
  }

  return Py_BuildValue("i", 1);
}
Beispiel #17
0
bool OutputIceCast::applyConnection()
{
    int r;
    r = shout_set_host(_shout, _c.address.toStdString().c_str());
    if (r != SHOUTERR_SUCCESS) {
        emit error(QString("unable to set hostname: ") + shout_get_error(_shout));
        return false;
    }
    if (_c.protocol == "Icecast 1")
        r = shout_set_protocol(_shout, SHOUT_PROTOCOL_XAUDIOCAST);
    else if (_c.protocol == "Icecast 2")
        r = shout_set_protocol(_shout, SHOUT_PROTOCOL_HTTP);
    else if (_c.protocol == "Shoutcast")
        r = shout_set_protocol(_shout, SHOUT_PROTOCOL_ICY);
    if (r != SHOUTERR_SUCCESS) {
        emit error(QString("unable to set protocol: ") + shout_get_error(_shout));
        return false;
    }
    r = shout_set_port(_shout, _c.port);
    if (r != SHOUTERR_SUCCESS) {
        emit error(QString("unable to set port: ") + shout_get_error(_shout));
        return false;
    }
    r = shout_set_mount(_shout, _c.mountpoint.toStdString().c_str());
    if (r != SHOUTERR_SUCCESS) {
        emit error(QString("unable to set mountpoint: ") + shout_get_error(_shout));
        return false;
    }
    r = shout_set_user(_shout, _c.user.toStdString().c_str());
    if (r != SHOUTERR_SUCCESS) {
        emit error(QString("unable to set user: "******"unable to set password: "******"Lame MP3"))
        r = shout_set_format(_shout, SHOUT_FORMAT_MP3);
    else if (_c.encoder == QString("Ogg Vorbis"))
        r = shout_set_format(_shout, SHOUT_FORMAT_OGG);
    if (r != SHOUTERR_SUCCESS) {
        emit error(QString("unable to set protocol: ") + shout_get_error(_shout));
        return false;
    }
    return true;
}
Beispiel #18
0
void OutputIceCast::output(const char* buffer, uint32_t size)
{
    if (getState() != CONNECTED)
        return;

    if (size != 0) {
        int r = shout_send(_shout, ( const unsigned char* )buffer, size);
        if (r != SHOUTERR_SUCCESS) {
            emit warn(QString("send error: ") + shout_get_error(_shout));
            _state = DISCONNECTED;
            emit stateChanged(DISCONNECTED);
            emit stateChanged("offline");
            emit requestReconnect();
            _trial = 0;
        }
        shout_sync(_shout);
    }
}
Beispiel #19
0
int
reconnectServer(shout_t *shout, int closeConn)
{
	unsigned int	i;
	int		close_conn = closeConn;

	printf("%s: Connection to %s lost\n", __progname, pezConfig->URL);

	i = 0;
	while (++i) {
		printf("%s: Attempting reconnection #", __progname);
		if (pezConfig->reconnectAttempts > 0)
			printf("%u/%u: ", i,
			       pezConfig->reconnectAttempts);
		else
			printf("%u: ", i);

		if (close_conn == 0)
			close_conn = 1;
		else
			shout_close(shout);
		if (shout_open(shout) == SHOUTERR_SUCCESS) {
			printf("OK\n%s: Reconnect to %s successful\n",
			       __progname, pezConfig->URL);
			return (1);
		}

		printf("FAILED: %s\n", shout_get_error(shout));

		if (pezConfig->reconnectAttempts > 0 &&
		    i >= pezConfig->reconnectAttempts)
			break;

		printf("%s: Waiting 5s for %s to come back ...\n",
		       __progname, pezConfig->URL);
		if (quit)
			return (0);
		else
			sleep(5);
	};

	printf("%s: Giving up\n", __progname);
	return (0);
}
Beispiel #20
0
bool Shouter::start() {
    int res;
    char srv[64];
    switch(login()) {
    case SHOUT_PROTOCOL_HTTP:
        sprintf(srv,"icecast2");
        break;
    case SHOUT_PROTOCOL_ICY:
        sprintf(srv,"shoutcast");
        break;
    default:
        sprintf(srv,"icecast 1");
        break;
    }

    if(shout_get_connected(ice)) {
        // if allready connected, reconnect
        func("icecast still connected: disconnecting");
        shout_sync(ice);
        shout_close(ice);
    }

    notice("Contacting %s server %s on port %u",srv,host(),port());

    shout_sync(ice);
    res = shout_open(ice);
    func("Shouter::start() shout_open returns %i",res);

    if(res==SHOUTERR_SUCCESS) {
        notice("started streaming on %s",streamurl);
        running = true;
    } else {
        error("shout_open: %s",shout_get_error(ice));
        shout_sync(ice);
        shout_close(ice);
        running = false;
    }

    return(running);
}
Beispiel #21
0
int Shouter::send(short int *buf, unsigned int enc) {
    int res = 0;
    if(!running) return(0);
    if(enc<1) return res;

    shout_sync(ice);

    res = shout_send(ice,(unsigned char*) buf, enc);
    if(res) {
        error("shout_send: %s",shout_get_error(ice));
        if (got_sigpipe && (res==SHOUTERR_SOCKET)) {
            errors++;
            got_sigpipe = false;
            if(errors>10) {
                res = -2;
                errors = 0;
            }
        } else res = -1;
    } else errors = 0;

    return(res);
}
Beispiel #22
0
static int pshoutobj_setattr(PyObject* self, char* name, PyObject* v) {
  ShoutObject* me = (ShoutObject*)self;
  ShoutObjectAttr* attr;

  if (!me->attr && !(me->attr = PyDict_New()))
    return -1;

  if (v == NULL)
    return -1;
  
  for (attr = ShoutObjectAttrs; attr->name; attr++) {
    if (!strcmp(attr->name, name)) {
      if (v != Py_None && attr->set(attr, me, v) != SHOUTERR_SUCCESS) {
	if (!PyErr_Occurred())
	  PyErr_SetString(ShoutError, shout_get_error(me->conn));
        return -1;
      }
      break;
    }
  }

  return PyDict_SetItemString(me->attr, name, v);
}
Beispiel #23
0
static GstFlowReturn
gst_shout2send_render (GstBaseSink * basesink, GstBuffer * buf)
{
  GstShout2send *sink;
  glong ret;

  sink = GST_SHOUT2SEND (basesink);

  /* presumably we connect here because we need to know the format before
   * we can set up the connection, which we don't know yet in _start() */
  if (!sink->connected) {
    if (!gst_shout2send_connect (sink))
      return GST_FLOW_ERROR;
  }

  /* FIXME: do we want to do syncing here at all? (tpm) */
  /* GST_LOG_OBJECT (sink, "using libshout to sync"); */
  shout_sync (sink->conn);

  GST_LOG_OBJECT (sink, "sending %u bytes of data", GST_BUFFER_SIZE (buf));
  ret = shout_send (sink->conn, GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf));
  if (ret != SHOUTERR_SUCCESS)
    goto send_error;

  return GST_FLOW_OK;

/* ERRORS */
send_error:
  {
    GST_ELEMENT_ERROR (sink, RESOURCE, WRITE, (NULL),
        ("shout_send() failed: %s", shout_get_error (sink->conn)));
    g_signal_emit (sink, gst_shout2send_signals[SIGNAL_CONNECTION_PROBLEM], 0,
        shout_get_errno (sink->conn));
    return GST_FLOW_ERROR;
  }
}
Beispiel #24
0
static switch_status_t shout_file_write(switch_file_handle_t *handle, void *data, size_t *len)
{
	shout_context_t *context;
	int rlen = 0;
	int16_t *audio = data;
	size_t nsamples = *len;

	if (!handle) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error no handle\n");
		return SWITCH_STATUS_FALSE;
	}

	if (!(context = handle->private_info)) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error no context\n");
		return SWITCH_STATUS_FALSE;
	}

	if (context->err) {
		return SWITCH_STATUS_FALSE;
	}

	if (context->shout && !context->shout_init) {

		if (!context->gfp) {
			return SWITCH_STATUS_FALSE;
		}

		context->shout_init++;
		if (shout_open(context->shout) != SHOUTERR_SUCCESS) {
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error opening stream: %s\n", shout_get_error(context->shout));
			context->err++;
			return SWITCH_STATUS_FALSE;
		}
		launch_write_stream_thread(context);
	}

	if (handle->handler && context->audio_mutex) {
		switch_mutex_lock(context->audio_mutex);
		if (context->audio_buffer) {
			if (!switch_buffer_write(context->audio_buffer, data, (nsamples * sizeof(int16_t) * handle->channels))) {
				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Buffer error\n");
				context->err++;
			}
		} else {
			context->err++;
		}

		switch_mutex_unlock(context->audio_mutex);
		if (context->err) {
			return SWITCH_STATUS_FALSE;
		}

		handle->sample_count += *len;
		return SWITCH_STATUS_SUCCESS;
	}

	if (!context->lame_ready) {
		lame_init_params(context->gfp);
		lame_print_config(context->gfp);
		context->lame_ready = 1;
	}

	if (context->mp3buflen < nsamples * 4) {
		context->mp3buflen = nsamples * 4;
		context->mp3buf = switch_core_alloc(context->memory_pool, context->mp3buflen);
	}

	if (handle->channels == 2) {
		switch_size_t i, j = 0;

		if (context->llen < nsamples) {
			context->l = switch_core_alloc(context->memory_pool, nsamples * 2);
			context->r = switch_core_alloc(context->memory_pool, nsamples * 2);
			context->llen = context->rlen = nsamples;
		}

		for (i = 0; i < nsamples; i++) {
			context->l[i] = audio[j++];
			context->r[i] = audio[j++];
		}

		if ((rlen = lame_encode_buffer(context->gfp, context->l, context->r, nsamples, context->mp3buf, context->mp3buflen)) < 0) {
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "MP3 encode error %d!\n", rlen);
			return SWITCH_STATUS_FALSE;
		}

	} else if (handle->channels == 1) {
		if ((rlen = lame_encode_buffer(context->gfp, audio, NULL, nsamples, context->mp3buf, context->mp3buflen)) < 0) {
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "MP3 encode error %d!\n", rlen);
			return SWITCH_STATUS_FALSE;
		}
	} else {
		rlen = 0;
	}

	if (rlen) {
		int ret = fwrite(context->mp3buf, 1, rlen, context->fp);
		if (ret < 0) {
			return SWITCH_STATUS_FALSE;
		}
	}

	handle->sample_count += *len;

	return SWITCH_STATUS_SUCCESS;
}
Beispiel #25
0
static switch_status_t shout_file_set_string(switch_file_handle_t *handle, switch_audio_col_t col, const char *string)
{
	shout_context_t *context = handle->private_info;
	switch_status_t status = SWITCH_STATUS_FALSE;

	if (!context->shout) {
		switch (col) {
		case SWITCH_AUDIO_COL_STR_TITLE:
			id3tag_set_title(context->gfp, string);
			break;
		case SWITCH_AUDIO_COL_STR_COMMENT:
			id3tag_set_comment(context->gfp, string);
			break;
		case SWITCH_AUDIO_COL_STR_ARTIST:
			id3tag_set_artist(context->gfp, string);
			break;
		case SWITCH_AUDIO_COL_STR_DATE:
			id3tag_set_year(context->gfp, string);
			break;
		case SWITCH_AUDIO_COL_STR_SOFTWARE:
			break;
			id3tag_set_album(context->gfp, string);
		case SWITCH_AUDIO_COL_STR_COPYRIGHT:
			id3tag_set_genre(context->gfp, string);
			break;
		default:
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Value Ignored %d, %s\n", col, string);
			break;
		}

		return status;
	}

	switch (col) {
	case SWITCH_AUDIO_COL_STR_TITLE:
		if (shout_set_name(context->shout, string) == SHOUTERR_SUCCESS) {
			status = SWITCH_STATUS_SUCCESS;
		} else {
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error setting name: %s\n", shout_get_error(context->shout));
		}
		break;
	case SWITCH_AUDIO_COL_STR_COMMENT:
		if (shout_set_url(context->shout, string) == SHOUTERR_SUCCESS) {
			status = SWITCH_STATUS_SUCCESS;
		} else {
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error setting name: %s\n", shout_get_error(context->shout));
		}
		break;
	case SWITCH_AUDIO_COL_STR_ARTIST:
		if (shout_set_description(context->shout, string) == SHOUTERR_SUCCESS) {
			status = SWITCH_STATUS_SUCCESS;
		} else {
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error setting name: %s\n", shout_get_error(context->shout));
		}
		break;
	default:
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Value Ignored %d, %s\n", col, string);
		break;
	}

	return status;
}
Beispiel #26
0
static switch_status_t shout_file_open(switch_file_handle_t *handle, const char *path)
{
	shout_context_t *context;
	char *host, *file;
	char *username, *password, *port;
	char *err = NULL;
	const char *mpg123err = NULL;
	int portno = 0;

	if ((context = switch_core_alloc(handle->memory_pool, sizeof(*context))) == 0) {
		return SWITCH_STATUS_MEMERR;
	}

	if (!handle->samplerate) {
		handle->samplerate = 8000;
	}

	context->memory_pool = handle->memory_pool;
	context->samplerate = handle->samplerate;
	context->handle = handle;

	switch_thread_rwlock_create(&(context->rwlock), context->memory_pool);

	switch_thread_rwlock_rdlock(context->rwlock);

	switch_mutex_init(&context->audio_mutex, SWITCH_MUTEX_NESTED, context->memory_pool);

	if (switch_test_flag(handle, SWITCH_FILE_FLAG_READ)) {
		if (switch_buffer_create_dynamic(&context->audio_buffer, TC_BUFFER_SIZE, TC_BUFFER_SIZE * 2, 0) != SWITCH_STATUS_SUCCESS) {
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Memory Error!\n");
			goto error;
		}

		context->mh = our_mpg123_new(NULL, NULL);
		if (mpg123_format_all(context->mh) != MPG123_OK) {
			MPGERROR();
		}
		if (mpg123_param(context->mh, MPG123_FORCE_RATE, context->samplerate, 0) != MPG123_OK) {
			MPGERROR();
		}

		if (handle->handler) {
			if (mpg123_param(context->mh, MPG123_FLAGS, MPG123_SEEKBUFFER | MPG123_MONO_MIX, 0) != MPG123_OK) {
				MPGERROR();
			}
			if (mpg123_open_feed(context->mh) != MPG123_OK) {
				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error opening mpg feed\n");
				mpg123err = mpg123_strerror(context->mh);
				goto error;
			}
			context->stream_url = switch_core_sprintf(context->memory_pool, "http://%s", path);
			context->prebuf = handle->prebuf;
			launch_read_stream_thread(context);
		} else {
			handle->seekable = 1;
			if (mpg123_param(context->mh, MPG123_FLAGS, MPG123_MONO_MIX, 0) != MPG123_OK) {
				MPGERROR();
			}
			if (mpg123_open(context->mh, path) != MPG123_OK) {
				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error opening %s\n", path);
				mpg123err = mpg123_strerror(context->mh);
				goto error;
			}

		}
	} else if (switch_test_flag(handle, SWITCH_FILE_FLAG_WRITE)) {
		if (switch_test_flag(handle, SWITCH_FILE_WRITE_APPEND)) {
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Appending to MP3 not supported.\n");
		}
		if (!(context->gfp = lame_init())) {
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not allocate lame\n");
			goto error;
		}

		if (!handle->handler) {
			id3tag_init(context->gfp);
			id3tag_v2_only(context->gfp);
			id3tag_pad_v2(context->gfp);

		}
		context->channels = handle->channels;
		lame_set_brate(context->gfp, 16 * (handle->samplerate / 8000) * handle->channels);
		lame_set_num_channels(context->gfp, handle->channels);
		lame_set_in_samplerate(context->gfp, handle->samplerate);
		lame_set_out_samplerate(context->gfp, handle->samplerate);

		if (handle->channels == 2) {
			lame_set_mode(context->gfp, STEREO);
		} else {
			lame_set_mode(context->gfp, MONO);
		}
		lame_set_quality(context->gfp, 2);	/* 2=high  5 = medium  7=low */

		lame_set_errorf(context->gfp, log_error);
		lame_set_debugf(context->gfp, log_debug);
		lame_set_msgf(context->gfp, log_msg);

		if (handle->handler) {
			if (switch_buffer_create_dynamic(&context->audio_buffer, MY_BLOCK_SIZE, MY_BUF_LEN, 0) != SWITCH_STATUS_SUCCESS) {
				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Memory Error!\n");
				goto error;
			}
			lame_set_bWriteVbrTag(context->gfp, 0);
			lame_mp3_tags_fid(context->gfp, NULL);

			username = switch_core_strdup(handle->memory_pool, path);
			if (!(password = strchr(username, ':'))) {
				err = "invalid url";
				goto error;
			}
			*password++ = '\0';

			if (!(host = strchr(password, '@'))) {
				err = "invalid url";
				goto error;
			}
			*host++ = '\0';

			if ((file = strchr(host, '/'))) {
				*file++ = '\0';
			} else {
				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid URL: %s\n", path);
				goto error;
			}

			if ((port = strchr(host, ':'))) {
				*port++ = '\0';
				if (port) {
					portno = atoi(port);
				}
			}

			if (!portno) {
				portno = 8000;
			}

			if (!(context->shout = shout_new())) {
				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not allocate shout_t\n");
				goto error;
			}

			if (shout_set_host(context->shout, host) != SHOUTERR_SUCCESS) {
				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error setting hostname: %s\n", shout_get_error(context->shout));
				goto error;
			}

			if (shout_set_protocol(context->shout, SHOUT_PROTOCOL_HTTP) != SHOUTERR_SUCCESS) {
				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error setting protocol: %s\n", shout_get_error(context->shout));
				goto error;
			}

			if (shout_set_port(context->shout, portno) != SHOUTERR_SUCCESS) {
				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error setting port: %s\n", shout_get_error(context->shout));
				goto error;
			}

			if (shout_set_password(context->shout, password) != SHOUTERR_SUCCESS) {
				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error setting password: %s\n", shout_get_error(context->shout));
				goto error;
			}

			if (shout_set_mount(context->shout, file) != SHOUTERR_SUCCESS) {
				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error setting mount: %s\n", shout_get_error(context->shout));
				goto error;
			}

			if (shout_set_user(context->shout, username) != SHOUTERR_SUCCESS) {
				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error setting user: %s\n", shout_get_error(context->shout));
				goto error;
			}

			if (shout_set_url(context->shout, "http://www.freeswitch.org") != SHOUTERR_SUCCESS) {
				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error setting name: %s\n", shout_get_error(context->shout));
				goto error;
			}

			if (shout_set_description(context->shout, "FreeSWITCH mod_shout Broadcasting Module") != SHOUTERR_SUCCESS) {
				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error setting description: %s\n", shout_get_error(context->shout));
				goto error;
			}

			if (shout_set_audio_info(context->shout, "bitrate", "24000") != SHOUTERR_SUCCESS) {
				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error setting bitrate: %s\n", shout_get_error(context->shout));
				goto error;
			}

			if (shout_set_format(context->shout, SHOUT_FORMAT_MP3) != SHOUTERR_SUCCESS) {
				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error setting format: %s\n", shout_get_error(context->shout));
				goto error;
			}

		} else {
			/* lame being lame and all has FILE * coded into it's API for some functions so we gotta use it */
			if (!(context->fp = fopen(path, "wb+"))) {
				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error opening %s\n", path);
				goto error;
			}
		}
	}

	handle->samples = 0;
	handle->format = 0;
	handle->sections = 0;
	handle->speed = 0;
	handle->private_info = context;
	switch_thread_rwlock_unlock(context->rwlock);

	return SWITCH_STATUS_SUCCESS;

  error:
	switch_thread_rwlock_unlock(context->rwlock);
	if (err) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error: %s\n", err);
	}
	if (mpg123err) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error from mpg123: %s\n", mpg123err);
	}
	free_context(context);
	return SWITCH_STATUS_GENERR;

}
Beispiel #27
0
static void *SWITCH_THREAD_FUNC write_stream_thread(switch_thread_t *thread, void *obj)
{
	shout_context_t *context = (shout_context_t *) obj;

	switch_thread_rwlock_rdlock(context->rwlock);

	if (context->thread_running) {
		context->thread_running++;
	} else {
		switch_thread_rwlock_unlock(context->rwlock);
		return NULL;
	}

	if (!context->lame_ready) {
		lame_init_params(context->gfp);
		lame_print_config(context->gfp);
		context->lame_ready = 1;
	}

	while (!context->err && context->thread_running) {
		unsigned char mp3buf[8192] = "";
		int16_t audio[9600] = { 0 };
		switch_size_t audio_read = 0;
		int rlen = 0;
		long ret = 0;

		switch_mutex_lock(context->audio_mutex);
		if (context->audio_buffer) {
			audio_read = switch_buffer_read(context->audio_buffer, audio, sizeof(audio));
		} else {
			context->err++;
		}
		switch_mutex_unlock(context->audio_mutex);

		error_check();

		if (!audio_read) {
			audio_read = sizeof(audio);
			memset(audio, 255, sizeof(audio));
		}

		if (context->channels == 2) {
			int16_t l[4800] = { 0 };
			int16_t r[4800] = { 0 };
			int j = 0;
			switch_size_t i;

			for (i = 0; i < audio_read / 4; i++) {
				l[i] = audio[j++];
				r[i] = audio[j++];
			}

			if ((rlen = lame_encode_buffer(context->gfp, l, r, audio_read / 4, mp3buf, sizeof(mp3buf))) < 0) {
				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "MP3 encode error %d!\n", rlen);
				goto error;
			}

		} else if (context->channels == 1) {
			if ((rlen = lame_encode_buffer(context->gfp, (void *) audio, NULL, audio_read / sizeof(int16_t), mp3buf, sizeof(mp3buf))) < 0) {
				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "MP3 encode error %d!\n", rlen);
				goto error;
			}
		}

		if (rlen) {
			ret = shout_send(context->shout, mp3buf, rlen);
			if (ret != SHOUTERR_SUCCESS) {
				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Send error: %s\n", shout_get_error(context->shout));
				goto error;
			}
		} else {
			memset(mp3buf, 0, 128);
			ret = shout_send(context->shout, mp3buf, 128);
		}

		shout_sync(context->shout);
		switch_yield(100000);
	}

  error:
	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Write Thread Done\n");
	switch_thread_rwlock_unlock(context->rwlock);
	context->thread_running = 0;
	return NULL;
}
Beispiel #28
0
int
setMetadata(shout_t *shout, metadata_t *mdata, char **mdata_copy)
{
	shout_metadata_t	*shout_mdata = NULL;
	char			*songInfo;
	const char		*artist, *title;
	int			 ret = SHOUTERR_SUCCESS;

	if (shout == NULL) {
		printf("%s: setMetadata(): Internal error: NULL shout_t\n",
		       __progname);
		abort();
	}

	if (mFlag)
		return (SHOUTERR_SUCCESS);

	if (mdata == NULL)
		return 1;

	if ((shout_mdata = shout_metadata_new()) == NULL) {
		printf("%s: shout_metadata_new(): %s\n", __progname,
		       strerror(ENOMEM));
		exit(1);
	}

	artist = metadata_get_artist(mdata);
	title = metadata_get_title(mdata);

	/*
	 * We can do this, because we know how libshout works. This adds
	 * "charset=UTF-8" to the HTTP metadata update request and has the
	 * desired effect of letting newer-than-2.3.1 versions of Icecast know
	 * which encoding we're using.
	 */
	if (shout_metadata_add(shout_mdata, "charset", "UTF-8") != SHOUTERR_SUCCESS) {
		/* Assume SHOUTERR_MALLOC */
		printf("%s: shout_metadata_add(): %s\n", __progname,
		       strerror(ENOMEM));
		exit(1);
	}

	if ((songInfo = getMetadataString(pezConfig->metadataFormat, mdata)) == NULL) {
		if (artist[0] == '\0' && title[0] == '\0')
			songInfo = xstrdup(metadata_get_string(mdata));
		else
			songInfo = metadata_assemble_string(mdata);
		if (artist[0] != '\0' && title[0] != '\0') {
			if (shout_metadata_add(shout_mdata, "artist", artist) != SHOUTERR_SUCCESS) {
				printf("%s: shout_metadata_add(): %s\n", __progname,
				       strerror(ENOMEM));
				exit(1);
			}
			if (shout_metadata_add(shout_mdata, "title", title) != SHOUTERR_SUCCESS) {
				printf("%s: shout_metadata_add(): %s\n", __progname,
				       strerror(ENOMEM));
				exit(1);
			}
		} else {
			if (shout_metadata_add(shout_mdata, "song", songInfo) != SHOUTERR_SUCCESS) {
				printf("%s: shout_metadata_add(): %s\n", __progname,
				       strerror(ENOMEM));
				exit(1);
			}
		}
	} else if (shout_metadata_add(shout_mdata, "song", songInfo) != SHOUTERR_SUCCESS) {
		printf("%s: shout_metadata_add(): %s\n", __progname,
		       strerror(ENOMEM));
		exit(1);
	}

	if ((ret = shout_set_metadata(shout, shout_mdata)) != SHOUTERR_SUCCESS)
		printf("%s: shout_set_metadata(): %s\n",
		       __progname, shout_get_error(shout));

	shout_metadata_free(shout_mdata);

	if (ret == SHOUTERR_SUCCESS) {
		if (mdata_copy != NULL && *mdata_copy == NULL)
			*mdata_copy = xstrdup(songInfo);
	}

	xfree(songInfo);
	return (ret);
}
Beispiel #29
0
/*****************************************************************************
 * Open: open the shout connection
 *****************************************************************************/
static int Open( vlc_object_t *p_this )
{
    sout_access_out_t *p_access = (sout_access_out_t*)p_this;
    sout_access_out_sys_t *p_sys;
    shout_t *p_shout;
    long i_ret;
    char *psz_val;

    char *psz_name;
    char *psz_description;
    char *psz_genre;
    char *psz_url;
    vlc_url_t url;

    config_ChainParse( p_access, SOUT_CFG_PREFIX, ppsz_sout_options, p_access->p_cfg );

    if( !p_access->psz_path )
    {
        msg_Err( p_access,
                 "please specify url=user:password@host:port/mountpoint" );
        return VLC_EGENERIC;
    }

    vlc_UrlParse( &url , p_access->psz_path, 0 );
    if( url.i_port <= 0 )
        url.i_port = 8000;

    p_sys = p_access->p_sys = malloc( sizeof( sout_access_out_sys_t ) );
    if( !p_sys )
    {
        vlc_UrlClean( &url );
        return VLC_ENOMEM;
    }

    psz_name = var_GetNonEmptyString( p_access, SOUT_CFG_PREFIX "name" );
    psz_description = var_GetNonEmptyString( p_access, SOUT_CFG_PREFIX "description" );
    psz_genre = var_GetNonEmptyString( p_access, SOUT_CFG_PREFIX "genre" );
    psz_url = var_GetNonEmptyString( p_access, SOUT_CFG_PREFIX "url" );

    p_shout = p_sys->p_shout = shout_new();
    if( !p_shout
         || shout_set_host( p_shout, url.psz_host ) != SHOUTERR_SUCCESS
         || shout_set_protocol( p_shout, SHOUT_PROTOCOL_ICY ) != SHOUTERR_SUCCESS
         || shout_set_port( p_shout, url.i_port ) != SHOUTERR_SUCCESS
         || shout_set_password( p_shout, url.psz_password ) != SHOUTERR_SUCCESS
         || shout_set_mount( p_shout, url.psz_path ) != SHOUTERR_SUCCESS
         || shout_set_user( p_shout, url.psz_username ) != SHOUTERR_SUCCESS
         || shout_set_agent( p_shout, "VLC media player " VERSION ) != SHOUTERR_SUCCESS
         || shout_set_name( p_shout, psz_name ) != SHOUTERR_SUCCESS
         || shout_set_description( p_shout, psz_description ) != SHOUTERR_SUCCESS
         || shout_set_genre( p_shout, psz_genre ) != SHOUTERR_SUCCESS
         || shout_set_url( p_shout, psz_url ) != SHOUTERR_SUCCESS
         /* || shout_set_nonblocking( p_shout, 1 ) != SHOUTERR_SUCCESS */
      )
    {
        msg_Err( p_access, "failed to initialize shout streaming to %s:%i/%s",
                 url.psz_host, url.i_port, url.psz_path );

        free( psz_name );
        free( psz_description );
        free( psz_genre );
        free( psz_url );
        goto error;
    }

    free( psz_name );
    free( psz_description );
    free( psz_genre );
    free( psz_url );

    i_ret = shout_set_format( p_shout, var_GetBool( p_access, SOUT_CFG_PREFIX "mp3" ) ?
                                       SHOUT_FORMAT_MP3 : SHOUT_FORMAT_OGG );

    if( i_ret != SHOUTERR_SUCCESS )
    {
        msg_Err( p_access, "failed to set the shoutcast streaming format" );
        goto error;
    }

    /* Don't force bitrate to 0 but only use when specified. This will otherwise
       show an empty field on icecast directory listing instead of NA */
    psz_val = var_GetNonEmptyString( p_access, SOUT_CFG_PREFIX "bitrate" );
    if( psz_val )
    {
        i_ret = shout_set_audio_info( p_shout, SHOUT_AI_BITRATE, psz_val );
        free( psz_val );
        if( i_ret != SHOUTERR_SUCCESS )
        {
            msg_Err( p_access, "failed to set the information about the bitrate" );
            goto error;
        }
    }
    else
    {
        /* Bitrate information is used for icecast/shoutcast servers directory
           listings (sorting, stream info etc.) */
        msg_Warn( p_access, "no bitrate information specified (required for listing " \
                            "the server as public on the shoutcast website)" );
    }

    /* Information about samplerate, channels and quality will not be propagated
       through the YP protocol for icecast to the public directory listing when
       the icecast server is operating in shoutcast compatibility mode */

    psz_val = var_GetNonEmptyString( p_access, SOUT_CFG_PREFIX "samplerate" );
    if( psz_val )
    {
        i_ret = shout_set_audio_info( p_shout, SHOUT_AI_SAMPLERATE, psz_val );
        free( psz_val );
        if( i_ret != SHOUTERR_SUCCESS )
        {
            msg_Err( p_access, "failed to set the information about the samplerate" );
            goto error;
        }
    }

    psz_val = var_GetNonEmptyString( p_access, SOUT_CFG_PREFIX "channels" );
    if( psz_val )
    {
        i_ret = shout_set_audio_info( p_shout, SHOUT_AI_CHANNELS, psz_val );
        free( psz_val );
        if( i_ret != SHOUTERR_SUCCESS )
        {
            msg_Err( p_access, "failed to set the information about the number of channels" );
            goto error;
        }
    }

    psz_val = var_GetNonEmptyString( p_access, SOUT_CFG_PREFIX "quality" );
    if( psz_val )
    {
        i_ret = shout_set_audio_info( p_shout, SHOUT_AI_QUALITY, psz_val );
        free( psz_val );
        if( i_ret != SHOUTERR_SUCCESS )
        {
            msg_Err( p_access, "failed to set the information about Ogg Vorbis quality" );
            goto error;
        }
    }

    if( var_GetBool( p_access, SOUT_CFG_PREFIX "public" ) )
    {
        i_ret = shout_set_public( p_shout, 1 );
        if( i_ret != SHOUTERR_SUCCESS )
        {
            msg_Err( p_access, "failed to set the server status setting to public" );
            goto error;
        }
    }

    /* Connect at startup. Cycle through the possible protocols. */
    i_ret = shout_get_connected( p_shout );
    while ( i_ret != SHOUTERR_CONNECTED )
    {
        /* Shout parameters cannot be changed on an open connection */
        i_ret = shout_close( p_shout );
        if( i_ret == SHOUTERR_SUCCESS )
        {
            i_ret = SHOUTERR_UNCONNECTED;
        }

        /* Re-initialize for Shoutcast using ICY protocol. Not needed for initial connection
           but it is when we are reconnecting after other protocol was tried. */
        i_ret = shout_set_protocol( p_shout, SHOUT_PROTOCOL_ICY );
        if( i_ret != SHOUTERR_SUCCESS )
        {
            msg_Err( p_access, "failed to set the protocol to 'icy'" );
            goto error;
        }
        i_ret = shout_open( p_shout );
        if( i_ret == SHOUTERR_SUCCESS )
        {
            i_ret = SHOUTERR_CONNECTED;
            msg_Dbg( p_access, "connected using 'icy' (shoutcast) protocol" );
        }
        else
        {
            msg_Warn( p_access, "failed to connect using 'icy' (shoutcast) protocol" );

            /* Shout parameters cannot be changed on an open connection */
            i_ret = shout_close( p_shout );
            if( i_ret == SHOUTERR_SUCCESS )
            {
                i_ret = SHOUTERR_UNCONNECTED;
            }

            /* IceCAST using HTTP protocol */
            i_ret = shout_set_protocol( p_shout, SHOUT_PROTOCOL_HTTP );
            if( i_ret != SHOUTERR_SUCCESS )
            {
                msg_Err( p_access, "failed to set the protocol to 'http'" );
                goto error;
            }
            i_ret = shout_open( p_shout );
            if( i_ret == SHOUTERR_SUCCESS )
            {
                i_ret = SHOUTERR_CONNECTED;
                msg_Dbg( p_access, "connected using 'http' (icecast 2.x) protocol" );
            }
            else
                msg_Warn( p_access, "failed to connect using 'http' (icecast 2.x) protocol " );
        }
/*
        for non-blocking, use:
        while( i_ret == SHOUTERR_BUSY )
        {
            sleep( 1 );
            i_ret = shout_get_connected( p_shout );
        }
*/
        if ( i_ret != SHOUTERR_CONNECTED )
    	{
    	    msg_Warn( p_access, "unable to establish connection, retrying..." );
            msleep( 30000000 );
        }
    }

    if( i_ret != SHOUTERR_CONNECTED )
    {
        msg_Err( p_access, "failed to open shout stream to %s:%i/%s: %s",
                 url.psz_host, url.i_port, url.psz_path, shout_get_error(p_shout) );
        goto error;
    }

    p_access->pf_write = Write;
    p_access->pf_seek  = Seek;
    p_access->pf_control = Control;

    msg_Dbg( p_access, "shout access output opened (%s@%s:%i/%s)",
             url.psz_username, url.psz_host, url.i_port, url.psz_path );

    vlc_UrlClean( &url );
    return VLC_SUCCESS;

error:
    if( p_sys->p_shout )
        shout_free( p_sys->p_shout );
    vlc_UrlClean( &url );
    free( p_sys );
    return VLC_EGENERIC;
}
Beispiel #30
0
int
sendStream(shout_t *shout, FILE *filepstream, const char *fileName,
	   int isStdin, const char *songLenStr, struct timeval *tv)
{
	unsigned char	 buff[4096];
	size_t		 bytes_read, total, oldTotal;
	int		 ret;
	double		 kbps = -1.0;
	struct timeval	 timeStamp, *startTime = tv;
	struct timeval	 callTime, currentTime;

	if (startTime == NULL) {
		printf("%s: sendStream(): Internal error: startTime is NULL\n",
		       __progname);
		abort();
	}

	ez_gettimeofday((void *)&callTime);

	timeStamp.tv_sec = startTime->tv_sec;
	timeStamp.tv_usec = startTime->tv_usec;

	total = oldTotal = 0;
	ret = STREAM_DONE;
	while ((bytes_read = fread(buff, 1UL, sizeof(buff), filepstream)) > 0) {
		if (shout_get_connected(shout) != SHOUTERR_CONNECTED &&
		    reconnectServer(shout, 0) == 0) {
			ret = STREAM_SERVERR;
			break;
		}

		shout_sync(shout);

		if (shout_send(shout, buff, bytes_read) != SHOUTERR_SUCCESS) {
			printf("%s: shout_send(): %s\n", __progname,
			       shout_get_error(shout));
			if (reconnectServer(shout, 1))
				break;
			else {
				ret = STREAM_SERVERR;
				break;
			}
		}

		if (quit)
			break;
		if (rereadPlaylist_notify) {
			rereadPlaylist_notify = 0;
			if (!pezConfig->fileNameIsProgram)
				printf("%s: SIGHUP signal received, will reread playlist after this file\n",
				       __progname);
		}
		if (skipTrack) {
			skipTrack = 0;
			ret = STREAM_SKIP;
			break;
		}

		ez_gettimeofday((void *)&currentTime);

		if (queryMetadata ||
		    (pezConfig->metadataRefreshInterval != -1
		     && (currentTime.tv_sec - callTime.tv_sec
			 >= pezConfig->metadataRefreshInterval)
		    )
		   ) {
			queryMetadata = 0;
			if (metadataFromProgram) {
				ret = STREAM_UPDMDATA;
				break;
			}
		}

		total += bytes_read;
		if (qFlag && vFlag) {
			double	oldTime, newTime;

			if (!isStdin && playlistMode) {
				if (pezConfig->fileNameIsProgram) {
					char *tmp = xstrdup(pezConfig->fileName);
					printf("  [%s]",
					       local_basename(tmp));
					xfree(tmp);
				} else
					printf("  [%4lu/%-4lu]",
					       playlist_get_position(playlist),
					       playlist_get_num_items(playlist));
			}

			oldTime = (double)timeStamp.tv_sec
				+ (double)timeStamp.tv_usec / 1000000.0;
			newTime = (double)currentTime.tv_sec
				+ (double)currentTime.tv_usec / 1000000.0;
			if (songLenStr == NULL)
				printf("  [ %s]",
				       getTimeString(currentTime.tv_sec -
						     startTime->tv_sec));
			else
				printf("  [ %s/%s]",
				       getTimeString(currentTime.tv_sec -
						     startTime->tv_sec),
				       songLenStr);
			if (newTime - oldTime >= 1.0) {
				kbps = (((double)(total - oldTotal)
					 / (newTime - oldTime)) * 8.0) / 1000.0;
				timeStamp.tv_sec = currentTime.tv_sec;
				timeStamp.tv_usec = currentTime.tv_usec;
				oldTotal = total;
			}
			if (kbps < 0)
				printf("                 ");
			else
				printf("  [%8.2f kbps]", kbps);

			printf("  \r");
			fflush(stdout);
		}
	}
	if (ferror(filepstream)) {
		if (errno == EINTR) {
			clearerr(filepstream);
			ret = STREAM_CONT;
		} else if (errno == EBADF && isStdin)
			printf("%s: No (more) data available on standard input\n",
			       __progname);
		else
			printf("%s: sendStream(): Error while reading '%s': %s\n",
			       __progname, fileName, strerror(errno));
	}

	return (ret);
}