shout.c
上传用户:kjfoods
上传日期:2020-07-06
资源大小:29949k
文件大小:9k
源码类别:

midi

开发平台:

Unix_Linux

  1. /*****************************************************************************
  2.  * shout.c:  Shoutcast services discovery module
  3.  *****************************************************************************
  4.  * Copyright (C) 2005-2007 the VideoLAN team
  5.  * $Id: b12dfbd9afb2337ba2c218e7696ed2fc1692e3bd $
  6.  *
  7.  * Authors: Sigmund Augdal Helberg <dnumgis@videolan.org>
  8.  *          Antoine Cellerier <dionoea -@T- videolan -d.t- org>
  9.  *          Pierre d'Herbemont <pdherbemont # videolan.org>
  10.  *
  11.  * This program is free software; you can redistribute it and/or modify
  12.  * it under the terms of the GNU General Public License as published by
  13.  * the Free Software Foundation; either version 2 of the License, or
  14.  * (at your option) any later version.
  15.  *
  16.  * This program is distributed in the hope that it will be useful,
  17.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  19.  * GNU General Public License for more details.
  20.  *
  21.  * You should have received a copy of the GNU General Public License
  22.  * along with this program; if not, write to the Free Software
  23.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  24.  *****************************************************************************/
  25. /*****************************************************************************
  26.  * Includes
  27.  *****************************************************************************/
  28. #ifdef HAVE_CONFIG_H
  29. # include "config.h"
  30. #endif
  31. #include <vlc_common.h>
  32. #include <vlc_plugin.h>
  33. #include <vlc_services_discovery.h>
  34. /*****************************************************************************
  35.  * Module descriptor
  36.  *****************************************************************************/
  37. enum type_e { ShoutRadio = 0, ShoutTV = 1, Freebox = 2, FrenchTV = 3 };
  38. static int  Open( vlc_object_t *, enum type_e );
  39. static void Close( vlc_object_t * );
  40. struct shout_item_t
  41. {
  42.     const char *psz_url;
  43.     const char *psz_name;
  44.     const char *ppsz_options[2];
  45.     const struct shout_item_t * p_children;
  46. };
  47. #define endItem( ) { NULL, NULL, { NULL }, NULL }
  48. #define item( title, url ) { url, title, { NULL }, NULL }
  49. #define itemWithOption( title, url, option ) { url, title, { option, NULL }, NULL }
  50. #define itemWithChildren( title, children ) { "vlc://nop", title, { NULL }, children }
  51. /* WARN: We support only two levels */
  52. static const struct shout_item_t p_frenchtv_canalplus[] = {
  53.     itemWithOption( N_("Les Guignols"), "http://www.canalplus.fr/index.php?pid=1784", "http-forward-cookies" ),
  54.     endItem()
  55. };
  56.     
  57. static const struct shout_item_t p_frenchtv[] = {
  58.     itemWithChildren( N_("Canal +"),  p_frenchtv_canalplus ),
  59.     endItem()
  60. };
  61. static const struct shout_item_t p_items[] = {
  62.     item(            N_("Shoutcast Radio"), "http/shout-winamp://www.shoutcast.com/sbin/newxml.phtml" ),
  63.     item(            N_("Shoutcast TV"),    "http/shout-winamp://www.shoutcast.com/sbin/newtvlister.phtml?alltv=1" ),
  64.     item(            N_("Freebox TV"),      "http://mafreebox.freebox.fr/freeboxtv/playlist.m3u" ),
  65.     itemWithChildren(N_("French TV"),        p_frenchtv ),
  66.     endItem()
  67. };
  68. #undef endItem
  69. #undef item
  70. #undef itemWithOptions
  71. #undef itemWithChildren
  72. struct shout_category_t {
  73.     services_discovery_t * p_sd;
  74.     const char * psz_category;
  75. };
  76. /* Main functions */
  77. #define OPEN( type )                                
  78. static int Open ## type ( vlc_object_t *p_this )    
  79. {                                                   
  80.     msg_Dbg( p_this, "Starting " #type );           
  81.     return Open( p_this, type );                    
  82. }
  83. OPEN( ShoutRadio )
  84. OPEN( ShoutTV )
  85. OPEN( Freebox )
  86. OPEN( FrenchTV )
  87. vlc_module_begin ()
  88.     set_category( CAT_PLAYLIST )
  89.     set_subcategory( SUBCAT_PLAYLIST_SD )
  90.     add_obsolete_integer( "shoutcast-limit" )
  91.         set_shortname( "Shoutcast")
  92.         set_description( N_("Shoutcast radio listings") )
  93.         set_capability( "services_discovery", 0 )
  94.         set_callbacks( OpenShoutRadio, Close )
  95.         add_shortcut( "shoutcast" )
  96.     add_submodule ()
  97.         set_shortname( "ShoutcastTV" )
  98.         set_description( N_("Shoutcast TV listings") )
  99.         set_capability( "services_discovery", 0 )
  100.         set_callbacks( OpenShoutTV, Close )
  101.         add_shortcut( "shoutcasttv" )
  102.     add_submodule ()
  103.         set_shortname( "frenchtv")
  104.         set_description( N_("French TV") )
  105.         set_capability( "services_discovery", 0 )
  106.         set_callbacks( OpenFrenchTV, Close )
  107.         add_shortcut( "frenchtv" )
  108.     add_submodule ()
  109.         set_shortname( "Freebox")
  110.         set_description( N_("Freebox TV listing (French ISP free.fr services)") )
  111.         set_capability( "services_discovery", 0 )
  112.         set_callbacks( OpenFreebox, Close )
  113.         add_shortcut( "freebox" )
  114. vlc_module_end ()
  115. /*****************************************************************************
  116.  * Local prototypes
  117.  *****************************************************************************/
  118. static void *Run( void * );
  119. struct services_discovery_sys_t
  120. {
  121.     vlc_thread_t thread;
  122.     enum type_e i_type;
  123. };
  124. /*****************************************************************************
  125.  * Open: initialize and create stuff
  126.  *****************************************************************************/
  127. static int Open( vlc_object_t *p_this, enum type_e i_type )
  128. {
  129.     services_discovery_t *p_sd = ( services_discovery_t* )p_this;
  130.     p_sd->p_sys = malloc (sizeof (*(p_sd->p_sys)));
  131.     if (p_sd->p_sys == NULL)
  132.         return VLC_ENOMEM;
  133.     p_sd->p_sys->i_type = i_type;
  134.     if (vlc_clone (&p_sd->p_sys->thread, Run, p_sd, VLC_THREAD_PRIORITY_LOW))
  135.     {
  136.         free (p_sd->p_sys);
  137.         return VLC_EGENERIC;
  138.     }
  139.     return VLC_SUCCESS;
  140. }
  141. /*****************************************************************************
  142.  * ItemAdded:
  143.  *****************************************************************************/
  144. static void ItemAdded( const vlc_event_t * p_event, void * user_data )
  145. {
  146.     struct shout_category_t * params = user_data;
  147.     services_discovery_AddItem( params->p_sd,
  148.             p_event->u.input_item_subitem_added.p_new_child,
  149.             params->psz_category );
  150. }
  151. /*****************************************************************************
  152.  * CreateInputItemFromShoutItem:
  153.  *****************************************************************************/
  154. static input_item_t * CreateInputItemFromShoutItem( services_discovery_t *p_sd,
  155.                                          const struct shout_item_t * p_item )
  156. {
  157.     int i;
  158.     /* Create the item */
  159.     input_item_t *p_input = input_item_New( p_sd, p_item->psz_url,
  160.                                             vlc_gettext(p_item->psz_name) );
  161.     /* Copy options */
  162.     for( i = 0; p_item->ppsz_options[i] != NULL; i++ )
  163.         input_item_AddOption( p_input, p_item->ppsz_options[i], VLC_INPUT_OPTION_TRUSTED );
  164.     input_item_AddOption( p_input, "no-playlist-autostart", VLC_INPUT_OPTION_TRUSTED );
  165.     return p_input;
  166. }
  167. /*****************************************************************************
  168.  * AddSubitemsOfShoutItemURL:
  169.  *****************************************************************************/
  170. static void AddSubitemsOfShoutItemURL( services_discovery_t *p_sd,
  171.                                        const struct shout_item_t * p_item,
  172.                                        const char * psz_category )
  173. {
  174.     struct shout_category_t category = { p_sd, psz_category };
  175.     /* Create the item */
  176.     input_item_t *p_input = CreateInputItemFromShoutItem( p_sd, p_item );
  177.     /* Read every subitems, and add them in ItemAdded */
  178.     vlc_event_attach( &p_input->event_manager, vlc_InputItemSubItemAdded,
  179.                       ItemAdded, &category );
  180.     input_Read( p_sd, p_input, true );
  181.     vlc_event_detach( &p_input->event_manager, vlc_InputItemSubItemAdded,
  182.                       ItemAdded, &category );
  183.     vlc_gc_decref( p_input );
  184. }
  185. /*****************************************************************************
  186.  * Run:
  187.  *****************************************************************************/
  188. static void *Run( void *data )
  189. {
  190.     services_discovery_t *p_sd = data;
  191.     services_discovery_sys_t *p_sys = p_sd->p_sys;
  192.     enum type_e i_type = p_sys->i_type;
  193.     int i, j;
  194.     int canc = vlc_savecancel();
  195.     
  196.     if( !p_items[i_type].p_children )
  197.     {
  198.         AddSubitemsOfShoutItemURL( p_sd, &p_items[i_type], NULL );
  199.         vlc_restorecancel(canc);
  200.         return NULL;
  201.     }
  202.     for( i = 0; p_items[i_type].p_children[i].psz_name; i++ )
  203.     {
  204.         const struct shout_item_t * p_subitem = &p_items[i_type].p_children[i];
  205.         if( !p_subitem->p_children )
  206.         {
  207.             AddSubitemsOfShoutItemURL( p_sd, p_subitem, p_subitem->psz_name );
  208.             continue;
  209.         }
  210.         for( j = 0; p_subitem->p_children[j].psz_name; j++ )
  211.         {
  212.             input_item_t *p_input = CreateInputItemFromShoutItem( p_sd, &p_subitem->p_children[j] );
  213.             services_discovery_AddItem( p_sd,
  214.                 p_input,
  215.                 p_subitem->psz_name );
  216.             vlc_gc_decref( p_input );
  217.         }
  218.     }
  219.     vlc_restorecancel(canc);
  220.     return NULL;
  221. }
  222. /*****************************************************************************
  223.  * Close:
  224.  *****************************************************************************/
  225. static void Close( vlc_object_t *p_this )
  226. {
  227.     services_discovery_t *p_sd = (services_discovery_t *)p_this;
  228.     services_discovery_sys_t *p_sys = p_sd->p_sys;
  229.     vlc_join (p_sys->thread, NULL);
  230.     free (p_sys);
  231. }