#include <vlc_plugin.h>
#include <vlc_sout.h>
#include <vlc_block.h>
+#include <vlc_url.h>
#include <shout/shout.h>
add_shortcut( "shout" )
add_string( SOUT_CFG_PREFIX "name", "VLC media player - Live stream",
NAME_TEXT, NAME_LONGTEXT, false )
- add_string( SOUT_CFG_PREFIX "description", "Live stream from VLC media player", NULL,
+ add_string( SOUT_CFG_PREFIX "description", "Live stream from VLC media player",
DESCRIPTION_TEXT, DESCRIPTION_LONGTEXT, false )
add_bool( SOUT_CFG_PREFIX "mp3", false,
MP3_TEXT, MP3_LONGTEXT, true )
sout_access_out_sys_t *p_sys;
shout_t *p_shout;
long i_ret;
- unsigned int i_port;
char *psz_val;
- char *psz_accessname;
- char *psz_parser;
- const char *psz_user;
- char *psz_pass;
- char *psz_host;
- char *psz_mount;
- char *psz_port;
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 );
return VLC_EGENERIC;
}
- psz_accessname = psz_parser = strdup( p_access->psz_path );
- if( !psz_parser )
- return VLC_ENOMEM;
-
- /* Parse connection data user:pwd@host:port/mountpoint */
- psz_host = strchr( psz_parser, '@' );
- if( psz_host )
- {
- psz_user = psz_parser;
- *(psz_host++) = '\0';
- }
- else
- psz_user = "";
-
- psz_pass = strchr( psz_user, ':' );
- if( psz_pass )
- *(psz_pass++) = '\0';
- else
- psz_pass = "";
-
- psz_mount = strchr( psz_host, '/' );
- if( psz_mount )
- *(psz_mount++) = '\0';
- else
- psz_mount = "";
-
- if( psz_host[0] == '[' )
- {
- psz_port = strstr( psz_host, "]:" );
- if( psz_port )
- {
- *psz_port = '\0';
- psz_port += 2;
- }
- }
- else
- {
- psz_port = strchr( psz_host, ':' );
- if( psz_port )
- *(psz_port++) = '\0';
- }
- i_port = psz_port ? atoi( psz_port ) : 8000;
+ 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 )
{
- free( psz_accessname );
+ vlc_UrlClean( &url );
return VLC_ENOMEM;
}
p_shout = p_sys->p_shout = shout_new();
if( !p_shout
- || shout_set_host( p_shout, psz_host ) != SHOUTERR_SUCCESS
+ || 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, 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_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
)
{
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 );
+ url.psz_host, url.i_port, url.psz_path );
+
free( psz_name );
free( psz_description );
free( psz_genre );
free( psz_url );
- return VLC_EGENERIC;
+ goto error;
}
free( psz_name );
free( psz_genre );
free( psz_url );
- if( var_GetBool( p_access, SOUT_CFG_PREFIX "mp3" ) )
- i_ret = shout_set_format( p_shout, SHOUT_FORMAT_MP3 );
- else
- i_ret = shout_set_format( p_shout, SHOUT_FORMAT_OGG );
+ 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 )
{
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;
+ url.psz_host, url.i_port, url.psz_path, shout_get_error(p_shout) );
+ goto error;
}
p_access->pf_write = Write;
p_access->pf_control = Control;
msg_Dbg( p_access, "shout access output opened (%s@%s:%i/%s)",
- psz_user, psz_host, i_port, psz_mount );
- free( psz_accessname );
+ url.psz_username, url.psz_host, url.i_port, url.psz_path );
+ vlc_UrlClean( &url );
return VLC_SUCCESS;
error:
- free( psz_accessname );
+ if( p_sys->p_shout )
+ shout_free( p_sys->p_shout );
+ vlc_UrlClean( &url );
free( p_sys );
return VLC_EGENERIC;
}
static void Close( vlc_object_t * p_this )
{
sout_access_out_t *p_access = (sout_access_out_t*)p_this;
+ sout_access_out_sys_t *p_sys = p_access->p_sys;
- if( p_access->p_sys && p_access->p_sys->p_shout )
+ if( p_sys->p_shout )
{
- shout_close( p_access->p_sys->p_shout );
+ shout_close( p_sys->p_shout );
+ shout_free( p_sys->p_shout );
shout_shutdown();
}
- free( p_access->p_sys );
+ free( p_sys );
msg_Dbg( p_access, "shout access output closed" );
}
*****************************************************************************/
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_access->p_sys->p_shout );
+ shout_sync( 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 )
+ 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_access->p_sys->p_shout) );
+ 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_access->p_sys->p_shout );
+ 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_access->p_sys->p_shout ) == SHOUTERR_SUCCESS )
+ if( shout_open( p_sys->p_shout ) == SHOUTERR_SUCCESS )
{
- shout_sync( p_access->p_sys->p_shout );
+ 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);
+ block_ChainRelease( p_buffer );
return VLC_EGENERIC;
}