m3u.c
上传用户:riyaled888
上传日期:2009-03-27
资源大小:7338k
文件大小:23k
源码类别:

多媒体

开发平台:

MultiPlatform

  1. /*****************************************************************************
  2.  * m3u.c: a meta demux to parse pls, m3u, asx et b4s playlists
  3.  *****************************************************************************
  4.  * Copyright (C) 2001-2004 VideoLAN
  5.  * $Id: m3u.c 9105 2004-11-02 12:50:17Z hartman $
  6.  *
  7.  * Authors: Sigmund Augdal <sigmunau@idi.ntnu.no>
  8.  *          Gildas Bazin <gbazin@netcourrier.com>
  9.  *          Cl閙ent Stenac <zorglub@via.ecp.fr>
  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., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
  24.  *****************************************************************************/
  25. /*****************************************************************************
  26.  * Preamble
  27.  *****************************************************************************/
  28. #include <stdlib.h>                                      /* malloc(), free() */
  29. #include <vlc/vlc.h>
  30. #include <vlc/input.h>
  31. #include <vlc_playlist.h>
  32. /*****************************************************************************
  33.  * Constants and structures
  34.  *****************************************************************************/
  35. #define MAX_LINE 8192
  36. #define TYPE_UNKNOWN 0
  37. #define TYPE_M3U 1
  38. #define TYPE_ASX 2
  39. #define TYPE_HTML 3
  40. #define TYPE_PLS 4
  41. #define TYPE_B4S 5
  42. #define TYPE_WMP 6
  43. #define TYPE_RTSP 7
  44. struct demux_sys_t
  45. {
  46.     int i_type;                                   /* playlist type (m3u/asx) */
  47. };
  48. /*****************************************************************************
  49.  * Local prototypes
  50.  *****************************************************************************/
  51. static int  Activate  ( vlc_object_t * );
  52. static void Deactivate( vlc_object_t * );
  53. static int  Demux     ( demux_t * );
  54. static int  Control   ( demux_t *, int, va_list );
  55. /*****************************************************************************
  56.  * Module descriptor
  57.  *****************************************************************************/
  58. vlc_module_begin();
  59.     set_description( _("Playlist metademux") );
  60.     set_capability( "demux2", 10 );
  61.     set_callbacks( Activate, Deactivate );
  62.     add_shortcut( "m3u" );
  63.     add_shortcut( "asx" );
  64.     add_shortcut( "html" );
  65.     add_shortcut( "pls" );
  66.     add_shortcut( "b4s" );
  67. vlc_module_end();
  68. /*****************************************************************************
  69.  * Activate: initializes m3u demux structures
  70.  *****************************************************************************/
  71. static int Activate( vlc_object_t * p_this )
  72. {
  73.     demux_t *p_demux = (demux_t *)p_this;
  74.     char    *psz_ext;
  75.     int     i_type  = TYPE_UNKNOWN;
  76.     int     i_type2 = TYPE_UNKNOWN;
  77.     p_demux->pf_control = Control;
  78.     p_demux->pf_demux = Demux;
  79.     /* Check for m3u/asx file extension or if the demux has been forced */
  80.     psz_ext = strrchr ( p_demux->psz_path, '.' );
  81.     if( ( psz_ext && !strcasecmp( psz_ext, ".m3u") ) ||
  82.         /* a .ram file can contain a single rtsp link */
  83.         ( psz_ext && !strcasecmp( psz_ext, ".ram") ) ||
  84.         ( p_demux->psz_demux && !strcmp(p_demux->psz_demux, "m3u") ) )
  85.     {
  86.         i_type = TYPE_M3U;
  87.     }
  88.     else if( ( psz_ext && !strcasecmp( psz_ext, ".asx") ) ||
  89.              ( p_demux->psz_demux && !strcmp(p_demux->psz_demux, "asx") ) )
  90.     {
  91.         i_type = TYPE_ASX;
  92.     }
  93.     else if( ( psz_ext && !strcasecmp( psz_ext, ".html") ) ||
  94.              ( p_demux->psz_demux && !strcmp(p_demux->psz_demux, "html") ) )
  95.     {
  96.         i_type = TYPE_HTML;
  97.     }
  98.     else if( ( psz_ext && !strcasecmp( psz_ext, ".pls") ) ||
  99.              ( p_demux->psz_demux && !strcmp(p_demux->psz_demux, "pls") ) )
  100.     {
  101.         i_type = TYPE_PLS;
  102.     }
  103.     else if( ( psz_ext && !strcasecmp( psz_ext, ".b4s") ) ||
  104.              ( p_demux->psz_demux && !strcmp(p_demux->psz_demux, "b4s") ) )
  105.     {
  106.         i_type = TYPE_B4S;
  107.     }
  108.     /* we had no luck looking at the file extention, so we have a look
  109.      * at the content. This is useful for .asp, .php and similar files
  110.      * that are actually html. Also useful for some asx files that have
  111.      * another extension */
  112.     /* XXX we double check for file != m3u as some asx ... are just m3u file */
  113.     if( i_type != TYPE_M3U )
  114.     {
  115.         uint8_t *p_peek;
  116.         int i_size = stream_Peek( p_demux->s, &p_peek, MAX_LINE );
  117.         i_size -= sizeof("[Reference]") - 1;
  118.         if( i_size > 0 )
  119.         {
  120.             while( i_size &&
  121.                    strncasecmp(p_peek, "[playlist]", sizeof("[playlist]") - 1)
  122.                    && strncasecmp( p_peek, "[Reference]", sizeof("[Reference]") - 1 )
  123.                    && strncasecmp( p_peek, "<html>", sizeof("<html>") - 1 )
  124.                    && strncasecmp( p_peek, "<asx", sizeof("<asx") - 1 )
  125.                    && strncasecmp( p_peek, "rtsptext", sizeof("rtsptext") - 1 )
  126.                    && strncasecmp( p_peek, "<?xml", sizeof("<?xml") -1 ) )
  127.             {
  128.                 p_peek++;
  129.                 i_size--;
  130.             }
  131.             if( !i_size )
  132.             {
  133.                 ;
  134.             }
  135.             else if( !strncasecmp( p_peek, "[playlist]", sizeof("[playlist]") -1 ) )
  136.             {
  137.                 i_type2 = TYPE_PLS;
  138.             }
  139.             else if( !strncasecmp( p_peek, "[Reference]", sizeof("[Reference]") -1 ) )
  140.             {
  141.                 i_type2 = TYPE_WMP;
  142.             }
  143.             else if( !strncasecmp( p_peek, "<html>", sizeof("<html>") -1 ) )
  144.             {
  145.                 i_type2 = TYPE_HTML;
  146.             }
  147.             else if( !strncasecmp( p_peek, "<asx", sizeof("<asx") -1 ) )
  148.             {
  149.                 i_type2 = TYPE_ASX;
  150.             }
  151.             else if( !strncasecmp( p_peek, "rtsptext", sizeof("rtsptext") -1 ) )
  152.             {
  153.                 i_type2 = TYPE_RTSP;
  154.             }
  155. #if 0
  156.             else if( !strncasecmp( p_peek, "<?xml", sizeof("<?xml") -1 ) )
  157.             {
  158.                 i_type2 = TYPE_B4S;
  159.             }
  160. #endif
  161.         }
  162.     }
  163.     if( i_type == TYPE_UNKNOWN && i_type2 == TYPE_UNKNOWN)
  164.     {
  165.         return VLC_EGENERIC;
  166.     }
  167.     if( i_type  != TYPE_UNKNOWN && i_type2 == TYPE_UNKNOWN )
  168.     {
  169.         i_type = TYPE_M3U;
  170.     }
  171.     else
  172.     {
  173.         i_type = i_type2;
  174.     }
  175.     /* Allocate p_m3u */
  176.     p_demux->p_sys = malloc( sizeof( demux_sys_t ) );
  177.     p_demux->p_sys->i_type = i_type;
  178.     msg_Dbg( p_this, "Playlist type: %d - %d", i_type, i_type2 );
  179.     return VLC_SUCCESS;
  180. }
  181. /*****************************************************************************
  182.  * Deactivate: frees unused data
  183.  *****************************************************************************/
  184. static void Deactivate( vlc_object_t *p_this )
  185. {
  186.     demux_t *p_demux = (demux_t *)p_this;
  187.     free( p_demux->p_sys );
  188. }
  189. /*****************************************************************************
  190.  * XMLSpecialChars: Handle the special chars in a XML file.
  191.  * ***************************************************************************/
  192. static void XMLSpecialChars ( char *str )
  193. {
  194.     char *src = str;
  195.     char *dst = str;
  196.     while( *src )
  197.     {
  198.         if( *src == '&' )
  199.         {
  200.             if( !strncasecmp( src, "&#xe0;", 6 ) ) *dst++ = '