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

多媒体

开发平台:

MultiPlatform

  1. /*****************************************************************************
  2.  * m3u.c : M3U playlist format import
  3.  *****************************************************************************
  4.  * Copyright (C) 2004 VideoLAN
  5.  * $Id: m3u.c 8157 2004-07-09 15:15:07Z gbazin $
  6.  *
  7.  * Authors: Cl閙ent Stenac <zorglub@videolan.org>
  8.  * Authors: Sigmund Augdal <sigmunau@idi.ntnu.no>
  9.  *
  10.  * This program is free software; you can redistribute it and/or modify
  11.  * it under the terms of the GNU General Public License as published by
  12.  * the Free Software Foundation; either version 2 of the License, or
  13.  * (at your option) any later version.
  14.  *
  15.  * This program is distributed in the hope that it will be useful,
  16.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18.  * GNU General Public License for more details.
  19.  *
  20.  * You should have received a copy of the GNU General Public License
  21.  * along with this program; if not, write to the Free Software
  22.  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
  23.  *****************************************************************************/
  24. /*****************************************************************************
  25.  * Preamble
  26.  *****************************************************************************/
  27. #include <stdlib.h>                                      /* malloc(), free() */
  28. #include <vlc/vlc.h>
  29. #include <vlc/input.h>
  30. #include <vlc/intf.h>
  31. #include <errno.h>                                                 /* ENOMEM */
  32. #include "playlist.h"
  33. struct demux_sys_t
  34. {
  35.     char *psz_prefix;
  36. };
  37. /*****************************************************************************
  38.  * Local prototypes
  39.  *****************************************************************************/
  40. static int Demux( demux_t *p_demux);
  41. static int Control( demux_t *p_demux, int i_query, va_list args );
  42. /*****************************************************************************
  43.  * Import_M3U: main import function
  44.  *****************************************************************************/
  45. int Import_M3U( vlc_object_t *p_this )
  46. {
  47.     demux_t *p_demux = (demux_t *)p_this;
  48.     uint8_t *p_peek;
  49.     char    *psz_ext;
  50.     if( stream_Peek( p_demux->s , &p_peek, 7 ) < 7 )
  51.     {
  52.         return VLC_EGENERIC;
  53.     }
  54.     psz_ext = strrchr ( p_demux->psz_path, '.' );
  55.     if( !strncmp( p_peek, "#EXTM3U", 7 ) )
  56.     {
  57.         ;
  58.     }
  59.     else if( ( psz_ext && !strcasecmp( psz_ext, ".m3u") ) ||
  60.              ( psz_ext && !strcasecmp( psz_ext, ".ram") ) ||
  61.              /* A .ram file can contain a single rtsp link */
  62.              ( p_demux->psz_demux && !strcmp(p_demux->psz_demux, "m3u") ) )
  63.     {
  64.         ;
  65.     }
  66.     else
  67.     {
  68.         return VLC_EGENERIC;
  69.     }
  70.     msg_Dbg( p_demux, "found valid M3U playlist file");
  71.     p_demux->pf_control = Control;
  72.     p_demux->pf_demux = Demux;
  73.     p_demux->p_sys = malloc( sizeof(demux_sys_t) );
  74.     if( p_demux->p_sys == NULL )
  75.     {
  76.         msg_Err( p_demux, "Out of memory" );
  77.         return VLC_ENOMEM;
  78.     }
  79.     p_demux->p_sys->psz_prefix = FindPrefix( p_demux );
  80.     return VLC_SUCCESS;
  81. }
  82. /*****************************************************************************
  83.  * Deactivate: frees unused data
  84.  *****************************************************************************/
  85. void Close_M3U( vlc_object_t *p_this )
  86. {
  87.     demux_t *p_demux = (demux_t *)p_this;
  88.     if( p_demux->p_sys->psz_prefix ) free( p_demux->p_sys->psz_prefix );
  89.     free( p_demux->p_sys );
  90. }
  91. static int Demux( demux_t *p_demux )
  92. {
  93.     playlist_t *p_playlist;
  94.     char       *psz_line;
  95.     int        i_position;
  96.     char *psz_name = NULL;
  97.     mtime_t i_duration = -1;
  98.     char **ppsz_options = NULL;
  99.     int i_options = 0;
  100.     vlc_bool_t b_cleanup = VLC_FALSE;
  101.     p_playlist = (playlist_t *) vlc_object_find( p_demux, VLC_OBJECT_PLAYLIST,
  102.                                                  FIND_PARENT );
  103.     if( !p_playlist )
  104.     {
  105.         msg_Err( p_demux, "can't find playlist" );
  106.         return -1;
  107.     }
  108.     vlc_mutex_lock( &p_playlist->object_lock );
  109.     p_playlist->pp_items[p_playlist->i_index]->b_autodeletion = VLC_TRUE;
  110.     i_position = p_playlist->i_index + 1;
  111.     vlc_mutex_unlock( &p_playlist->object_lock );
  112.     psz_line = stream_ReadLine( p_demux->s );
  113.     while( psz_line )
  114.     {
  115.         char *psz_parse = psz_line;
  116.         /* Skip leading tabs and spaces */
  117.         while( *psz_parse == ' ' || *psz_parse == 't' ||
  118.                *psz_parse == 'n' || *psz_parse == 'r' ) psz_parse++;
  119.         if( *psz_parse == '#' )
  120.         {
  121.             /* Parse extra info */
  122.             /* Skip leading tabs and spaces */
  123.             while( *psz_parse == ' ' || *psz_parse == 't' || 
  124.                    *psz_parse == 'n' || *psz_parse == 'r' ||
  125.                    *psz_parse == '#' ) psz_parse++;
  126.             if( !*psz_parse ) goto error;
  127.             if( !strncasecmp( psz_parse, "EXTINF:", sizeof("EXTINF:") -1 ) )
  128.             {
  129.                 /* Extended info */
  130.                 char *psz_duration;
  131.                 psz_parse += sizeof("EXTINF:") - 1;
  132.                 while( *psz_parse == 't' || *psz_parse == ' ' ) psz_parse++;
  133.                 psz_duration = psz_parse;
  134.                 psz_parse = strchr( psz_parse, ',' );
  135.                 if( psz_parse )
  136.                 {
  137.                     *psz_parse = '';
  138.                     psz_parse++;
  139.                     psz_name = strdup( psz_parse );
  140.                     i_duration = atoi( psz_duration );
  141.                     if( i_duration != -1 ) i_duration *= 1000000;
  142.                 }
  143.             }
  144.             else if( !strncasecmp( psz_parse, "EXTVLCOPT:",
  145.                                    sizeof("EXTVLCOPT:") -1 ) )
  146.             {
  147.                 /* VLC Option */
  148.                 char *psz_option;
  149.                 psz_parse += sizeof("EXTVLCOPT:") -1;
  150.                 if( !*psz_parse ) goto error;
  151.                 psz_option = strdup( psz_parse );
  152.                 if( psz_option )
  153.                     INSERT_ELEM( ppsz_options, i_options, i_options,
  154.                                  psz_option );
  155.             }
  156.         }
  157.         else if( *psz_parse )
  158.         {
  159.             char *psz_mrl =
  160.                 ProcessMRL( psz_parse, p_demux->p_sys->psz_prefix );
  161.             b_cleanup = VLC_TRUE;
  162.             if( !psz_mrl ) goto error;
  163.             playlist_AddExt( p_playlist, psz_mrl, psz_name,
  164.                              PLAYLIST_INSERT, i_position, i_duration,
  165.                              (const char **)ppsz_options, i_options );
  166.             i_position++;
  167.             free( psz_mrl );
  168.         }
  169.  error:
  170.         /* Fetch another line */
  171.         free( psz_line );
  172.         psz_line = stream_ReadLine( p_demux->s );
  173.         if( !psz_line ) b_cleanup = VLC_TRUE;
  174.         if( b_cleanup )
  175.         {
  176.             /* Cleanup state */
  177.             while( i_options-- ) free( ppsz_options[i_options] );
  178.             if( ppsz_options ) free( ppsz_options );
  179.             ppsz_options = NULL; i_options = 0;
  180.             if( psz_name ) free( psz_name );
  181.             psz_name = NULL;
  182.             i_duration = -1;
  183.             b_cleanup = VLC_FALSE;
  184.         }
  185.     }
  186.     vlc_object_release( p_playlist );
  187.     return VLC_SUCCESS;
  188. }
  189. static int Control( demux_t *p_demux, int i_query, va_list args )
  190. {
  191.     return VLC_EGENERIC;
  192. }