X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Fdemux%2Fplaylist%2Fshoutcast.c;h=a8c2e5d92c02eb56fb4079917617d2d73b3ec192;hb=8e32c9aae4af29e450361731b6dc984097d4daf3;hp=da6385bc231cd9710fe9b95558e1f0f744d95abc;hpb=f0ddd6157663426507a2ac18ef1341e69fbed2bf;p=vlc diff --git a/modules/demux/playlist/shoutcast.c b/modules/demux/playlist/shoutcast.c index da6385bc23..a8c2e5d92c 100644 --- a/modules/demux/playlist/shoutcast.c +++ b/modules/demux/playlist/shoutcast.c @@ -25,28 +25,16 @@ /***************************************************************************** * Preamble *****************************************************************************/ -#include /* isspace() */ -#include -#include -#include +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif -#include /* ENOMEM */ -#include "playlist.h" -#include "vlc_xml.h" - -struct demux_sys_t -{ - playlist_t *p_playlist; - playlist_item_t *p_current; - playlist_item_t *p_item_in_category; - int i_parent_id; +#include +#include - xml_t *p_xml; - xml_reader_t *p_xml_reader; - - vlc_bool_t b_adult; -}; +#include "playlist.h" +#include /* duplicate from modules/services_discovery/shout.c */ #define SHOUTCAST_BASE_URL "http/shout-winamp://www.shoutcast.com/sbin/newxml.phtml" @@ -59,28 +47,24 @@ 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 *****************************************************************************/ -int E_(Import_Shoutcast)( vlc_object_t *p_this ) +int Import_Shoutcast( vlc_object_t *p_this ) { demux_t *p_demux = (demux_t *)p_this; - if( !isDemux( p_demux, "shout-winamp" ) ) + 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; } @@ -88,44 +72,28 @@ int E_(Import_Shoutcast)( vlc_object_t *p_this ) /***************************************************************************** * Deactivate: frees unused data *****************************************************************************/ -void E_(Close_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 = p_current; - p_sys->i_parent_id = i_parent_id; - p_sys->p_item_in_category = p_item_in_category; - - 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 || @@ -135,125 +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 ); - if( 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 VLC_SUCCESS; + 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; -#define FREE(a) if( a ) free( a ); a = NULL; - 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 ) { - FREE(psz_attrname); - FREE(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 ); - vlc_input_item_CopyOptions( p_sys->p_current->p_input, - p_input ); - free( psz_mrl ); - playlist_AddWhereverNeeded( p_sys->p_playlist, p_input, - p_sys->p_current, p_sys->p_item_in_category, - (p_sys->i_parent_id > 0 ) ? VLC_TRUE: VLC_FALSE, - PLAYLIST_APPEND ); - FREE( psz_name ); + 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 ); } - FREE( psz_eltname ); + free( psz_eltname ); break; + } } } - return 0; + i_ret = 0; + +error: + free( psz_name ); + return i_ret; } /* radio stations: @@ -281,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 */ @@ -302,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 @@ -317,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); - FREE(psz_attrname); - FREE(psz_attrvalue); + free( psz_eltname ); + free( psz_attrname ); + free( psz_attrvalue ); return -1; } @@ -340,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); - FREE(psz_attrname); - FREE(psz_attrvalue); + free( psz_eltname ); + free( psz_attrname ); + free( psz_attrvalue ); return -1; } @@ -376,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: @@ -390,65 +370,60 @@ 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" ) ) ) ) ) { - playlist_item_t *p_item; 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 ); - vlc_input_item_CopyOptions( p_sys->p_current->p_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 ) { vlc_input_item_AddInfo( \ - 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 ); - p_input->p_meta = vlc_meta_New(); +#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 ) - vlc_meta_SetGenre( p_input->p_meta, psz_genre ); + input_item_SetGenre( p_input, psz_genre ); if( psz_ct ) - vlc_meta_SetNowPlaying( p_input->p_meta, psz_ct ); + input_item_SetNowPlaying( p_input, psz_ct ); if( psz_rt ) - vlc_meta_SetRating( p_input->p_meta, psz_rt ); - - playlist_AddWhereverNeeded( p_sys->p_playlist, p_input, - p_sys->p_current, p_sys->p_item_in_category, - (p_sys->i_parent_id > 0 ) ? VLC_TRUE: VLC_FALSE, - PLAYLIST_APPEND ); - - FREE( psz_name ); - FREE( psz_mt ) - FREE( psz_id ) - FREE( psz_br ) - FREE( psz_genre ) - FREE( psz_ct ) - FREE( psz_lc ) - FREE( psz_rt ) + input_item_SetRating( p_input, psz_rt ); + 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 ); + FREENULL( psz_br ); + FREENULL( psz_genre ); + FREENULL( psz_ct ); + FREENULL( psz_lc ); + FREENULL( psz_rt ); + FREENULL( psz_load ); } free( psz_eltname ); break; @@ -456,9 +431,9 @@ static int DemuxStation( demux_t *p_demux ) } return 0; } -#undef FREE static int Control( demux_t *p_demux, int i_query, va_list args ) { + VLC_UNUSED(p_demux); VLC_UNUSED(i_query); VLC_UNUSED(args); return VLC_EGENERIC; }