/* <genrelist> * <genre name="the name"></genre> * ... * </genrelist> **/ static int DemuxGenre( demux_t *p_demux, xml_reader_t *p_xml_reader, input_item_node_t *p_input_node ) { const char *node; char *psz_name = NULL; /* genre name */ int type; while( (type = xml_ReaderNextNode( p_xml_reader, &node )) > 0 ) { switch( type ) { case XML_READER_STARTELEM: { if( !strcmp( node, "genre" ) ) { // Read the attributes const char *name, *value; while( (name = xml_ReaderNextAttr( p_xml_reader, &value )) ) { if( !strcmp( name, "name" ) ) { free(psz_name); psz_name = strdup( value ); } else msg_Warn( p_demux, "unexpected attribute %s in <%s>", name, node ); } } break; } case XML_READER_ENDELEM: if( !strcmp( node, "genre" ) && psz_name != NULL ) { char* psz_mrl; if( asprintf( &psz_mrl, SHOUTCAST_BASE_URL "?genre=%s", psz_name ) != -1 ) { input_item_t *p_input; vlc_xml_decode( psz_mrl ); p_input = input_item_New( 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 ); } break; } } free( psz_name ); return 0; }
int access_fsdir_additem(struct access_fsdir *p_fsdir, const char *psz_uri, const char *psz_filename, int i_type, int i_net) { enum slave_type i_slave_type; struct fsdir_slave *p_fsdir_slave = NULL; input_item_node_t *p_node; if (p_fsdir->i_sub_autodetect_fuzzy != 0 && input_item_slave_GetType(psz_filename, &i_slave_type)) { p_fsdir_slave = malloc(sizeof(*p_fsdir_slave)); if (!p_fsdir_slave) return VLC_ENOMEM; p_fsdir_slave->p_node = NULL; p_fsdir_slave->psz_filename = strdup(psz_filename); p_fsdir_slave->p_slave = input_item_slave_New(psz_uri, i_slave_type, SLAVE_PRIORITY_MATCH_NONE); if (!p_fsdir_slave->p_slave || !p_fsdir_slave->psz_filename) { free(p_fsdir_slave->psz_filename); free(p_fsdir_slave); return VLC_ENOMEM; } INSERT_ELEM(p_fsdir->pp_slaves, p_fsdir->i_slaves, p_fsdir->i_slaves, p_fsdir_slave); } if (fsdir_is_ignored(p_fsdir, psz_filename)) return VLC_SUCCESS; input_item_t *p_item = input_item_NewExt(psz_uri, psz_filename, -1, i_type, i_net); if (p_item == NULL) return VLC_ENOMEM; input_item_CopyOptions(p_item, p_fsdir->p_node->p_item); p_node = input_item_node_AppendItem(p_fsdir->p_node, p_item); input_item_Release(p_item); /* A slave can also be an item. If there is a match, this item will be * removed from the parent node. This is not a common case, since most * slaves will be ignored by fsdir_is_ignored() */ if (p_fsdir_slave != NULL) p_fsdir_slave->p_node = p_node; return VLC_SUCCESS; }
bool MediaServer::addContainer( IXML_Element* containerElement ) { char* psz_url; const char* objectID = ixmlElement_getAttribute( containerElement, "id" ); if ( !objectID ) return false; const char* title = xml_getChildElementValue( containerElement, "dc:title" ); if ( !title ) return false; if( asprintf( &psz_url, "upnp://%s?ObjectID=%s", m_psz_root, objectID ) < 0 ) return false; input_item_t* p_item = input_item_NewDirectory( psz_url, title, ITEM_NET ); free( psz_url); if ( !p_item ) return false; input_item_CopyOptions( p_item, m_node->p_item ); input_item_node_AppendItem( m_node, p_item ); input_item_Release( p_item ); return true; }
static int Demux( demux_t *p_demux ) { char *psz_line; char *psz_name = NULL; char *psz_artist = NULL; char *psz_album_art = NULL; int i_parsed_duration = 0; mtime_t i_duration = -1; const char**ppsz_options = NULL; char * (*pf_dup) (const char *) = p_demux->p_sys->pf_dup; int i_options = 0; bool b_cleanup = false; input_item_t *p_input; input_item_t *p_current_input = GetCurrentItem(p_demux); input_item_node_t *p_subitems = input_item_node_Create( p_current_input ); psz_line = vlc_stream_ReadLine( p_demux->s ); while( psz_line ) { char *psz_parse = psz_line; /* Skip leading tabs and spaces */ while( *psz_parse == ' ' || *psz_parse == '\t' || *psz_parse == '\n' || *psz_parse == '\r' ) psz_parse++; if( *psz_parse == '#' ) { /* Parse extra info */ /* Skip leading tabs and spaces */ while( *psz_parse == ' ' || *psz_parse == '\t' || *psz_parse == '\n' || *psz_parse == '\r' || *psz_parse == '#' ) psz_parse++; if( !*psz_parse ) goto error; if( !strncasecmp( psz_parse, "EXTINF:", sizeof("EXTINF:") -1 ) ) { /* Extended info */ psz_parse += sizeof("EXTINF:") - 1; FREENULL( psz_name ); FREENULL( psz_artist ); parseEXTINF( psz_parse, &psz_artist, &psz_name, &i_parsed_duration ); if( i_parsed_duration >= 0 ) i_duration = i_parsed_duration * INT64_C(1000000); if( psz_name ) psz_name = pf_dup( psz_name ); if( psz_artist ) psz_artist = pf_dup( psz_artist ); } else if( !strncasecmp( psz_parse, "EXTVLCOPT:", sizeof("EXTVLCOPT:") -1 ) ) { /* VLC Option */ char *psz_option; psz_parse += sizeof("EXTVLCOPT:") -1; if( !*psz_parse ) goto error; psz_option = pf_dup( psz_parse ); if( psz_option ) INSERT_ELEM( ppsz_options, i_options, i_options, psz_option ); } /* Special case for jamendo which provide the albumart */ else if( !strncasecmp( psz_parse, "EXTALBUMARTURL:", sizeof( "EXTALBUMARTURL:" ) -1 ) ) { psz_parse += sizeof( "EXTALBUMARTURL:" ) - 1; free( psz_album_art ); psz_album_art = pf_dup( psz_parse ); } } else if( !strncasecmp( psz_parse, "RTSPtext", sizeof("RTSPtext") -1 ) ) { ;/* special case to handle QuickTime RTSPtext redirect files */ } else if( *psz_parse ) { char *psz_mrl; psz_parse = pf_dup( psz_parse ); if( !psz_name && psz_parse ) /* Use filename as name for relative entries */ psz_name = strdup( psz_parse ); psz_mrl = ProcessMRL( psz_parse, p_demux->p_sys->psz_prefix ); b_cleanup = true; if( !psz_mrl ) { free( psz_parse ); goto error; } p_input = input_item_NewExt( psz_mrl, psz_name, i_duration, ITEM_TYPE_UNKNOWN, ITEM_NET_UNKNOWN ); free( psz_parse ); free( psz_mrl ); if( !p_input ) goto error; input_item_AddOptions( p_input, i_options, ppsz_options, 0 ); input_item_CopyOptions( p_input, p_current_input ); if( !EMPTY_STR(psz_artist) ) input_item_SetArtist( p_input, psz_artist ); if( psz_name ) input_item_SetTitle( p_input, psz_name ); if( !EMPTY_STR(psz_album_art) ) input_item_SetArtURL( p_input, psz_album_art ); input_item_node_AppendItem( p_subitems, p_input ); vlc_gc_decref( p_input ); } error: /* Fetch another line */ free( psz_line ); psz_line = vlc_stream_ReadLine( p_demux->s ); if( !psz_line ) b_cleanup = true; if( b_cleanup ) { /* Cleanup state */ while( i_options-- ) free( (char*)ppsz_options[i_options] ); FREENULL( ppsz_options ); i_options = 0; FREENULL( psz_name ); FREENULL( psz_artist ); FREENULL( psz_album_art ); i_parsed_duration = 0; i_duration = -1; b_cleanup = false; } } input_item_node_PostAndDelete( p_subitems ); vlc_gc_decref(p_current_input); var_Destroy( p_demux, "m3u-extvlcopt" ); return 0; /* Needed for correct operation of go back */ }
/* 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; } }
/* <genrelist> * <genre name="the name"></genre> * ... * </genrelist> **/ static int DemuxGenre( demux_t *p_demux ) { 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; 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; if( !strcmp( psz_eltname, "genre" ) ) { // Read the attributes 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 ) { FREENULL(psz_attrname); FREENULL(psz_attrvalue); free(psz_eltname); /*FIXME: isn't return a bit too much. what about break*/ return -1; } GET_VALUE( name ) else { msg_Warn( p_demux, "unexpected attribure %s in element %s", psz_attrname,psz_eltname ); } free( psz_attrname ); free( psz_attrvalue ); } } free( psz_eltname ); psz_eltname = NULL; 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, "genre" ) ) { char* psz_mrl; if( asprintf( &psz_mrl, SHOUTCAST_BASE_URL "?genre=%s", psz_name ) != -1 ) { p_input = input_item_New( p_demux, psz_mrl, psz_name ); input_item_CopyOptions( p_sys->p_current_input, p_input ); free( psz_mrl ); input_item_AddSubItem( p_sys->p_current_input, p_input ); vlc_gc_decref( p_input ); } FREENULL( psz_name ); } FREENULL( psz_eltname ); break; } } return 0; }
static int GetTracks( access_t *p_access, input_item_t *p_current ) { access_sys_t *p_sys = p_access->p_sys; const int i_titles = ioctl_GetTracksMap( VLC_OBJECT(p_access), p_sys->vcddev, &p_sys->p_sectors ); if( i_titles <= 0 ) { if( i_titles < 0 ) msg_Err( p_access, "unable to count tracks" ); else if( i_titles <= 0 ) msg_Err( p_access, "no audio tracks found" ); return VLC_EGENERIC;; } /* */ input_item_SetName( p_current, "Audio CD" ); const char *psz_album = NULL; const char *psz_year = NULL; const char *psz_genre = NULL; const char *psz_artist = NULL; const char *psz_description = NULL; /* Return true if the given string is not NULL and not empty */ #define NONEMPTY( psz ) ( (psz) && *(psz) ) /* If the given string is NULL or empty, fill it by the return value of 'code' */ #define ON_EMPTY( psz, code ) do { if( !NONEMPTY( psz) ) { (psz) = code; } } while(0) /* Retreive CDDB information */ #ifdef HAVE_LIBCDDB char psz_year_buffer[4+1]; msg_Dbg( p_access, "fetching infos with CDDB" ); cddb_disc_t *p_disc = GetCDDBInfo( p_access, i_titles, p_sys->p_sectors ); if( p_disc ) { psz_album = cddb_disc_get_title( p_disc ); psz_genre = cddb_disc_get_genre( p_disc ); /* */ const unsigned i_year = cddb_disc_get_year( p_disc ); if( i_year > 0 ) { psz_year = psz_year_buffer; snprintf( psz_year_buffer, sizeof(psz_year_buffer), "%u", i_year ); } /* Set artist only if unique */ for( int i = 0; i < i_titles; i++ ) { cddb_track_t *t = cddb_disc_get_track( p_disc, i ); if( !t ) continue; const char *psz_track_artist = cddb_track_get_artist( t ); if( psz_artist && psz_track_artist && strcmp( psz_artist, psz_track_artist ) ) { psz_artist = NULL; break; } psz_artist = psz_track_artist; } } #endif /* CD-Text */ vlc_meta_t **pp_cd_text; int i_cd_text; if( ioctl_GetCdText( VLC_OBJECT(p_access), p_sys->vcddev, &pp_cd_text, &i_cd_text ) ) { msg_Dbg( p_access, "CD-TEXT information missing" ); i_cd_text = 0; pp_cd_text = NULL; } /* Retrieve CD-TEXT information but prefer CDDB */ if( i_cd_text > 0 && pp_cd_text[0] ) { const vlc_meta_t *p_disc = pp_cd_text[0]; ON_EMPTY( psz_album, vlc_meta_Get( p_disc, vlc_meta_Album ) ); ON_EMPTY( psz_genre, vlc_meta_Get( p_disc, vlc_meta_Genre ) ); ON_EMPTY( psz_artist, vlc_meta_Get( p_disc, vlc_meta_Artist ) ); ON_EMPTY( psz_description, vlc_meta_Get( p_disc, vlc_meta_Description ) ); } if( NONEMPTY( psz_album ) ) { input_item_SetName( p_current, psz_album ); input_item_SetAlbum( p_current, psz_album ); } if( NONEMPTY( psz_genre ) ) input_item_SetGenre( p_current, psz_genre ); if( NONEMPTY( psz_artist ) ) input_item_SetArtist( p_current, psz_artist ); if( NONEMPTY( psz_year ) ) input_item_SetDate( p_current, psz_year ); if( NONEMPTY( psz_description ) ) input_item_SetDescription( p_current, psz_description ); const mtime_t i_duration = (int64_t)( p_sys->p_sectors[i_titles] - p_sys->p_sectors[0] ) * CDDA_DATA_SIZE * 1000000 / 44100 / 2 / 2; input_item_SetDuration( p_current, i_duration ); input_item_node_t *p_root = input_item_node_Create( p_current ); /* Build title table */ for( int i = 0; i < i_titles; i++ ) { input_item_t *p_input_item; char *psz_uri, *psz_opt, *psz_first, *psz_last; char *psz_name; msg_Dbg( p_access, "track[%d] start=%d", i, p_sys->p_sectors[i] ); /* */ if( asprintf( &psz_uri, "cdda://%s", p_access->psz_location ) == -1 ) psz_uri = NULL; if( asprintf( &psz_opt, "cdda-track=%i", i+1 ) == -1 ) psz_opt = NULL; if( asprintf( &psz_first, "cdda-first-sector=%i",p_sys->p_sectors[i] ) == -1 ) psz_first = NULL; if( asprintf( &psz_last, "cdda-last-sector=%i", p_sys->p_sectors[i+1] ) == -1 ) psz_last = NULL; /* Define a "default name" */ if( asprintf( &psz_name, _("Audio CD - Track %02i"), (i+1) ) == -1 ) psz_name = NULL; /* Create playlist items */ const mtime_t i_duration = (int64_t)( p_sys->p_sectors[i+1] - p_sys->p_sectors[i] ) * CDDA_DATA_SIZE * 1000000 / 44100 / 2 / 2; p_input_item = input_item_NewWithType( psz_uri, psz_name, 0, NULL, 0, i_duration, ITEM_TYPE_DISC ); input_item_CopyOptions( p_current, p_input_item ); input_item_AddOption( p_input_item, psz_first, VLC_INPUT_OPTION_TRUSTED ); input_item_AddOption( p_input_item, psz_last, VLC_INPUT_OPTION_TRUSTED ); input_item_AddOption( p_input_item, psz_opt, VLC_INPUT_OPTION_TRUSTED ); const char *psz_track_title = NULL; const char *psz_track_artist = NULL; const char *psz_track_genre = NULL; const char *psz_track_description = NULL; #ifdef HAVE_LIBCDDB /* Retreive CDDB information */ if( p_disc ) { cddb_track_t *t = cddb_disc_get_track( p_disc, i ); if( t != NULL ) { psz_track_title = cddb_track_get_title( t ); psz_track_artist = cddb_track_get_artist( t ); } } #endif /* Retreive CD-TEXT information but prefer CDDB */ if( i+1 < i_cd_text && pp_cd_text[i+1] ) { const vlc_meta_t *t = pp_cd_text[i+1]; ON_EMPTY( psz_track_title, vlc_meta_Get( t, vlc_meta_Title ) ); ON_EMPTY( psz_track_artist, vlc_meta_Get( t, vlc_meta_Artist ) ); ON_EMPTY( psz_track_genre, vlc_meta_Get( t, vlc_meta_Genre ) ); ON_EMPTY( psz_track_description, vlc_meta_Get( t, vlc_meta_Description ) ); } /* */ ON_EMPTY( psz_track_artist, psz_artist ); ON_EMPTY( psz_track_genre, psz_genre ); ON_EMPTY( psz_track_description, psz_description ); /* */ if( NONEMPTY( psz_track_title ) ) { input_item_SetName( p_input_item, psz_track_title ); input_item_SetTitle( p_input_item, psz_track_title ); } if( NONEMPTY( psz_track_artist ) ) input_item_SetArtist( p_input_item, psz_track_artist ); if( NONEMPTY( psz_track_genre ) ) input_item_SetGenre( p_input_item, psz_track_genre ); if( NONEMPTY( psz_track_description ) ) input_item_SetDescription( p_input_item, psz_track_description ); if( NONEMPTY( psz_album ) ) input_item_SetAlbum( p_input_item, psz_album ); if( NONEMPTY( psz_year ) ) input_item_SetDate( p_input_item, psz_year ); char psz_num[3+1]; snprintf( psz_num, sizeof(psz_num), "%d", 1+i ); input_item_SetTrackNum( p_input_item, psz_num ); input_item_node_AppendItem( p_root, p_input_item ); vlc_gc_decref( p_input_item ); free( psz_uri ); free( psz_opt ); free( psz_name ); free( psz_first ); free( psz_last ); } #undef ON_EMPTY #undef NONEMPTY input_item_node_PostAndDelete( p_root ); /* */ for( int i = 0; i < i_cd_text; i++ ) { vlc_meta_t *p_meta = pp_cd_text[i]; if( !p_meta ) continue; vlc_meta_Delete( p_meta ); } free( pp_cd_text ); #ifdef HAVE_LIBCDDB if( p_disc ) cddb_disc_destroy( p_disc ); #endif return VLC_SUCCESS; }
static int Demux( demux_t *p_demux ) { char *psz_name = NULL; char *psz_line; char *psz_mrl = NULL; char *psz_mrl_orig = NULL; char *psz_key; char *psz_value; int i_item = -1; input_item_t *p_input; input_item_t *p_current_input = GetCurrentItem(p_demux); input_item_node_t *p_subitems = input_item_node_Create( p_current_input ); while( ( psz_line = stream_ReadLine( p_demux->s ) ) ) { if( !strncasecmp( psz_line, "[playlist]", sizeof("[playlist]")-1 ) || !strncasecmp( psz_line, "[Reference]", sizeof("[Reference]")-1 ) ) { free( psz_line ); continue; } psz_key = psz_line; psz_value = strchr( psz_line, '=' ); if( psz_value ) { *psz_value='\0'; psz_value++; } else { free( psz_line ); continue; } if( !strcasecmp( psz_key, "version" ) ) { msg_Dbg( p_demux, "pls file version: %s", psz_value ); free( psz_line ); continue; } if( !strcasecmp( psz_key, "numberofentries" ) ) { msg_Dbg( p_demux, "pls should have %d entries", atoi(psz_value) ); free( psz_line); continue; } /* find the number part of of file1, title1 or length1 etc */ int i_new_item; if( sscanf( psz_key, "%*[^0-9]%d", &i_new_item ) != 1 ) { msg_Warn( p_demux, "couldn't find number of items" ); free( psz_line ); continue; } if( i_item == -1 ) i_item = i_new_item; else if( i_item != i_new_item ) { /* we found a new item, insert the previous */ if( psz_mrl ) { p_input = input_item_New( psz_mrl, psz_name ); input_item_CopyOptions( p_current_input, p_input ); input_item_node_AppendItem( p_subitems, p_input ); vlc_gc_decref( p_input ); free( psz_mrl_orig ); psz_mrl_orig = psz_mrl = NULL; } else { msg_Warn( p_demux, "no file= part found for item %d", i_item ); } free( psz_name ); psz_name = NULL; i_item = i_new_item; } if( !strncasecmp( psz_key, "file", sizeof("file") -1 ) || !strncasecmp( psz_key, "Ref", sizeof("Ref") -1 ) ) { free( psz_mrl_orig ); psz_mrl_orig = psz_mrl = ProcessMRL( psz_value, p_demux->p_sys->psz_prefix ); if( !strncasecmp( psz_key, "Ref", sizeof("Ref") -1 ) ) { if( !strncasecmp( psz_mrl, "http://", sizeof("http://") -1 ) ) memcpy( psz_mrl, "mmsh", 4 ); } } else if( !strncasecmp( psz_key, "title", sizeof("title") -1 ) ) { free( psz_name ); psz_name = strdup( psz_value ); } else if( !strncasecmp( psz_key, "length", sizeof("length") -1 ) ) /* duration in seconds */; else { msg_Warn( p_demux, "unknown key found in pls file: %s", psz_key ); } free( psz_line ); } /* Add last object */ if( psz_mrl ) { p_input = input_item_New( psz_mrl, psz_name ); input_item_CopyOptions( p_current_input, p_input ); input_item_node_AppendItem( p_subitems, p_input ); vlc_gc_decref( p_input ); free( psz_mrl_orig ); } else { msg_Warn( p_demux, "no file= part found for item %d", i_item ); } free( psz_name ); psz_name = NULL; input_item_node_PostAndDelete( p_subitems ); vlc_gc_decref(p_current_input); return 0; /* Needed for correct operation of go back */ }
/* 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; }
int __vlclua_playlist_add_internal( vlc_object_t *p_this, lua_State *L, playlist_t *p_playlist, input_item_t *p_parent, bool b_play ) { int i_count = 0; input_item_node_t *p_parent_node = NULL; assert( p_parent || p_playlist ); /* playlist */ if( lua_istable( L, -1 ) ) { if( p_parent ) p_parent_node = input_item_node_Create( p_parent ); lua_pushnil( L ); /* playlist nil */ while( lua_next( L, -2 ) ) { /* playlist key item */ /* <Parse playlist item> */ if( lua_istable( L, -1 ) ) { lua_getfield( L, -1, "path" ); /* playlist key item path */ if( lua_isstring( L, -1 ) ) { const char *psz_path = NULL; const char *psz_name = NULL; char **ppsz_options = NULL; int i_options = 0; mtime_t i_duration = -1; input_item_t *p_input; /* Read path and name */ psz_path = lua_tostring( L, -1 ); msg_Dbg( p_this, "Path: %s", psz_path ); lua_getfield( L, -2, "name" ); /* playlist key item path name */ if( lua_isstring( L, -1 ) ) { psz_name = lua_tostring( L, -1 ); msg_Dbg( p_this, "Name: %s", psz_name ); } else { if( !lua_isnil( L, -1 ) ) msg_Warn( p_this, "Playlist item name should be a string." ); psz_name = psz_path; } /* Read duration */ lua_getfield( L, -3, "duration" ); /* playlist key item path name duration */ if( lua_isnumber( L, -1 ) ) { i_duration = (mtime_t)(lua_tonumber( L, -1 )*1e6); } else if( !lua_isnil( L, -1 ) ) { msg_Warn( p_this, "Playlist item duration should be a number (in seconds)." ); } lua_pop( L, 1 ); /* pop "duration" */ /* playlist key item path name */ /* Read options: item must be on top of stack */ lua_pushvalue( L, -3 ); /* playlist key item path name item */ vlclua_read_options( p_this, L, &i_options, &ppsz_options ); /* Create input item */ p_input = input_item_NewExt( p_playlist, psz_path, psz_name, i_options, (const char **)ppsz_options, VLC_INPUT_OPTION_TRUSTED, i_duration ); lua_pop( L, 3 ); /* pop "path name item" */ /* playlist key item */ /* Read meta data: item must be on top of stack */ vlclua_read_meta_data( p_this, L, p_input ); /* Read custom meta data: item must be on top of stack*/ vlclua_read_custom_meta_data( p_this, L, p_input ); /* Append item to playlist */ if( p_parent ) /* Add to node */ { input_item_CopyOptions( p_parent, p_input ); input_item_node_AppendItem( p_parent_node, p_input ); } else /* Play or Enqueue (preparse) */ /* FIXME: playlist_AddInput() can fail */ playlist_AddInput( p_playlist, p_input, PLAYLIST_APPEND | ( b_play ? PLAYLIST_GO : PLAYLIST_PREPARSE ), PLAYLIST_END, true, false ); i_count ++; /* increment counter */ vlc_gc_decref( p_input ); while( i_options > 0 ) free( ppsz_options[--i_options] ); free( ppsz_options ); } else { lua_pop( L, 1 ); /* pop "path" */ msg_Warn( p_this, "Playlist item's path should be a string" ); } /* playlist key item */ } else { msg_Warn( p_this, "Playlist item should be a table" ); } /* <Parse playlist item> */ lua_pop( L, 1 ); /* pop the value, keep the key for * the next lua_next() call */ /* playlist key */ } /* playlist */ if( p_parent ) { if( i_count ) input_item_node_PostAndDelete( p_parent_node ); else input_item_node_Delete( p_parent_node ); } } else { msg_Warn( p_this, "Playlist should be a table." ); } return i_count; }
bool MediaServer::addItem( IXML_Element* itemElement ) { ItemDescriptionHolder holder; if (!holder.init(itemElement)) return false; /* Try to extract all resources in DIDL */ IXML_NodeList* p_resource_list = ixmlDocument_getElementsByTagName( (IXML_Document*) itemElement, "res" ); if ( !p_resource_list) return false; int list_lenght = ixmlNodeList_length( p_resource_list ); if (list_lenght <= 0 ) { ixmlNodeList_free( p_resource_list ); return false; } input_item_t *p_item = NULL; for (int index = 0; index < list_lenght; index++) { IXML_Element* p_resource = ( IXML_Element* ) ixmlNodeList_item( p_resource_list, index ); const char* rez_type = ixmlElement_getAttribute( p_resource, "protocolInfo" ); if (strncmp(rez_type, "http-get:*:video/", 17) == 0 && holder.media_type == ItemDescriptionHolder::VIDEO) { if (!p_item) p_item = holder.createNewItem(p_resource); holder.addSubtitleSlave(p_resource); } else if (strncmp(rez_type, "http-get:*:image/", 17) == 0) switch (holder.media_type) { case ItemDescriptionHolder::IMAGE: if (!p_item) { p_item = holder.createNewItem(p_resource); break; } case ItemDescriptionHolder::VIDEO: case ItemDescriptionHolder::AUDIO: holder.setArtworkURL(p_resource); break; } else if (strncmp(rez_type, "http-get:*:text/", 16) == 0) holder.addSlave(xml_getChildElementValue( p_resource, "res" ), SLAVE_TYPE_SPU); else if (strncmp(rez_type, "http-get:*:audio/", 17) == 0) { if (holder.media_type == ItemDescriptionHolder::AUDIO) { if (!p_item) p_item = holder.createNewItem(p_resource); } else holder.addSlave(xml_getChildElementValue( p_resource, "res" ), SLAVE_TYPE_AUDIO); } } ixmlNodeList_free( p_resource_list ); if (!p_item) return false; holder.apply(p_item); input_item_CopyOptions( p_item, m_node->p_item ); input_item_node_AppendItem( m_node, p_item ); input_item_Release( p_item ); return true; }
static int Demux( demux_t *p_demux ) { const char *psz_node = NULL; char *psz_txt = NULL; char *psz_base = FindPrefix( p_demux ); char *psz_title_asx = NULL; char *psz_entryref = NULL; xml_reader_t *p_xml_reader = NULL; input_item_t *p_current_input = GetCurrentItem( p_demux ); input_item_node_t *p_subitems = NULL; bool b_first_node = false; int i_type; int i_n_entry = 0; p_xml_reader = xml_ReaderCreate( p_demux, p_demux->s ); if( !p_xml_reader ) { msg_Err( p_demux, "Cannot parse ASX input file as XML"); goto error; } p_subitems = input_item_node_Create( p_current_input ); do { i_type = xml_ReaderNextNode( p_xml_reader, &psz_node ); if( i_type == XML_READER_STARTELEM ) { if( !b_first_node ) { if(!strncasecmp( psz_node, "ASX", 3 ) ) b_first_node = true; else { msg_Err( p_demux, "invalid root node" ); goto error; } } /* Metadata Node Handler */ if( !strncasecmp( psz_node, "TITLE", 5 ) ) { ReadElement( p_xml_reader, &psz_title_asx ); input_item_SetTitle( p_current_input, psz_title_asx ); } else if( !strncasecmp( psz_node, "AUTHOR", 6 ) ) { ReadElement( p_xml_reader, &psz_txt ); input_item_SetArtist( p_current_input, psz_txt ); } else if( !strncasecmp( psz_node, "COPYRIGHT", 9 ) ) { ReadElement( p_xml_reader, &psz_txt ); input_item_SetCopyright( p_current_input, psz_txt ); } else if( !strncasecmp( psz_node, "MOREINFO", 8 ) ) { const char *psz_tmp; do { psz_tmp = xml_ReaderNextAttr( p_xml_reader, &psz_node ); } while( psz_tmp && strncasecmp( psz_tmp, "HREF", 4 ) ); if( !psz_tmp ) // If HREF attribute doesn't exist ReadElement( p_xml_reader, &psz_txt ); else psz_txt = strdup( psz_node ); resolve_xml_special_chars( psz_txt ); input_item_SetURL( p_current_input, psz_txt ); } else if( !strncasecmp( psz_node, "ABSTRACT", 8 ) ) { ReadElement( p_xml_reader, &psz_txt ); input_item_SetDescription( p_current_input, psz_txt ); } else /* Base Node handler */ if( !strncasecmp( psz_node, "BASE", 4 ) ) ReadElement( p_xml_reader, &psz_base ); else /* Entry Ref Handler */ if( !strncasecmp( psz_node, "ENTRYREF", 7 ) ) { const char *psz_tmp; do { psz_tmp = xml_ReaderNextAttr( p_xml_reader, &psz_node ); } while( psz_tmp && !strncasecmp( psz_tmp, "HREF", 4 ) ); /* Create new input item */ input_item_t *p_input; psz_txt = strdup( psz_node ); resolve_xml_special_chars( psz_txt ); p_input = input_item_New( psz_txt, psz_title_asx ); input_item_CopyOptions( p_current_input, p_input ); input_item_node_AppendItem( p_subitems, p_input ); vlc_gc_decref( p_input ); } else /* Entry Handler */ if( !strncasecmp( psz_node, "ENTRY", 5 ) ) { ProcessEntry( &i_n_entry, p_xml_reader, p_subitems, p_current_input, psz_base); } /* FIXME Unsupported elements PARAM EVENT REPEAT ENDMARK STARTMARK */ } } while( i_type != XML_READER_ENDELEM || strncasecmp( psz_node, "ASX", 3 ) ); input_item_node_PostAndDelete( p_subitems ); p_subitems = NULL; error: free( psz_base ); free( psz_title_asx ); free( psz_entryref ); free( psz_txt ); if( p_xml_reader) xml_ReaderDelete( p_xml_reader ); if( p_subitems ) input_item_node_Delete( p_subitems ); vlc_gc_decref( p_current_input ); return 0; }
static void ProcessEntry( int *pi_n_entry, xml_reader_t *p_xml_reader, input_item_node_t *p_subitems, input_item_t *p_current_input, char *psz_prefix ) { const char *psz_node = NULL; const char *psz_txt = NULL; int i_type; char *psz_title = NULL; char *psz_artist = NULL; char *psz_copyright = NULL; char *psz_moreinfo = NULL; char *psz_description = NULL; char *psz_name = NULL; char *psz_mrl = NULL; char *psz_href = NULL; input_item_t *p_entry = NULL; int i_options; mtime_t i_start = 0; mtime_t i_duration = 0; char *ppsz_options[2]; do { i_type = xml_ReaderNextNode( p_xml_reader, &psz_node ); if( i_type == XML_READER_STARTELEM ) { /* Metadata Node */ if( !strncasecmp( psz_node, "TITLE", 5 ) ) ReadElement( p_xml_reader, &psz_title ); else if( !strncasecmp( psz_node, "AUTHOR", 6 ) ) ReadElement( p_xml_reader, &psz_artist ); else if( !strncasecmp( psz_node, "COPYRIGHT", 9 ) ) ReadElement( p_xml_reader, &psz_copyright ); else if( !strncasecmp( psz_node,"MOREINFO", 8 ) ) { do { psz_txt = xml_ReaderNextAttr( p_xml_reader, &psz_node ); } while(psz_txt && strncasecmp( psz_txt, "HREF", 4 ) ); if( !psz_txt ) ReadElement( p_xml_reader, &psz_moreinfo ); else psz_moreinfo = strdup( psz_node ); resolve_xml_special_chars( psz_moreinfo ); } else if( !strncasecmp( psz_node, "ABSTRACT", 8 ) ) ReadElement( p_xml_reader, &psz_description ); else if( !strncasecmp( psz_node, "DURATION", 8 ) ) i_duration = ParseTime( p_xml_reader ); else if( !strncasecmp( psz_node, "STARTTIME", 9 ) ) i_start = ParseTime( p_xml_reader ); else /* Reference Node */ /* All ref node will be converted into an entry */ if( !strncasecmp( psz_node, "REF", 3 ) ) { *pi_n_entry = *pi_n_entry + 1; if( !psz_title ) psz_title = input_item_GetTitle( p_current_input ); if( !psz_artist ) psz_artist = input_item_GetArtist( p_current_input ); if( !psz_copyright ) psz_copyright = input_item_GetCopyright( p_current_input ); if( !psz_description ) psz_description = input_item_GetDescription( p_current_input ); do { psz_txt = xml_ReaderNextAttr( p_xml_reader, &psz_node ); } while( strncasecmp( psz_txt, "HREF", 4) ); psz_href = strdup( psz_node ); if( asprintf( &psz_name, "%d. %s", *pi_n_entry, psz_title ) == -1) psz_name = strdup( psz_title ); resolve_xml_special_chars( psz_href ); psz_mrl = ProcessMRL( psz_href, psz_prefix ); /* Add Time information */ i_options = 0; if( i_start ) { if( asprintf( ppsz_options, ":start-time=%d" ,(int) i_start/1000000 ) != -1) i_options++; } if( i_duration) { if( asprintf( ppsz_options + i_options, ":stop-time=%d", (int) (i_start+i_duration)/1000000 ) != -1) i_options++; } /* Create the input item */ p_entry = input_item_NewExt( psz_mrl, psz_name, i_options, (const char* const*) ppsz_options, VLC_INPUT_OPTION_TRUSTED, i_duration ); input_item_CopyOptions( p_current_input, p_entry ); /* Add the metadata */ if( psz_name ) input_item_SetTitle( p_entry, psz_name ); if( psz_artist ) input_item_SetArtist( p_entry, psz_artist ); if( psz_copyright ) input_item_SetCopyright( p_entry, psz_copyright ); if( psz_moreinfo ) input_item_SetURL( p_entry, psz_moreinfo ); if( psz_description ) input_item_SetDescription( p_entry, psz_description ); if( i_duration > 0) input_item_SetDuration( p_entry, i_duration ); input_item_node_AppendItem( p_subitems, p_entry ); while( i_options ) free( ppsz_options[--i_options] ); free( psz_name ); free( psz_mrl ); } } } while( i_type != XML_READER_ENDELEM || strncasecmp( psz_node, "ENTRY", 5 ) ); free( psz_href ); free( psz_title ); free( psz_artist ); free( psz_copyright ); free( psz_moreinfo ); free( psz_description ); }
/***************************************************************************** * Demux: reads and demuxes data packets ***************************************************************************** * Returns -1 in case of error, 0 in case of EOF, 1 otherwise *****************************************************************************/ static int Demux ( demux_t *p_demux ) { demux_sys_t *p_sys = p_demux->p_sys; input_item_t *p_child = NULL; char *psz_line; input_item_t *p_current_input = GetCurrentItem(p_demux); while( ( psz_line = stream_ReadLine( p_demux->s ) ) ) { ParseLine( p_demux, psz_line ); free( psz_line ); } if( p_sys->psz_mcast_ip ) { /* Definetly schedules multicast session */ /* We don't care if it's live or not */ free( p_sys->psz_uri ); if( asprintf( &p_sys->psz_uri, "udp://@" "%s:%i", p_sys->psz_mcast_ip, p_sys->i_mcast_port ) == -1 ) { p_sys->psz_uri = NULL; return -1; } } if( p_sys->psz_uri == NULL ) { if( p_sys->psz_server && p_sys->psz_location ) { if( asprintf( &p_sys->psz_uri, "rtsp://" "%s:%i%s", p_sys->psz_server, p_sys->i_port > 0 ? p_sys->i_port : 554, p_sys->psz_location ) == -1 ) { p_sys->psz_uri = NULL; return -1; } } } if( p_sys->b_concert ) { /* It's definetly a simulcasted scheduled stream */ /* We don't care if it's live or not */ if( p_sys->psz_uri == NULL ) { msg_Err( p_demux, "no URI was found" ); return -1; } char *uri; if( asprintf( &uri, "%s%%3FMeDiAbAsEshowingId=%d%%26MeDiAbAsEconcert" "%%3FMeDiAbAsE", p_sys->psz_uri, p_sys->i_sid ) == -1 ) return -1; free( p_sys->psz_uri ); p_sys->psz_uri = uri; } p_child = input_item_NewWithType( p_sys->psz_uri, p_sys->psz_name ? p_sys->psz_name : p_sys->psz_uri, 0, NULL, 0, p_sys->i_duration, ITEM_TYPE_NET ); if( !p_child ) { msg_Err( p_demux, "A valid playlistitem could not be created" ); return -1; } input_item_CopyOptions( p_current_input, p_child ); if( p_sys->i_packet_size && p_sys->psz_mcast_ip ) { char *psz_option; p_sys->i_packet_size += 1000; if( asprintf( &psz_option, "mtu=%i", p_sys->i_packet_size ) != -1 ) { input_item_AddOption( p_child, psz_option, VLC_INPUT_OPTION_TRUSTED ); free( psz_option ); } } if( !p_sys->psz_mcast_ip ) input_item_AddOption( p_child, "rtsp-caching=5000", VLC_INPUT_OPTION_TRUSTED ); if( !p_sys->psz_mcast_ip && p_sys->b_rtsp_kasenna ) input_item_AddOption( p_child, "rtsp-kasenna", VLC_INPUT_OPTION_TRUSTED ); input_item_PostSubItem( p_current_input, p_child ); vlc_gc_decref( p_child ); vlc_gc_decref(p_current_input); return 0; /* Needed for correct operation of go back */ }