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"); } }
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"); }
void OutputIceCast::disconnectStream() { shout_close(_shout); _state = DISCONNECTED; emit stateChanged(DISCONNECTED); emit stateChanged("offline"); emit message(QString("Disconnected from ") + _c.address); }
bool Shouter::stop() { if(running) { notice("closed stream to %s",streamurl); shout_close(ice); running = false; } return true; }
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); }
/***************************************************************************** * Close: close the target *****************************************************************************/ static void Close( vlc_object_t * p_this ) { sout_access_out_t *p_access = (sout_access_out_t*)p_this; if( p_access->p_sys && p_access->p_sys->p_shout ) { shout_close( p_access->p_sys->p_shout ); shout_shutdown(); } free( p_access->p_sys ); msg_Dbg( p_access, "shout access output closed" ); }
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); }
/***************************************************************************** * 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; }
bool EngineShoutcast::serverDisconnect() { if (m_encoder){ m_encoder->flush(); delete m_encoder; m_encoder = NULL; } m_pShoutcastStatus->set(SHOUTCAST_DISCONNECTED); if (m_pShout) { shout_close(m_pShout); return true; } return false; //if no connection has been established, nothing can be disconnected }
void close_stream(STREAM_HDR *stream) { stream->streaming = 0; if (stream->shout != NULL) { shout_close(stream->shout); stream->shout = NULL; } if (stream->shoutbuf != NULL) { free(stream->shoutbuf); stream->shoutbuf = NULL; stream->shoutbuf_size = 0; } if (stream->ringbuf != NULL) { jack_ringbuffer_free(stream->ringbuf); stream->ringbuf = NULL; } return; }
VideoEncoder::~VideoEncoder() { // flush all the ringbuffer to file and stream unsigned int encnum = 0; if(encbuf) { do { if((encnum = ringbuffer_read_space(ringbuffer)) > 0) encnum = ringbuffer_read(ringbuffer, encbuf, encnum); // ((audio_kbps + video_kbps)*1024)/24); if(encnum <= 0) break; if(write_to_disk && filedump_fd) { fwrite(encbuf, 1, encnum, filedump_fd); } if(write_to_stream && ice) { shout_sync(ice); shout_send(ice, (const unsigned char*)encbuf, encnum); } func("flushed %u bytes closing video encoder", encnum); } while(encnum > 0); free(encbuf); } // close the filedump if(filedump_fd) fclose(filedump_fd); // now deallocate the ringbuffer ringbuffer_free(ringbuffer); shout_close(ice); // shout_sync(ice); // shout_free(ice); shout_shutdown(); if(enc_y) free(enc_y); if(enc_u) free(enc_u); if(enc_v) free(enc_v); if(enc_yuyv) free(enc_yuyv); free(fps); }
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); }
/***************************************************************************** * Close: close the target *****************************************************************************/ static void Close( vlc_object_t * p_this ) { sout_access_out_t *p_access = (sout_access_out_t*)p_this; if( p_access->p_sys && p_access->p_sys->p_shout ) { shout_close( p_access->p_sys->p_shout ); shout_shutdown(); } free( p_access->p_sys ); /* Update pace control flag */ if( p_access->psz_access && !strcmp( p_access->psz_access, "stream" ) ) { p_access->p_sout->i_out_pace_nocontrol--; } msg_Dbg( p_access, "shout access output closed" ); }
EngineShoutcast::~EngineShoutcast() { if (m_encoder) { m_encoder->flush(); delete m_encoder; } delete m_pUpdateShoutcastFromPrefs; delete m_pShoutcastNeedUpdateFromPrefs; delete m_pShoutcastStatus; delete m_pMasterSamplerate; if (m_pShoutMetaData) { shout_metadata_free(m_pShoutMetaData); } if (m_pShout) { shout_close(m_pShout); shout_free(m_pShout); } shout_shutdown(); }
static gboolean gst_shout2send_stop (GstBaseSink * basesink) { GstShout2send *sink = GST_SHOUT2SEND (basesink); if (sink->conn) { if (sink->connected) shout_close (sink->conn); shout_free (sink->conn); sink->conn = NULL; } if (sink->songmetadata) { g_free (sink->songmetadata); sink->songmetadata = NULL; } sink->connected = FALSE; return TRUE; }
static int icecast_internal_disconnect(t_channel *c, t_channel_outputstream *os, t_icecast *icecast, char *error, int errsize) { (void)c; (void)error; (void)errsize; (void)os; if (!icecast->connected) return MSERV_SUCCESS; vorbis_analysis_wrote(&icecast->vd, 0); vorbis_block_clear(&icecast->vb); vorbis_dsp_clear(&icecast->vd); vorbis_info_clear(&icecast->vi); shout_close(icecast->shout); icecast->connected = 0; return MSERV_SUCCESS; }
/* Top level ices shutdown function. * This is the _only_ way out of here */ void ices_setup_shutdown (void) { ices_stream_t* stream; /* Tell libshout to disconnect from server */ for (stream = ices_config.streams; stream; stream = stream->next) if (stream->conn) shout_close (stream->conn); #ifdef HAVE_LIBLAME /* Order the reencoding engine to shutdown */ ices_reencode_shutdown (); #endif /* Tell the playlist module to shutdown and cleanup */ ices_playlist_shutdown (); /* Cleanup the cue file (the cue module has no init yet) */ ices_cue_shutdown (); /* Make sure we're not leaving any memory allocated around when * we exit. This makes it easier to find memory leaks, and * some systems actually don't clean up that well */ ices_free_all (&ices_config); /* Let the log and console know we went down ok */ ices_log ("Ices Exiting..."); /* Close logfiles */ ices_log_shutdown (); shout_shutdown(); /* Down and down we go... */ exit (1); }
/***************************************************************************** * 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; }
int main(int argc, char *argv[]) { int c; char *configFile = NULL; char *host = NULL; unsigned short port = 0; char *mount = NULL; shout_t *shout; extern char *optarg; extern int optind; #ifdef HAVE_SIGNALS struct sigaction act; unsigned int i; #endif #ifdef XALLOC_DEBUG xalloc_initialize_debug(2, NULL); #else xalloc_initialize(); #endif /* XALLOC_DEBUG */ playlist_init(); shout_init(); __progname = getProgname(argv[0]); pezConfig = getEZConfig(); mFlag = 0; nFlag = 0; qFlag = 0; vFlag = 0; while ((c = local_getopt(argc, argv, "c:hmnqsVv")) != -1) { switch (c) { case 'c': if (configFile != NULL) { printf("Error: multiple -c arguments given\n"); usage(); return (ez_shutdown(2)); } configFile = xstrdup(optarg); break; case 'h': usage(); usageHelp(); return (ez_shutdown(0)); case 'm': mFlag = 1; break; case 'n': nFlag = 1; break; case 'q': qFlag = 1; break; case 's': sFlag = 1; break; case 'V': printf("%s\n", PACKAGE_STRING); return (ez_shutdown(0)); case 'v': vFlag++; break; case '?': usage(); return (ez_shutdown(2)); default: break; } } argc -= optind; argv += optind; if (sFlag) { playlist_t *pl; const char *entry; switch (argc) { case 0: pl = playlist_read(NULL); if (pl == NULL) return (ez_shutdown(1)); break; case 1: pl = playlist_read(argv[0]); if (pl == NULL) return (ez_shutdown(1)); break; default: printf("Error: Too many arguments.\n"); return (ez_shutdown(2)); } playlist_shuffle(pl); while ((entry = playlist_get_next(pl)) != NULL) printf("%s\n", entry); playlist_free(&pl); return (ez_shutdown(0)); } if (configFile == NULL) { printf("You must supply a config file with the -c argument.\n"); usage(); return (ez_shutdown(2)); } else { /* * Attempt to open configFile here for a more meaningful error * message. Where possible, do it with stat() and check for * safe config file permissions. */ #ifdef HAVE_STAT struct stat st; if (stat(configFile, &st) == -1) { printf("%s: %s\n", configFile, strerror(errno)); usage(); return (ez_shutdown(2)); } if (vFlag && (st.st_mode & (S_IRGRP | S_IROTH))) printf("%s: Warning: %s is group and/or world readable\n", __progname, configFile); if (st.st_mode & (S_IWGRP | S_IWOTH)) { printf("%s: Error: %s is group and/or world writeable\n", __progname, configFile); return (ez_shutdown(2)); } #else FILE *tmp; if ((tmp = fopen(configFile, "r")) == NULL) { printf("%s: %s\n", configFile, strerror(errno)); usage(); return (ez_shutdown(2)); } fclose(tmp); #endif /* HAVE_STAT */ } if (!parseConfig(configFile)) return (ez_shutdown(2)); if (pezConfig->URL == NULL) { printf("%s: Error: Missing <url>\n", configFile); return (ez_shutdown(2)); } if (!urlParse(pezConfig->URL, &host, &port, &mount)) { printf("Must be of the form ``http://server:port/mountpoint''\n"); return (ez_shutdown(2)); } if (strlen(host) == 0) { printf("%s: Error: Invalid <url>: Missing server:\n", configFile); printf("Must be of the form ``http://server:port/mountpoint''\n"); return (ez_shutdown(2)); } if (strlen(mount) == 0) { printf("%s: Error: Invalid <url>: Missing mountpoint:\n", configFile); printf("Must be of the form ``http://server:port/mountpoint''\n"); return (ez_shutdown(2)); } if (pezConfig->password == NULL) { printf("%s: Error: Missing <sourcepassword>\n", configFile); return (ez_shutdown(2)); } if (pezConfig->fileName == NULL) { printf("%s: Error: Missing <filename>\n", configFile); return (ez_shutdown(2)); } if (pezConfig->format == NULL) { printf("%s: Warning: Missing <format>:\n", configFile); printf("Specify a stream format of either MP3, VORBIS or THEORA\n"); } xfree(configFile); if ((shout = stream_setup(host, port, mount)) == NULL) return (ez_shutdown(1)); if (pezConfig->metadataProgram != NULL) metadataFromProgram = 1; else metadataFromProgram = 0; #ifdef HAVE_SIGNALS memset(&act, 0, sizeof(act)); act.sa_handler = sig_handler; # ifdef SA_RESTART act.sa_flags = SA_RESTART; # endif for (i = 0; i < sizeof(ezstream_signals) / sizeof(int); i++) { if (sigaction(ezstream_signals[i], &act, NULL) == -1) { printf("%s: sigaction(): %s\n", __progname, strerror(errno)); return (ez_shutdown(1)); } } /* * Ignore SIGPIPE, which has been seen to give a long-running ezstream * process trouble. EOF and/or EPIPE are also easier to handle. */ act.sa_handler = SIG_IGN; if (sigaction(SIGPIPE, &act, NULL) == -1) { printf("%s: sigaction(): %s\n", __progname, strerror(errno)); return (ez_shutdown(1)); } #endif /* HAVE_SIGNALS */ if (shout_open(shout) == SHOUTERR_SUCCESS) { int ret; printf("%s: Connected to http://%s:%hu%s\n", __progname, host, port, mount); if (pezConfig->fileNameIsProgram || strrcasecmp(pezConfig->fileName, ".m3u") == 0 || strrcasecmp(pezConfig->fileName, ".txt") == 0) playlistMode = 1; else playlistMode = 0; if (vFlag && pezConfig->fileNameIsProgram) printf("%s: Using program '%s' to get filenames for streaming\n", __progname, pezConfig->fileName); do { if (playlistMode) { ret = streamPlaylist(shout, pezConfig->fileName); } else { ret = streamFile(shout, pezConfig->fileName); } if (quit) break; if (pezConfig->streamOnce) break; } while (ret); shout_close(shout); } else printf("%s: Connection to http://%s:%hu%s failed: %s\n", __progname, host, port, mount, shout_get_error(shout)); if (quit) printf("\r%s: SIGINT or SIGTERM received\n", __progname); if (vFlag) printf("%s: Exiting ...\n", __progname); xfree(host); xfree(mount); playlist_free(&playlist); return (ez_shutdown(0)); }
void OutputIceCast::reconnectStream() { shout_close(_shout); applyConnection(); _timer->start(); }
Shouter::~Shouter() { shout_close(shout); shout_shutdown(); }
/* The main loop for each instance. Gets data passed to it from the stream * manager (which gets it from the input module), and streams it to the * specified server */ void *ices_instance_stream(void *arg) { int ret, shouterr; ref_buffer *buffer; char *connip; stream_description *sdsc = arg; instance_t *stream = sdsc->stream; input_module_t *inmod = sdsc->input; int reencoding = (inmod->type == ICES_INPUT_VORBIS) && stream->encode; int encoding = (inmod->type == ICES_INPUT_PCM) && stream->encode; char *stream_name = NULL, *stream_genre = NULL, *stream_description = NULL; char *user = NULL; vorbis_comment_init(&sdsc->vc); sdsc->shout = shout_new(); /* we only support the ice protocol and vorbis streams currently */ shout_set_format(sdsc->shout, SHOUT_FORMAT_VORBIS); //shout_set_protocol(sdsc->shout, SHOUT_PROTOCOL_ICE); shout_set_protocol(sdsc->shout, SHOUT_PROTOCOL_HTTP); signal(SIGPIPE, signal_hup_handler); connip = malloc(16); if(!resolver_getip(stream->hostname, connip, 16)) { LOG_ERROR1("Could not resolve hostname \"%s\"", stream->hostname); free(connip); stream->died = 1; return NULL; } if (!(shout_set_host(sdsc->shout, connip)) == SHOUTERR_SUCCESS) { LOG_ERROR1("libshout error: %s\n", shout_get_error(sdsc->shout)); free(connip); stream->died = 1; return NULL; } shout_set_port(sdsc->shout, stream->port); if (!(shout_set_password(sdsc->shout, stream->password)) == SHOUTERR_SUCCESS) { LOG_ERROR1("libshout error: %s\n", shout_get_error(sdsc->shout)); free(connip); stream->died = 1; return NULL; } if (stream->user) user = stream->user; else user = "******"; if(shout_set_user(sdsc->shout, user) != SHOUTERR_SUCCESS) { LOG_ERROR1("libshout error: %s\n", shout_get_error(sdsc->shout)); free(connip); stream->died = 1; return NULL; } if (!(shout_set_agent(sdsc->shout, VERSIONSTRING)) == SHOUTERR_SUCCESS) { LOG_ERROR1("libshout error: %s\n", shout_get_error(sdsc->shout)); free(connip); stream->died = 1; return NULL; } if (!(shout_set_mount(sdsc->shout, stream->mount)) == SHOUTERR_SUCCESS) { LOG_ERROR1("libshout error: %s\n", shout_get_error(sdsc->shout)); free(connip); stream->died = 1; return NULL; } /* set the metadata for the stream */ if(stream->stream_name) stream_name = stream->stream_name; else if (ices_config->stream_name) stream_name = ices_config->stream_name; if(stream->stream_description) stream_description = stream->stream_description; else if (ices_config->stream_description) stream_description = ices_config->stream_description; if(stream->stream_genre) stream_genre = stream->stream_genre; else if (ices_config->stream_genre) stream_genre = ices_config->stream_genre; if(stream_name) if (!(shout_set_name(sdsc->shout, stream_name)) == SHOUTERR_SUCCESS) { LOG_ERROR1("libshout error: %s\n", shout_get_error(sdsc->shout)); free(connip); stream->died = 1; return NULL; } if (stream_genre) if (!(shout_set_genre(sdsc->shout, stream_genre)) == SHOUTERR_SUCCESS) { LOG_ERROR1("libshout error: %s\n", shout_get_error(sdsc->shout)); free(connip); stream->died = 1; return NULL; } if (stream_description) if (!(shout_set_description(sdsc->shout, stream_description)) == SHOUTERR_SUCCESS) { LOG_ERROR1("libshout error: %s\n", shout_get_error(sdsc->shout)); free(connip); stream->died = 1; return NULL; } if(stream->downmix && encoding && stream->channels == 1) { stream->channels = 1; sdsc->downmix = downmix_initialise(); } if(stream->resampleinrate && stream->resampleoutrate && encoding) { stream->samplerate = stream->resampleoutrate; sdsc->resamp = resample_initialise(stream->channels, stream->resampleinrate, stream->resampleoutrate); } if(encoding) { if(inmod->metadata_update) inmod->metadata_update(inmod->internal, &sdsc->vc); sdsc->enc = encode_initialise(stream->channels, stream->samplerate, stream->managed, stream->min_br, stream->nom_br, stream->max_br, stream->quality, stream->serial++, &sdsc->vc); if(!sdsc->enc) { LOG_ERROR0("Failed to configure encoder"); stream->died = 1; return NULL; /* FIXME: probably leaking some memory here */ } } else if(reencoding) sdsc->reenc = reencode_init(stream); if(stream->savefilename != NULL) { stream->savefile = fopen(stream->savefilename, "wb"); if(!stream->savefile) LOG_ERROR2("Failed to open stream save file %s: %s", stream->savefilename, strerror(errno)); else LOG_INFO1("Saving stream to file %s", stream->savefilename); } if((shouterr = shout_open(sdsc->shout)) == SHOUTERR_SUCCESS) { LOG_INFO3("Connected to server: %s:%d%s", shout_get_host(sdsc->shout), shout_get_port(sdsc->shout), shout_get_mount(sdsc->shout)); while(1) { if(stream->buffer_failures > MAX_ERRORS) { LOG_WARN0("Too many errors, shutting down"); break; } buffer = stream_wait_for_data(stream); /* buffer being NULL means that either a fatal error occured, * or we've been told to shut down */ if(!buffer) break; /* If data is NULL or length is 0, we should just skip this one. * Probably, we've been signalled to shut down, and that'll be * caught next iteration. Add to the error count just in case, * so that we eventually break out anyway */ if(!buffer->buf || !buffer->len) { LOG_WARN0("Bad buffer dequeued!"); stream->buffer_failures++; continue; } if(stream->wait_for_critical) { LOG_INFO0("Trying restart on new substream"); stream->wait_for_critical = 0; } ret = process_and_send_buffer(sdsc, buffer); /* No data produced, do nothing */ if(ret == -1) ; /* Fatal error */ else if(ret == -2) { LOG_ERROR0("Serious error, waiting to restart on " "next substream. Stream temporarily suspended."); /* Set to wait until a critical buffer comes through (start of * a new substream, typically), and flush existing queue. */ thread_mutex_lock(&ices_config->flush_lock); stream->wait_for_critical = 1; input_flush_queue(stream->queue, 0); thread_mutex_unlock(&ices_config->flush_lock); } /* Non-fatal shout error */ else if(ret == 0) { LOG_ERROR2("Send error: %s (%s)", shout_get_error(sdsc->shout), strerror(errno)); if(shout_get_errno(sdsc->shout) == SHOUTERR_SOCKET) { int i=0; /* While we're trying to reconnect, don't receive data * to this instance, or we'll overflow once reconnect * succeeds */ thread_mutex_lock(&ices_config->flush_lock); stream->skip = 1; /* Also, flush the current queue */ input_flush_queue(stream->queue, 1); thread_mutex_unlock(&ices_config->flush_lock); while((i < stream->reconnect_attempts || stream->reconnect_attempts==-1) && !ices_config->shutdown) { i++; LOG_WARN0("Trying reconnect after server socket error"); shout_close(sdsc->shout); if((shouterr = shout_open(sdsc->shout)) == SHOUTERR_SUCCESS) { LOG_INFO3("Connected to server: %s:%d%s", shout_get_host(sdsc->shout), shout_get_port(sdsc->shout), shout_get_mount(sdsc->shout)); /* This stream can't restart until the next * logical stream comes along, since the * server won't have any cached headers for * this source/connection. So, don't continue * yet. */ thread_mutex_lock(&ices_config->flush_lock); stream->wait_for_critical = 1; input_flush_queue(stream->queue, 0); thread_mutex_unlock(&ices_config->flush_lock); break; } else { LOG_ERROR3("Failed to reconnect to %s:%d (%s)", shout_get_host(sdsc->shout),shout_get_port(sdsc->shout), shout_get_error(sdsc->shout)); if(i==stream->reconnect_attempts) { LOG_ERROR0("Reconnect failed too many times, " "giving up."); /* We want to die now */ stream->buffer_failures = MAX_ERRORS+1; } else /* Don't try again too soon */ sleep(stream->reconnect_delay); } } stream->skip = 0; } stream->buffer_failures++; } stream_release_buffer(buffer); } } else { LOG_ERROR3("Failed initial connect to %s:%d (%s)", shout_get_host(sdsc->shout),shout_get_port(sdsc->shout), shout_get_error(sdsc->shout)); } shout_close(sdsc->shout); if(stream->savefile != NULL) fclose(stream->savefile); shout_free(sdsc->shout); encode_clear(sdsc->enc); reencode_clear(sdsc->reenc); downmix_clear(sdsc->downmix); resample_clear(sdsc->resamp); vorbis_comment_clear(&sdsc->vc); stream->died = 1; return NULL; }
bool EngineShoutcast::serverConnect() { // set to busy in case another thread calls one of the other // EngineShoutcast calls m_iShoutStatus = SHOUTERR_BUSY; m_pShoutcastStatus->set(SHOUTCAST_CONNECTING); // reset the number of failures to zero m_iShoutFailures = 0; // set to a high number to automatically update the metadata // on the first change m_iMetaDataLife = 31337; // clear metadata, to make sure the first track is not skipped // because it was sent via an previous connection (see metaDataHasChanged) if(m_pMetaData) { m_pMetaData.clear(); } //If static metadata is available, we only need to send metadata one time m_firstCall = false; /*Check if m_encoder is initalized * Encoder is initalized in updateFromPreferences which is called always before serverConnect() * If m_encoder is NULL, then we propably want to use MP3 streaming, however, lame could not be found * It does not make sense to connect */ if(m_encoder == NULL){ m_pConfig->set(ConfigKey(SHOUTCAST_PREF_KEY,"enabled"),ConfigValue("0")); m_pShoutcastStatus->set(SHOUTCAST_DISCONNECTED); return false; } const int iMaxTries = 3; while (!m_bQuit && m_iShoutFailures < iMaxTries) { if (m_pShout) shout_close(m_pShout); m_iShoutStatus = shout_open(m_pShout); if (m_iShoutStatus == SHOUTERR_SUCCESS) m_iShoutStatus = SHOUTERR_CONNECTED; if ((m_iShoutStatus == SHOUTERR_BUSY) || (m_iShoutStatus == SHOUTERR_CONNECTED) || (m_iShoutStatus == SHOUTERR_SUCCESS)) break; m_iShoutFailures++; qDebug() << "Shoutcast failed connect. Failures:" << m_iShoutFailures; sleep(1); } if (m_iShoutFailures == iMaxTries) { if (m_pShout) shout_close(m_pShout); m_pConfig->set(ConfigKey(SHOUTCAST_PREF_KEY,"enabled"),ConfigValue("0")); m_pShoutcastStatus->set(SHOUTCAST_DISCONNECTED); return false; } if (m_bQuit) { if (m_pShout) shout_close(m_pShout); m_pShoutcastStatus->set(SHOUTCAST_DISCONNECTED); return false; } m_iShoutFailures = 0; int timeout = 0; while (m_iShoutStatus == SHOUTERR_BUSY && timeout < TIMEOUT) { qDebug() << "Connection pending. Sleeping..."; sleep(1); m_iShoutStatus = shout_get_connected(m_pShout); ++ timeout; } if (m_iShoutStatus == SHOUTERR_CONNECTED) { qDebug() << "***********Connected to Shoutcast server..."; m_pShoutcastStatus->set(SHOUTCAST_CONNECTED); return true; } //otherwise disable shoutcast in preferences m_pConfig->set(ConfigKey(SHOUTCAST_PREF_KEY,"enabled"),ConfigValue("0")); if(m_pShout){ shout_close(m_pShout); //errorDialog(tr("Mixxx could not connect to the server"), tr("Please check your connection to the Internet and verify that your username and password are correct.")); } m_pShoutcastStatus->set(SHOUTCAST_DISCONNECTED); return false; }
/***************************************************************************** * 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; unsigned int i_port; vlc_value_t val; char *psz_accessname = NULL; char *psz_parser = NULL; char *psz_user = NULL; char *psz_pass = NULL; char *psz_host = NULL; char *psz_mount = NULL; char *psz_name = NULL; char *psz_description = NULL; char *tmp_port = NULL; sout_CfgParse( p_access, SOUT_CFG_PREFIX, ppsz_sout_options, p_access->p_cfg ); psz_accessname = psz_parser = strdup( p_access->psz_name ); if( !p_access->psz_name ) { msg_Err( p_access, "please specify url=user:password@host:port/mountpoint" ); return VLC_EGENERIC; } /* Parse connection data user:pwd@host:port/mountpoint */ psz_user = psz_parser; while( psz_parser[0] && psz_parser[0] != ':' ) psz_parser++; if( psz_parser[0] ) { psz_parser[0] = 0; psz_parser++; } psz_pass = psz_parser; while( psz_parser[0] && psz_parser[0] != '@' ) psz_parser++; if( psz_parser[0] ) { psz_parser[0] = 0; psz_parser++; } psz_host = psz_parser; while( psz_parser[0] && psz_parser[0] != ':' ) psz_parser++; if( psz_parser[0] ) { psz_parser[0] = 0; psz_parser++; } tmp_port = psz_parser; while( psz_parser[0] && psz_parser[0] != '/' ) psz_parser++; if( psz_parser[0] ) { psz_parser[0] = 0; psz_parser++; } psz_mount = psz_parser; i_port = atoi( tmp_port ); p_sys = p_access->p_sys = malloc( sizeof( sout_access_out_sys_t ) ); if( !p_sys ) { msg_Err( p_access, "out of memory" ); free( psz_accessname ); return VLC_ENOMEM; } var_Get( p_access, SOUT_CFG_PREFIX "name", &val ); if( *val.psz_string ) psz_name = val.psz_string; else free( val.psz_string ); var_Get( p_access, SOUT_CFG_PREFIX "description", &val ); if( *val.psz_string ) psz_description = val.psz_string; else free( val.psz_string ); p_shout = p_sys->p_shout = shout_new(); if( !p_shout || shout_set_host( p_shout, psz_host ) != SHOUTERR_SUCCESS || shout_set_protocol( p_shout, SHOUT_PROTOCOL_ICY ) != SHOUTERR_SUCCESS || shout_set_port( p_shout, i_port ) != SHOUTERR_SUCCESS || shout_set_password( p_shout, psz_pass ) != SHOUTERR_SUCCESS || shout_set_mount( p_shout, psz_mount ) != SHOUTERR_SUCCESS || shout_set_user( p_shout, psz_user ) != 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_nonblocking( p_shout, 1 ) != SHOUTERR_SUCCESS */ ) { msg_Err( p_access, "failed to initialize shout streaming to %s:%i/%s", psz_host, i_port, psz_mount ); free( p_access->p_sys ); free( psz_accessname ); return VLC_EGENERIC; } if( psz_name ) free( psz_name ); if( psz_description ) free( psz_description ); var_Get( p_access, SOUT_CFG_PREFIX "mp3", &val ); if( val.b_bool == VLC_TRUE ) i_ret = shout_set_format( p_shout, SHOUT_FORMAT_MP3 ); else i_ret = shout_set_format( p_shout, SHOUT_FORMAT_OGG ); if( i_ret != SHOUTERR_SUCCESS ) { msg_Err( p_access, "failed to set the shoutcast streaming format" ); free( p_access->p_sys ); free( psz_accessname ); return VLC_EGENERIC; } /* Shoutcast using ICY protocol */ 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'" ); free( p_access->p_sys ); free( psz_accessname ); return VLC_EGENERIC; } 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_Err( p_access, "failed to open shout stream to %s:%i/%s: %s", psz_host, i_port, psz_mount, shout_get_error(p_shout) ); free( p_access->p_sys ); free( psz_accessname ); return VLC_EGENERIC; } p_access->pf_write = Write; p_access->pf_read = Read; p_access->pf_seek = Seek; msg_Dbg( p_access, "shout access output opened (%s@%s:%i/%s)", psz_user, psz_host, i_port, psz_mount ); /* Update pace control flag */ if( p_access->psz_access && !strcmp( p_access->psz_access, "stream" ) ) { p_access->p_sout->i_out_pace_nocontrol++; } free( psz_accessname ); return VLC_SUCCESS; }
static int icecast_internal_connect(t_channel *c, t_channel_outputstream *os, t_icecast *icecast, char *error, int errsize) { ogg_packet header; ogg_packet header_comm; ogg_packet header_code; (void)c; (void)os; if (icecast->connected) return MSERV_SUCCESS; if (shout_open(icecast->shout) != SHOUTERR_SUCCESS) { snprintf(error, errsize, "icecast: failed opening connection: %s", shout_get_error(icecast->shout)); goto failed; } mserv_log("Successfully connected to Icecast server '%s:%d'" " for mount '%s'", shout_get_host(icecast->shout), shout_get_port(icecast->shout), shout_get_mount(icecast->shout)); icecast->connected = 1; vorbis_info_init(&icecast->vi); if (vorbis_encode_init(&icecast->vi, os->channels, os->samplerate, -1, icecast->bitrate, -1) != 0) { snprintf(error, errsize, "icecast: failed to initialise vorbis engine"); goto failed; } vorbis_comment_init(&icecast->vc); vorbis_comment_add_tag(&icecast->vc, "ENCODER", "mserv " VERSION); vorbis_analysis_init(&icecast->vd, &icecast->vi); vorbis_block_init(&icecast->vd, &icecast->vb); ogg_stream_init(&icecast->os, rand()); vorbis_analysis_headerout(&icecast->vd, &icecast->vc, &header, &header_comm, &header_code); ogg_stream_packetin(&icecast->os, &header); ogg_stream_packetin(&icecast->os, &header_comm); ogg_stream_packetin(&icecast->os, &header_code); for (;;) { if (ogg_stream_flush(&icecast->os, &icecast->og) == 0) break; if (shout_send(icecast->shout, icecast->og.header, icecast->og.header_len) != SHOUTERR_SUCCESS || shout_send(icecast->shout, icecast->og.body, icecast->og.body_len) != SHOUTERR_SUCCESS) { snprintf(error, errsize, "icecast: failed to send starter to " "shout: %s", shout_get_error(icecast->shout)); vorbis_block_clear(&icecast->vb); vorbis_dsp_clear(&icecast->vd); vorbis_info_clear(&icecast->vi); goto failed; } } return MSERV_SUCCESS; failed: if (icecast->connected) shout_close(icecast->shout); icecast->connected = 0; return MSERV_FAILURE; }
int main() { shout_t *shout; char buff[4096]; long read, ret, total; shout_init(); if (!(shout = shout_new())) { printf("Could not allocate shout_t\n"); return 1; } if (shout_set_host(shout, "127.0.0.1") != SHOUTERR_SUCCESS) { printf("Error setting hostname: %s\n", shout_get_error(shout)); return 1; } if (shout_set_protocol(shout, SHOUT_PROTOCOL_HTTP) != SHOUTERR_SUCCESS) { printf("Error setting protocol: %s\n", shout_get_error(shout)); return 1; } if (shout_set_port(shout, 8000) != SHOUTERR_SUCCESS) { printf("Error setting port: %s\n", shout_get_error(shout)); return 1; } if (shout_set_password(shout, "hackme") != SHOUTERR_SUCCESS) { printf("Error setting password: %s\n", shout_get_error(shout)); return 1; } if (shout_set_mount(shout, "/example.ogg") != SHOUTERR_SUCCESS) { printf("Error setting mount: %s\n", shout_get_error(shout)); return 1; } if (shout_set_user(shout, "source") != SHOUTERR_SUCCESS) { printf("Error setting user: %s\n", shout_get_error(shout)); return 1; } if (shout_set_format(shout, SHOUT_FORMAT_OGG) != SHOUTERR_SUCCESS) { printf("Error setting user: %s\n", shout_get_error(shout)); return 1; } if (shout_open(shout) == SHOUTERR_SUCCESS) { printf("Connected to server...\n"); total = 0; while (1) { read = fread(buff, 1, sizeof(buff), stdin); total = total + read; if (read > 0) { ret = shout_send(shout, buff, 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)); } shout_close(shout); shout_shutdown(); return 0; }
static inline void free_context(shout_context_t *context) { int ret; if (context) { switch_mutex_lock(context->audio_mutex); context->err++; switch_mutex_unlock(context->audio_mutex); if (context->stream_url) { int sanity = 0; while (context->thread_running) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Waiting for stream to terminate: %s\n", context->stream_url); switch_yield(500000); if (++sanity > 10) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Giving up waiting for stream to terminate: %s\n", context->stream_url); break; } } } switch_thread_rwlock_wrlock(context->rwlock); if (context->mh) { mpg123_close(context->mh); mpg123_delete(context->mh); } if (context->fp) { unsigned char mp3buffer[8192]; int len; int16_t blank[2048] = { 0 }, *r = NULL; if (context->channels == 2) { r = blank; } len = lame_encode_buffer(context->gfp, blank, r, sizeof(blank) / 2, mp3buffer, sizeof(mp3buffer)); if (len) { ret = fwrite(mp3buffer, 1, len, context->fp); } while ((len = lame_encode_flush(context->gfp, mp3buffer, sizeof(mp3buffer))) > 0) { ret = fwrite(mp3buffer, 1, len, context->fp); if (ret < 0) { break; } } lame_mp3_tags_fid(context->gfp, context->fp); fclose(context->fp); context->fp = NULL; } if (context->shout) { shout_close(context->shout); context->shout = NULL; } if (context->gfp) { lame_close(context->gfp); context->gfp = NULL; } if (context->audio_buffer) { switch_buffer_destroy(&context->audio_buffer); } switch_mutex_destroy(context->audio_mutex); switch_thread_rwlock_unlock(context->rwlock); switch_thread_rwlock_destroy(context->rwlock); } }
int main (int argc, char * argv[]) { int rate = 44100; int bits = 16; int channels = 2; int codec = ROAR_CODEC_OGG_VORBIS; char * server = NULL; char * k; char * s_server = NULL; char * s_mount = NULL; char * s_pw = NULL; int s_port = -1; char * s_desc = NULL; char * s_genre = NULL; char * s_name = NULL; char * s_url = NULL; int s_public = 0; int fh; int i; char buf[BUFSIZE]; shout_t * shout; for (i = 1; i < argc; i++) { k = argv[i]; if ( strcmp(k, "--server") == 0 ) { server = argv[++i]; } else if ( strcmp(k, "--rate") == 0 ) { rate = atoi(argv[++i]); } else if ( strcmp(k, "--bits") == 0 ) { bits = atoi(argv[++i]); } else if ( strcmp(k, "--channels") == 0 || strcmp(k, "--chans") == 0 ) { channels = atoi(argv[++i]); } else if ( strcmp(k, "--codec") == 0 ) { codec = roar_str2codec(argv[++i]); } else if ( strcmp(k, "-p") == 0 || strcmp(k, "--public") == 0 ) { s_public = 1; } else if ( strcmp(k, "-d") == 0 ) { s_desc = argv[++i]; } else if ( strcmp(k, "-g") == 0 ) { s_genre = argv[++i]; } else if ( strcmp(k, "-n") == 0 ) { s_name = argv[++i]; } else if ( strcmp(k, "-u") == 0 ) { s_url = argv[++i]; } else if ( strcmp(k, "-h") == 0 || strcmp(k, "--help") == 0 ) { usage(); return 0; } else if ( s_server == NULL ) { s_server = k; } else if ( s_port == -1 ) { s_port = atoi(k); } else if ( s_pw == NULL ) { s_pw = k; } else if ( s_mount == NULL ) { s_mount = k; } else { fprintf(stderr, "Error: unknown argument: %s\n", k); usage(); return 1; } } if ( s_server == NULL ) s_server = "localhost"; if ( s_mount == NULL ) s_mount = "/roar.ogg"; if ( s_pw == NULL ) s_pw = "hackme"; if ( s_port == -1 ) s_port = 8000; shout_init(); if (!(shout = shout_new())) { ROAR_ERR("Can not create shout object"); return 1; } if (shout_set_host(shout, s_server) != SHOUTERR_SUCCESS) { ROAR_ERR("Error setting hostname: %s", shout_get_error(shout)); return 1; } if (shout_set_protocol(shout, SHOUT_PROTOCOL_HTTP) != SHOUTERR_SUCCESS) { ROAR_ERR("Error setting protocol: %s", shout_get_error(shout)); return 1; } if (shout_set_port(shout, s_port) != SHOUTERR_SUCCESS) { ROAR_ERR("Error setting port: %s", shout_get_error(shout)); return 1; } if (shout_set_password(shout, s_pw) != SHOUTERR_SUCCESS) { ROAR_ERR("Error setting password: %s", shout_get_error(shout)); return 1; } if (shout_set_mount(shout, s_mount) != SHOUTERR_SUCCESS) { ROAR_ERR("Error setting mount: %s", shout_get_error(shout)); return 1; } if (shout_set_user(shout, "source") != SHOUTERR_SUCCESS) { ROAR_ERR("Error setting user: %s", shout_get_error(shout)); return 1; } if (shout_set_format(shout, SHOUT_FORMAT_OGG) != SHOUTERR_SUCCESS) { ROAR_ERR("Error setting format: %s", shout_get_error(shout)); return 1; } shout_set_public(shout, s_public); if (s_desc != NULL) shout_set_description(shout, s_desc); if (s_genre != NULL) shout_set_genre(shout, s_genre); if (s_name != NULL) shout_set_name(shout, s_name); if (s_url != NULL) shout_set_url(shout, s_url); if ( (fh = roar_simple_monitor(rate, channels, bits, codec, server, "roarshout")) == -1 ) { fprintf(stderr, "Error: can not start monitoring\n"); return 1; } if (shout_open(shout) != SHOUTERR_SUCCESS) { ROAR_ERR("Can not open connection via libshout!"); return -1; } while((i = read(fh, buf, BUFSIZE))) if (shout_send(shout, (unsigned char*)buf, i) != SHOUTERR_SUCCESS) break; roar_simple_close(fh); shout_sync(shout); shout_close(shout); shout_shutdown(); return 0; }