X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;ds=sidebyside;f=modules%2Fdemux%2Fplaylist%2Fshoutcast.c;h=a8c2e5d92c02eb56fb4079917617d2d73b3ec192;hb=12ade3e3bc975d5426ba4af155b7372c31093b31;hp=2ba221783ffd1342898004376ba5604c1ef9c885;hpb=630076053112b47b2f6279b1e67a4031d2ca45b2;p=vlc diff --git a/modules/demux/playlist/shoutcast.c b/modules/demux/playlist/shoutcast.c index 2ba221783f..a8c2e5d92c 100644 --- a/modules/demux/playlist/shoutcast.c +++ b/modules/demux/playlist/shoutcast.c @@ -30,22 +30,11 @@ # include "config.h" #endif -#include +#include #include #include "playlist.h" -#include "vlc_xml.h" - -struct demux_sys_t -{ - playlist_t *p_playlist; - input_item_t *p_current_input; - - xml_t *p_xml; - xml_reader_t *p_xml_reader; - - bool b_adult; -}; +#include /* duplicate from modules/services_discovery/shout.c */ #define SHOUTCAST_BASE_URL "http/shout-winamp://www.shoutcast.com/sbin/newxml.phtml" @@ -58,8 +47,10 @@ struct demux_sys_t static int Demux( demux_t *p_demux); static int Control( demux_t *p_demux, int i_query, va_list args ); -static int DemuxGenre( demux_t *p_demux ); -static int DemuxStation( demux_t *p_demux ); +static int DemuxGenre( demux_t *p_demux, xml_reader_t *p_xml_reader, + input_item_node_t *p_input_node ); +static int DemuxStation( demux_t *p_demux, xml_reader_t *p_xml_reader, + input_item_node_t *p_input_node, bool b_adult ); /***************************************************************************** * Import_Shoutcast: main import function @@ -71,15 +62,9 @@ int Import_Shoutcast( vlc_object_t *p_this ) if( !demux_IsForced( p_demux, "shout-winamp" ) ) return VLC_EGENERIC; - STANDARD_DEMUX_INIT_MSG( "using shoutcast playlist reader" ); - p_demux->p_sys->p_playlist = NULL; - p_demux->p_sys->p_xml = NULL; - p_demux->p_sys->p_xml_reader = NULL; - - /* Do we want to list adult content ? */ - var_Create( p_demux, "shoutcast-show-adult", - VLC_VAR_BOOL | VLC_VAR_DOINHERIT ); - p_demux->p_sys->b_adult = var_GetBool( p_demux, "shoutcast-show-adult" ); + p_demux->pf_demux = Demux; + p_demux->pf_control = Control; + msg_Dbg( p_demux, "using shoutcast playlist reader" ); return VLC_SUCCESS; } @@ -89,40 +74,26 @@ int Import_Shoutcast( vlc_object_t *p_this ) *****************************************************************************/ void Close_Shoutcast( vlc_object_t *p_this ) { - demux_t *p_demux = (demux_t *)p_this; - demux_sys_t *p_sys = p_demux->p_sys; - - if( p_sys->p_playlist ) - vlc_object_release( p_sys->p_playlist ); - if( p_sys->p_xml_reader ) - xml_ReaderDelete( p_sys->p_xml, p_sys->p_xml_reader ); - if( p_sys->p_xml ) - xml_Delete( p_sys->p_xml ); - free( p_sys ); + (void)p_this; } static int Demux( demux_t *p_demux ) { - demux_sys_t *p_sys = p_demux->p_sys; - xml_t *p_xml; - xml_reader_t *p_xml_reader; + xml_reader_t *p_xml_reader = NULL; char *psz_eltname = NULL; - INIT_PLAYLIST_STUFF; - p_sys->p_playlist = p_playlist; - p_sys->p_current_input = p_current_input; - - p_xml = p_sys->p_xml = xml_Create( p_demux ); - if( !p_xml ) return -1; + int i_ret = -1; + input_item_t *p_current_input = GetCurrentItem(p_demux); + input_item_node_t *p_input_node = NULL; - p_xml_reader = xml_ReaderCreate( p_xml, p_demux->s ); - if( !p_xml_reader ) return -1; - p_sys->p_xml_reader = p_xml_reader; + p_xml_reader = xml_ReaderCreate( p_demux, p_demux->s ); + if( !p_xml_reader ) + goto error; /* check root node */ if( xml_ReaderRead( p_xml_reader ) != 1 ) { msg_Err( p_demux, "invalid file (no root node)" ); - return -1; + goto error; } if( xml_ReaderNodeType( p_xml_reader ) != XML_READER_STARTELEM || @@ -132,122 +103,139 @@ static int Demux( demux_t *p_demux ) { msg_Err( p_demux, "invalid root node %i, %s", xml_ReaderNodeType( p_xml_reader ), psz_eltname ); - free( psz_eltname ); - return -1; + goto error; } + p_input_node = input_item_node_Create( p_current_input ); + if( !strcmp( psz_eltname, "genrelist" ) ) { /* we're reading a genre list */ - free( psz_eltname ); - if( DemuxGenre( p_demux ) ) return -1; + if( DemuxGenre( p_demux, p_xml_reader, p_input_node ) ) + goto error; } else { /* we're reading a station list */ - free( psz_eltname ); - if( DemuxStation( p_demux ) ) return -1; + if( DemuxStation( p_demux, p_xml_reader, p_input_node, + var_InheritBool( p_demux, "shoutcast-show-adult" ) ) ) + goto error; } - HANDLE_PLAY_AND_RELEASE; - p_sys->p_playlist = NULL; - return 0; /* Needed for correct operation of go back */ + input_item_node_PostAndDelete( p_input_node ); + p_input_node = NULL; + + i_ret = 0; /* Needed for correct operation of go back */ + +error: + if( p_xml_reader ) + xml_ReaderDelete( p_xml_reader ); + free( psz_eltname ); + if( p_input_node ) input_item_node_Delete( p_input_node ); + vlc_gc_decref(p_current_input); + return i_ret; } #define GET_VALUE( a ) \ if( !strcmp( psz_attrname, #a ) ) \ { \ - psz_ ## a = strdup( psz_attrvalue ); \ + free(psz_ ## a); \ + psz_ ## a = psz_attrvalue; \ } /* * * ... * **/ -static int DemuxGenre( demux_t *p_demux ) +static int DemuxGenre( demux_t *p_demux, xml_reader_t *p_xml_reader, + input_item_node_t *p_input_node ) { - demux_sys_t *p_sys = p_demux->p_sys; char *psz_name = NULL; /* genre name */ - char *psz_eltname = NULL; /* tag name */ - input_item_t *p_input; + int i_ret = -1; - while( xml_ReaderRead( p_sys->p_xml_reader ) == 1 ) + while( xml_ReaderRead( p_xml_reader ) == 1 ) { - int i_type; - // Get the node type - i_type = xml_ReaderNodeType( p_sys->p_xml_reader ); - switch( i_type ) + switch( xml_ReaderNodeType( p_xml_reader ) ) { // Error case -1: - return -1; - break; + goto error; case XML_READER_STARTELEM: + { // Read the element name - psz_eltname = xml_ReaderName( p_sys->p_xml_reader ); - if( !psz_eltname ) return -1; + char *psz_eltname = xml_ReaderName( p_xml_reader ); + if( !psz_eltname ) + goto error; if( !strcmp( psz_eltname, "genre" ) ) { // Read the attributes - while( xml_ReaderNextAttr( p_sys->p_xml_reader ) == VLC_SUCCESS ) + while( xml_ReaderNextAttr( p_xml_reader ) == VLC_SUCCESS ) { - char *psz_attrname = xml_ReaderName( p_sys->p_xml_reader ); + char *psz_attrname = xml_ReaderName( p_xml_reader ); char *psz_attrvalue = - xml_ReaderValue( p_sys->p_xml_reader ); + xml_ReaderValue( p_xml_reader ); if( !psz_attrname || !psz_attrvalue ) { - FREENULL(psz_attrname); - FREENULL(psz_attrvalue); - free(psz_eltname); - /*FIXME: isn't return a bit too much. what about break*/ - return -1; + free( psz_attrname ); + free( psz_attrvalue ); + free( psz_eltname ); + break; } GET_VALUE( name ) else { msg_Warn( p_demux, - "unexpected attribure %s in element %s", - psz_attrname,psz_eltname ); + "unexpected attribute %s in element %s", + psz_attrname, psz_eltname ); + free( psz_attrvalue ); } free( psz_attrname ); - free( psz_attrvalue ); } } - free( psz_eltname ); psz_eltname = NULL; + free( psz_eltname ); break; + } case XML_READER_TEXT: break; // End element case XML_READER_ENDELEM: + { // Read the element name - psz_eltname = xml_ReaderName( p_sys->p_xml_reader ); - if( !psz_eltname ) return -1; + char *psz_eltname = xml_ReaderName( p_xml_reader ); + if( !psz_eltname ) + goto error; + if( !strcmp( psz_eltname, "genre" ) ) { - char *psz_mrl = malloc( strlen( SHOUTCAST_BASE_URL ) - + strlen( "?genre=" ) + strlen( psz_name ) + 1 ); - sprintf( psz_mrl, SHOUTCAST_BASE_URL "?genre=%s", - psz_name ); - p_input = input_ItemNewExt( p_sys->p_playlist, psz_mrl, - psz_name, 0, NULL, -1 ); - input_ItemCopyOptions( p_sys->p_current_input, - p_input ); - free( psz_mrl ); - input_ItemAddSubItem( p_sys->p_current_input, p_input ); - vlc_gc_decref( p_input ); + char* psz_mrl; + if( asprintf( &psz_mrl, SHOUTCAST_BASE_URL "?genre=%s", + psz_name ) != -1 ) + { + input_item_t *p_input; + p_input = input_item_New( p_demux, psz_mrl, psz_name ); + input_item_CopyOptions( p_input_node->p_item, p_input ); + free( psz_mrl ); + input_item_node_AppendItem( p_input_node, p_input ); + vlc_gc_decref( p_input ); + } FREENULL( psz_name ); } - FREENULL( psz_eltname ); + free( psz_eltname ); break; + } } } - return 0; + i_ret = 0; + +error: + free( psz_name ); + return i_ret; } /* radio stations: @@ -275,11 +263,9 @@ static int DemuxGenre( demux_t *p_demux ) * lc="listener count"> * **/ -static int DemuxStation( demux_t *p_demux ) +static int DemuxStation( demux_t *p_demux, xml_reader_t *p_xml_reader, + input_item_node_t *p_input_node, bool b_adult ) { - demux_sys_t *p_sys = p_demux->p_sys; - input_item_t *p_input; - char *psz_base = NULL; /* */ char *psz_name = NULL; /* genre name */ @@ -296,12 +282,12 @@ static int DemuxStation( demux_t *p_demux ) char *psz_eltname = NULL; /* tag name */ - while( xml_ReaderRead( p_sys->p_xml_reader ) == 1 ) + while( xml_ReaderRead( p_xml_reader ) == 1 ) { int i_type; // Get the node type - i_type = xml_ReaderNodeType( p_sys->p_xml_reader ); + i_type = xml_ReaderNodeType( p_xml_reader ); switch( i_type ) { // Error @@ -311,22 +297,22 @@ static int DemuxStation( demux_t *p_demux ) case XML_READER_STARTELEM: // Read the element name - psz_eltname = xml_ReaderName( p_sys->p_xml_reader ); + psz_eltname = xml_ReaderName( p_xml_reader ); if( !psz_eltname ) return -1; // Read the attributes if( !strcmp( psz_eltname, "tunein" ) ) { - while( xml_ReaderNextAttr( p_sys->p_xml_reader ) == VLC_SUCCESS ) + while( xml_ReaderNextAttr( p_xml_reader ) == VLC_SUCCESS ) { - char *psz_attrname = xml_ReaderName( p_sys->p_xml_reader ); + char *psz_attrname = xml_ReaderName( p_xml_reader ); char *psz_attrvalue = - xml_ReaderValue( p_sys->p_xml_reader ); + xml_ReaderValue( p_xml_reader ); if( !psz_attrname || !psz_attrvalue ) { - free(psz_eltname); - FREENULL(psz_attrname); - FREENULL(psz_attrvalue); + free( psz_eltname ); + free( psz_attrname ); + free( psz_attrvalue ); return -1; } @@ -334,25 +320,25 @@ static int DemuxStation( demux_t *p_demux ) else { msg_Warn( p_demux, - "unexpected attribure %s in element %s", + "unexpected attribute %s in element %s", psz_attrname, psz_eltname ); + free( psz_attrvalue ); } free( psz_attrname ); - free( psz_attrvalue ); } } else if( !strcmp( psz_eltname, "station" ) ) { - while( xml_ReaderNextAttr( p_sys->p_xml_reader ) == VLC_SUCCESS ) + while( xml_ReaderNextAttr( p_xml_reader ) == VLC_SUCCESS ) { - char *psz_attrname = xml_ReaderName( p_sys->p_xml_reader ); + char *psz_attrname = xml_ReaderName( p_xml_reader ); char *psz_attrvalue = - xml_ReaderValue( p_sys->p_xml_reader ); + xml_ReaderValue( p_xml_reader ); if( !psz_attrname || !psz_attrvalue ) { - free(psz_eltname); - FREENULL(psz_attrname); - FREENULL(psz_attrvalue); + free( psz_eltname ); + free( psz_attrname ); + free( psz_attrvalue ); return -1; } @@ -370,12 +356,12 @@ static int DemuxStation( demux_t *p_demux ) msg_Warn( p_demux, "unexpected attribute %s in element %s", psz_attrname, psz_eltname ); + free( psz_attrvalue ); } free( psz_attrname ); - free( psz_attrvalue ); } } - free(psz_eltname); + free( psz_eltname ); break; case XML_READER_TEXT: @@ -384,51 +370,51 @@ static int DemuxStation( demux_t *p_demux ) // End element case XML_READER_ENDELEM: // Read the element name - psz_eltname = xml_ReaderName( p_sys->p_xml_reader ); + psz_eltname = xml_ReaderName( p_xml_reader ); if( !psz_eltname ) return -1; if( !strcmp( psz_eltname, "station" ) && ( psz_base || ( psz_rt && psz_load && - ( p_sys->b_adult || strcmp( psz_rt, "NC17" ) ) ) ) ) + ( b_adult || strcmp( psz_rt, "NC17" ) ) ) ) ) { char *psz_mrl = NULL; if( psz_rt || psz_load ) { /* tv */ - psz_mrl = malloc( strlen( SHOUTCAST_TV_TUNEIN_URL ) - + strlen( psz_id ) + 1 ); - sprintf( psz_mrl, SHOUTCAST_TV_TUNEIN_URL "%s", - psz_id ); + if( asprintf( &psz_mrl, SHOUTCAST_TV_TUNEIN_URL "%s", + psz_id ) == -1) + psz_mrl = NULL; } else { /* radio */ - psz_mrl = malloc( strlen( SHOUTCAST_TUNEIN_BASE_URL ) - + strlen( psz_base ) + strlen( "?id=" ) - + strlen( psz_id ) + 1 ); - sprintf( psz_mrl, SHOUTCAST_TUNEIN_BASE_URL "%s?id=%s", - psz_base, psz_id ); + if( asprintf( &psz_mrl, SHOUTCAST_TUNEIN_BASE_URL "%s?id=%s", + psz_base, psz_id ) == -1 ) + psz_mrl = NULL; } - p_input = input_ItemNewExt( p_sys->p_playlist, psz_mrl, - psz_name , 0, NULL, -1 ); - free( psz_mrl ); - input_ItemCopyOptions( p_sys->p_current_input, - p_input ); + /* Create the item */ + input_item_t *p_input; + p_input = input_item_New( p_demux, psz_mrl, psz_name ); + input_item_CopyOptions( p_input_node->p_item, p_input ); + free( psz_mrl ); -#define SADD_INFO( type, field ) if( field ) { input_ItemAddInfo( \ - p_input, _("Shoutcast"), _(type), "%s", field ) ; } - SADD_INFO( "Mime type", psz_mt ); - SADD_INFO( "Bitrate", psz_br ); - SADD_INFO( "Listeners", psz_lc ); - SADD_INFO( "Load", psz_load ); +#define SADD_INFO( type, field ) \ + if( field ) \ + input_item_AddInfo( p_input, _("Shoutcast"), \ + vlc_gettext(type), "%s", field ) + SADD_INFO( N_("Mime"), psz_mt ); + SADD_INFO( N_("Bitrate"), psz_br ); + SADD_INFO( N_("Listeners"), psz_lc ); + SADD_INFO( N_("Load"), psz_load ); if( psz_genre ) input_item_SetGenre( p_input, psz_genre ); if( psz_ct ) input_item_SetNowPlaying( p_input, psz_ct ); if( psz_rt ) input_item_SetRating( p_input, psz_rt ); - input_ItemAddSubItem( p_sys->p_current_input, p_input ); + input_item_node_AppendItem( p_input_node, p_input ); vlc_gc_decref( p_input ); + FREENULL( psz_base ); FREENULL( psz_name ); FREENULL( psz_mt ); FREENULL( psz_id ); @@ -437,6 +423,7 @@ static int DemuxStation( demux_t *p_demux ) FREENULL( psz_ct ); FREENULL( psz_lc ); FREENULL( psz_rt ); + FREENULL( psz_load ); } free( psz_eltname ); break;