static void read_head( demux_t* p_demux, input_item_t* p_input ) { demux_sys_t* p_sys = p_demux->p_sys; const char* psz_name; int i_type; do { i_type = xml_ReaderNextNode( p_sys->p_reader, &psz_name ); if ( !strcasecmp( psz_name, "meta" ) ) { char* psz_attribute_name = NULL; char* psz_attribute_value = NULL; while (!psz_attribute_name || !psz_attribute_value) { const char* psz_attr = NULL; const char* psz_val = NULL; psz_attr = xml_ReaderNextAttr( p_sys->p_reader, &psz_val ); if ( !psz_attr || !psz_val ) break; if ( !strcasecmp( psz_attr, "name" ) ) psz_attribute_name = strdup( psz_val ); else if ( !strcasecmp( psz_attr, "content" ) ) psz_attribute_value = strdup( psz_val ); } if ( psz_attribute_name && psz_attribute_value ) { if ( !strcasecmp( psz_attribute_name, "TotalDuration" ) ) input_item_SetDuration( p_input, atoll( psz_attribute_value ) ); else if ( !strcasecmp( psz_attribute_name, "Author" ) ) input_item_SetPublisher( p_input, psz_attribute_value ); else if ( !strcasecmp( psz_attribute_name, "Rating" ) ) input_item_SetRating( p_input, psz_attribute_value ); else if ( !strcasecmp( psz_attribute_name, "Genre" ) ) input_item_SetGenre( p_input, psz_attribute_value ); } free( psz_attribute_name ); free( psz_attribute_value ); } else if ( !strcasecmp( psz_name, "title" ) ) { const char* psz_title; int i_type = xml_ReaderNextNode( p_sys->p_reader, &psz_title ); if ( i_type == XML_READER_TEXT && psz_title != NULL ) input_item_SetTitle( p_input, psz_title ); } } while ( i_type != XML_READER_ENDELEM || strcasecmp( psz_name, "head" ) ); }
static void AddTrack( services_discovery_t *p_sd, LIBMTP_track_t *p_track ) { input_item_t *p_input; char *psz_string; char *extension; extension = rindex( p_track->filename, '.' ); if( asprintf( &psz_string, "mtp://%"PRIu32":%"PRIu8":%"PRIu16":%d%s", p_sd->p_sys->i_bus, p_sd->p_sys->i_dev, p_sd->p_sys->i_product_id, p_track->item_id, extension ) == -1 ) { msg_Err( p_sd, "Error adding %s, skipping it", p_track->filename ); return; } if( ( p_input = input_item_New( psz_string, p_track->title ) ) == NULL ) { msg_Err( p_sd, "Error adding %s, skipping it", p_track->filename ); free( psz_string ); return; } free( psz_string ); input_item_SetArtist( p_input, p_track->artist ); input_item_SetGenre( p_input, p_track->genre ); input_item_SetAlbum( p_input, p_track->album ); if( asprintf( &psz_string, "%d", p_track->tracknumber ) != -1 ) { input_item_SetTrackNum( p_input, psz_string ); free( psz_string ); } if( asprintf( &psz_string, "%d", p_track->rating ) != -1 ) { input_item_SetRating( p_input, psz_string ); free( psz_string ); } input_item_SetDate( p_input, p_track->date ); input_item_SetDuration( p_input, p_track->duration * 1000 ); services_discovery_AddItem( p_sd, p_input, NULL ); p_sd->p_sys->pp_items[p_sd->p_sys->i_count++] = p_input; }
/* radio stations: * <stationlist> * <tunein base="/sbin/tunein-station.pls"></tunein> * <station name="the name" * mt="mime type" * id="the id" * br="bit rate" * genre="A big genre string" * ct="current track name/author/..." * lc="listener count"></station> * </stationlist> * * TV stations: * <stationlist> * <tunein base="/sbin/tunein-station.pls"></tunein> * <station name="the name" * id="the id" * br="bit rate" * rt="rating" * load="server load ?" * ct="current track name/author/..." * genre="A big genre string" * lc="listener count"></station> * </stationlist> **/ static int DemuxStation( demux_t *p_demux ) { demux_sys_t *p_sys = p_demux->p_sys; input_item_t *p_input; char *psz_base = NULL; /* */ char *psz_name = NULL; /* genre name */ char *psz_mt = NULL; /* mime type */ char *psz_id = NULL; /* id */ char *psz_br = NULL; /* bit rate */ char *psz_genre = NULL; /* genre */ char *psz_ct = NULL; /* current track */ char *psz_lc = NULL; /* listener count */ /* If these are set then it's *not* a radio but a TV */ char *psz_rt = NULL; /* rating for shoutcast TV */ char *psz_load = NULL; /* load for shoutcast TV */ char *psz_eltname = NULL; /* tag name */ while( xml_ReaderRead( p_sys->p_xml_reader ) == 1 ) { int i_type; // Get the node type i_type = xml_ReaderNodeType( p_sys->p_xml_reader ); switch( i_type ) { // Error case -1: return -1; break; case XML_READER_STARTELEM: // Read the element name psz_eltname = xml_ReaderName( p_sys->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 ) { char *psz_attrname = xml_ReaderName( p_sys->p_xml_reader ); char *psz_attrvalue = xml_ReaderValue( p_sys->p_xml_reader ); if( !psz_attrname || !psz_attrvalue ) { free( psz_eltname ); free( psz_attrname ); free( psz_attrvalue ); return -1; } GET_VALUE( base ) else { msg_Warn( p_demux, "unexpected attribure %s in element %s", psz_attrname, psz_eltname ); } free( psz_attrname ); free( psz_attrvalue ); } } else if( !strcmp( psz_eltname, "station" ) ) { while( xml_ReaderNextAttr( p_sys->p_xml_reader ) == VLC_SUCCESS ) { char *psz_attrname = xml_ReaderName( p_sys->p_xml_reader ); char *psz_attrvalue = xml_ReaderValue( p_sys->p_xml_reader ); if( !psz_attrname || !psz_attrvalue ) { free( psz_eltname ); free( psz_attrname ); free( psz_attrvalue ); return -1; } GET_VALUE( name ) else GET_VALUE( mt ) else GET_VALUE( id ) else GET_VALUE( br ) else GET_VALUE( genre ) else GET_VALUE( ct ) else GET_VALUE( lc ) else GET_VALUE( rt ) else GET_VALUE( load ) else { msg_Warn( p_demux, "unexpected attribute %s in element %s", psz_attrname, psz_eltname ); } free( psz_attrname ); free( psz_attrvalue ); } } 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; if( !strcmp( psz_eltname, "station" ) && ( psz_base || ( psz_rt && psz_load && ( p_sys->b_adult || strcmp( psz_rt, "NC17" ) ) ) ) ) { char *psz_mrl = NULL; if( psz_rt || psz_load ) { /* tv */ if( asprintf( &psz_mrl, SHOUTCAST_TV_TUNEIN_URL "%s", psz_id ) == -1) psz_mrl = NULL; } else { /* radio */ if( asprintf( &psz_mrl, SHOUTCAST_TUNEIN_BASE_URL "%s?id=%s", psz_base, psz_id ) == -1 ) psz_mrl = NULL; } p_input = input_item_New( p_demux, psz_mrl, psz_name ); input_item_CopyOptions( p_sys->p_current_input, p_input ); free( psz_mrl ); #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_item_AddSubItem( p_sys->p_current_input, p_input ); vlc_gc_decref( p_input ); FREENULL( psz_name ); FREENULL( psz_mt ); FREENULL( psz_id ); FREENULL( psz_br ); FREENULL( psz_genre ); FREENULL( psz_ct ); FREENULL( psz_lc ); FREENULL( psz_rt ); } free( psz_eltname ); break; } }
/* radio stations: * <stationlist> * <tunein base="/sbin/tunein-station.pls"></tunein> * <station name="the name" * mt="mime type" * id="the id" * br="bit rate" * genre="A big genre string" * ct="current track name/author/..." * lc="listener count"></station> * </stationlist> * * TV stations: * <stationlist> * <tunein base="/sbin/tunein-station.pls"></tunein> * <station name="the name" * id="the id" * br="bit rate" * rt="rating" * load="server load ?" * ct="current track name/author/..." * genre="A big genre string" * lc="listener count"></station> * </stationlist> **/ static int DemuxStation( demux_t *p_demux, xml_reader_t *p_xml_reader, input_item_node_t *p_input_node, bool b_adult ) { char *psz_base = NULL; /* */ char *psz_name = NULL; /* genre name */ char *psz_mt = NULL; /* mime type */ char *psz_id = NULL; /* id */ char *psz_br = NULL; /* bit rate */ char *psz_genre = NULL; /* genre */ char *psz_ct = NULL; /* current track */ char *psz_lc = NULL; /* listener count */ /* If these are set then it's *not* a radio but a TV */ char *psz_rt = NULL; /* rating for shoutcast TV */ char *psz_load = NULL; /* load for shoutcast TV */ const char *node; /* tag name */ int i_type; while( (i_type = xml_ReaderNextNode( p_xml_reader, &node )) > 0 ) { switch( i_type ) { case XML_READER_STARTELEM: // Read the attributes if( !strcmp( node, "tunein" ) ) { const char *name, *value; while( (name = xml_ReaderNextAttr( p_xml_reader, &value )) ) { if( !strcmp( name, "base" ) ) { free( psz_base ); psz_base = strdup( value ); } else msg_Warn( p_demux, "unexpected attribute %s in <%s>", name, node ); } } else if( !strcmp( node, "station" ) ) { const char *name, *value; while( (name = xml_ReaderNextAttr( p_xml_reader, &value )) ) { char **p = NULL; if( !strcmp( name, "name" ) ) p = &psz_name; else if ( !strcmp( name, "mt" ) ) p = &psz_mt; else if ( !strcmp( name, "id" ) ) p = &psz_id; else if ( !strcmp( name, "br" ) ) p = &psz_br; else if ( !strcmp( name, "genre" ) ) p = &psz_genre; else if ( !strcmp( name, "ct" ) ) p = &psz_ct; else if ( !strcmp( name, "lc" ) ) p = &psz_lc; else if ( !strcmp( name, "rt" ) ) p = &psz_rt; else if ( !strcmp( name, "load" ) ) p = &psz_load; if( p != NULL ) { free( *p ); *p = strdup( value ); } else msg_Warn( p_demux, "unexpected attribute %s in <%s>", name, node ); } } break; // End element case XML_READER_ENDELEM: if( !strcmp( node, "station" ) && ( psz_base || ( psz_rt && psz_load && ( b_adult || strcmp( psz_rt, "NC17" ) ) ) ) ) { char *psz_mrl = NULL; if( psz_rt || psz_load ) { /* tv */ if( asprintf( &psz_mrl, SHOUTCAST_TV_TUNEIN_URL "%s", psz_id ) == -1) psz_mrl = NULL; } else { /* radio */ if( asprintf( &psz_mrl, SHOUTCAST_TUNEIN_BASE_URL "%s?id=%s", psz_base, psz_id ) == -1 ) psz_mrl = NULL; } /* Create the item */ input_item_t *p_input; p_input = input_item_New( 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_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_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 ); } break; } } /* FIXME: leaks on missing ENDELEMENT? */ return 0; }