]> git.sesse.net Git - vlc/blob - modules/demux/playlist/pls.c
Merge back branch 0.8.6-playlist-vlm to trunk.
[vlc] / modules / demux / playlist / pls.c
1 /*****************************************************************************
2  * pls.c : PLS playlist format import
3  *****************************************************************************
4  * Copyright (C) 2004 the VideoLAN team
5  * $Id$
6  *
7  * Authors: ClĂ©ment Stenac <zorglub@videolan.org>
8  * Authors: Sigmund Augdal Helberg <dnumgis@videolan.org>
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., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
23  *****************************************************************************/
24
25 /*****************************************************************************
26  * Preamble
27  *****************************************************************************/
28 #include <stdlib.h>                                      /* malloc(), free() */
29
30 #include <vlc/vlc.h>
31 #include <vlc/input.h>
32 #include <vlc/intf.h>
33
34 #include <errno.h>                                                 /* ENOMEM */
35 #include "playlist.h"
36
37 struct demux_sys_t
38 {
39     char *psz_prefix;
40 };
41
42 /*****************************************************************************
43  * Local prototypes
44  *****************************************************************************/
45 static int Demux( demux_t *p_demux);
46 static int Control( demux_t *p_demux, int i_query, va_list args );
47
48 /*****************************************************************************
49  * Import_PLS: main import function
50  *****************************************************************************/
51 int E_(Import_PLS)( vlc_object_t *p_this )
52 {
53     demux_t *p_demux = (demux_t *)p_this;
54
55     uint8_t *p_peek;
56     char    *psz_ext;
57
58     if( stream_Peek( p_demux->s , &p_peek, 7 ) < 7 ) return VLC_EGENERIC;
59     psz_ext = strrchr ( p_demux->psz_path, '.' );
60
61     if( !strncasecmp( (char *)p_peek, "[playlist]", 10 ) )
62     {
63         ;
64     }
65     else if( ( psz_ext && !strcasecmp( psz_ext, ".pls") ) ||
66              ( p_demux->psz_demux && !strcmp(p_demux->psz_demux, "pls") ) )
67     {
68         ;
69     }
70     else return VLC_EGENERIC;
71
72     msg_Dbg( p_demux, "found valid PLS playlist file");
73
74     p_demux->pf_control = Control;
75     p_demux->pf_demux = Demux;
76     p_demux->p_sys = malloc( sizeof(demux_sys_t) );
77     if( p_demux->p_sys == NULL )
78     {
79         msg_Err( p_demux, "out of memory" );
80         return VLC_ENOMEM;
81     }
82     p_demux->p_sys->psz_prefix = E_(FindPrefix)( p_demux );
83
84     return VLC_SUCCESS;
85 }
86
87 /*****************************************************************************
88  * Deactivate: frees unused data
89  *****************************************************************************/
90 void E_(Close_PLS)( vlc_object_t *p_this )
91 {
92     demux_t *p_demux = (demux_t *)p_this;
93     if( p_demux->p_sys->psz_prefix )
94     {
95         free( p_demux->p_sys->psz_prefix );
96     }
97     free( p_demux->p_sys );
98 }
99
100 static int Demux( demux_t *p_demux )
101 {
102 #if 0
103     mtime_t        i_duration = -1;
104     char          *psz_name = NULL;
105     char          *psz_line;
106     char          *psz_mrl = NULL;
107     char          *psz_key;
108     char          *psz_value;
109     playlist_t    *p_playlist;
110     int            i_position;
111     int            i_item = -1;
112     int            i_new_item = 0;
113     int            i_key_length;
114     playlist_item_t *p_parent;
115     vlc_bool_t b_play;
116
117     p_playlist = (playlist_t *) vlc_object_find( p_demux, VLC_OBJECT_PLAYLIST,
118                                                  FIND_ANYWHERE );
119     if( !p_playlist )
120     {
121         msg_Err( p_demux, "can't find playlist" );
122         return -1;
123     }
124
125     b_play = E_(FindItem)( p_demux, p_playlist, &p_parent );
126     p_parent->input.i_type = ITEM_TYPE_PLAYLIST;
127
128     /* Change the item to a node */
129     if( p_parent->i_children == -1)
130     {
131         playlist_ItemToNode( p_playlist,p_parent );
132     }
133
134     while( ( psz_line = stream_ReadLine( p_demux->s ) ) )
135     {
136         if( !strncasecmp( psz_line, "[playlist]", sizeof("[playlist]")-1 ) )
137         {
138             free( psz_line );
139             continue;
140         }
141         psz_key = psz_line;
142         psz_value = strchr( psz_line, '=' );
143         if( psz_value )
144         {
145             *psz_value='\0';
146             psz_value++;
147         }
148         else
149         {
150             msg_Warn( p_demux, "invalid line in pls file" );
151             free( psz_line );
152             continue;
153         }
154         if( !strcasecmp( psz_key, "version" ) )
155         {
156             msg_Dbg( p_demux, "pls file version: %s", psz_value );
157             free( psz_line );
158             continue;
159         }
160         /* find the number part of of file1, title1 or length1 etc */
161         i_key_length = strlen( psz_key );
162         if( i_key_length >= 5 ) /* file1 type case */
163         {
164             i_new_item = atoi( psz_key + 4 );
165             if( i_new_item == 0 && i_key_length >= 6 ) /* title1 type case */
166             {
167                 i_new_item = atoi( psz_key + 5 );
168                 if( i_new_item == 0 && i_key_length >= 7 ) /* length1 type case */
169                 {
170                     i_new_item = atoi( psz_key + 6 );
171                 }
172             }
173         }
174         if( i_new_item == 0 )
175         {
176             msg_Warn( p_demux, "couldn't find number of items" );
177             free( psz_line );
178             continue;
179         }
180         if( i_item == -1 )
181         {
182             i_item = i_new_item;
183         }
184         /* we found a new item, insert the previous */
185         if( i_item != i_new_item )
186         {
187             if( psz_mrl )
188             {
189                 playlist_item_t *p_item = playlist_ItemNew( p_playlist, psz_mrl,
190                                                             psz_name );
191
192                 playlist_NodeAddItem( p_playlist,p_item,
193                                       p_parent->pp_parents[0]->i_view,
194                                       p_parent,
195                                       PLAYLIST_APPEND, PLAYLIST_END );
196
197                 playlist_CopyParents( p_parent, p_item );
198                 if( i_duration != -1 )
199                 {
200                     //playlist_SetDuration( p_playlist, i_position, i_duration );
201                 }
202                 i_position++;
203                 free( psz_mrl );
204                 psz_mrl = NULL;
205
206                 vlc_input_item_CopyOptions( &p_parent->input,
207                                             &p_item->input );
208             }
209             else
210             {
211                 msg_Warn( p_demux, "no file= part found for item %d", i_item );
212             }
213             if( psz_name )
214             {
215                 free( psz_name );
216                 psz_name = NULL;
217             }
218             i_duration = -1;
219             i_item = i_new_item;
220             i_new_item = 0;
221         }
222         if( !strncasecmp( psz_key, "file", sizeof("file") -1 ) )
223         {
224             psz_mrl = E_(ProcessMRL)( psz_value, p_demux->p_sys->psz_prefix );
225         }
226         else if( !strncasecmp( psz_key, "title", sizeof("title") -1 ) )
227         {
228             psz_name = strdup( psz_value );
229         }
230         else if( !strncasecmp( psz_key, "length", sizeof("length") -1 ) )
231         {
232             i_duration = atoi( psz_value );
233             if( i_duration != -1 )
234             {
235                 i_duration *= 1000000;
236             }
237         }
238         else
239         {
240             msg_Warn( p_demux, "unknown key found in pls file: %s", psz_key );
241         }
242         free( psz_line );
243     }
244     /* Add last object */
245     if( psz_mrl )
246     {
247         playlist_item_t *p_item = playlist_ItemNew( p_playlist, psz_mrl,
248                                                     psz_name );
249
250         playlist_NodeAddItem( p_playlist,p_item,
251                               p_parent->pp_parents[0]->i_view,
252                               p_parent,
253                               PLAYLIST_APPEND, PLAYLIST_END );
254
255         playlist_CopyParents( p_parent, p_item );
256         if( i_duration != -1 )
257         {
258             //playlist_SetDuration( p_playlist, i_position, i_duration );
259         }
260         free( psz_mrl );
261         psz_mrl = NULL;
262
263         vlc_input_item_CopyOptions( &p_parent->input,
264                                     &p_item->input );
265     }
266     else
267     {
268         msg_Warn( p_demux, "no file= part found for item %d", i_item );
269     }
270     if( psz_name )
271     {
272         free( psz_name );
273         psz_name = NULL;
274     }
275
276     if( b_play && p_playlist->status.p_item &&
277         p_playlist->status.p_item->i_children > 0 )
278     {
279         playlist_Control( p_playlist, PLAYLIST_VIEWPLAY,
280                           p_playlist->status.i_view,
281                           p_playlist->status.p_item,
282                           p_playlist->status.p_item->pp_children[0] );
283     }
284     vlc_object_release( p_playlist );
285     return VLC_SUCCESS;
286 #endif
287 }
288
289 static int Control( demux_t *p_demux, int i_query, va_list args )
290 {
291     return VLC_EGENERIC;
292 }