fix filename self-references
[vlc.git] / bindings / mediacontrol / mediacontrol_core.c
1 /*****************************************************************************
2  * mediacontrol_core.c: Core functions : init, playlist, stream management
3  *****************************************************************************
4  * Copyright (C) 2005 the VideoLAN team
5  * $Id$
6  *
7  * Authors: Olivier Aubert <olivier.aubert@liris.univ-lyon1.fr>
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22  *****************************************************************************/
23
24 #ifdef HAVE_CONFIG_H
25 # include "config.h"
26 #endif
27
28 #include "mediacontrol_internal.h"
29 #include <vlc/mediacontrol.h>
30
31 #include <vlc/libvlc.h>
32 #include <vlc_common.h>
33 #include <vlc_interface.h>
34 #include <vlc_playlist.h>
35
36 #include <vlc_vout.h>
37 #include <vlc_aout.h>
38 #include <vlc_input.h>
39 #include <vlc_osd.h>
40
41 #include <stdlib.h>                                      /* malloc(), free() */
42 #include <string.h>
43
44 #include <stdio.h>
45
46 #ifdef HAVE_UNISTD_H
47 #    include <unistd.h>
48 #endif
49 #include <sys/types.h>
50
51 mediacontrol_Instance* mediacontrol_new( int argc, char** argv, mediacontrol_Exception *exception )
52 {
53     mediacontrol_Instance* retval;
54     mediacontrol_exception_init( exception );
55
56     retval = ( mediacontrol_Instance* )malloc( sizeof( mediacontrol_Instance ) );
57     if( !retval )
58         RAISE_NULL( mediacontrol_InternalException, "Out of memory" );
59
60     retval->p_instance = libvlc_new( argc, (const char**)argv );
61     if( !retval->p_instance )
62         RAISE_NULL( mediacontrol_InternalException, "Out of memory" );
63     retval->p_media_player = libvlc_media_player_new( retval->p_instance );
64     if( !retval->p_media_player )
65         RAISE_NULL( mediacontrol_InternalException, "Out of memory" );
66     return retval;
67 }
68
69 void
70 mediacontrol_exit( mediacontrol_Instance *self )
71 {
72     libvlc_release( self->p_instance );
73 }
74
75 libvlc_instance_t*
76 mediacontrol_get_libvlc_instance( mediacontrol_Instance *self )
77 {
78     return self->p_instance;
79 }
80
81 libvlc_media_player_t*
82 mediacontrol_get_media_player( mediacontrol_Instance *self )
83 {
84     return self->p_media_player;
85 }
86
87 mediacontrol_Instance *
88 mediacontrol_new_from_instance( libvlc_instance_t* p_instance,
89                 mediacontrol_Exception *exception )
90 {
91     mediacontrol_Instance* retval;
92
93     retval = ( mediacontrol_Instance* )malloc( sizeof( mediacontrol_Instance ) );
94     if( ! retval )
95     {
96         RAISE_NULL( mediacontrol_InternalException, "Out of memory" );
97     }
98     retval->p_instance = p_instance;
99     retval->p_media_player = libvlc_media_player_new( retval->p_instance );
100     if( ! retval->p_media_player )
101          RAISE_NULL( mediacontrol_InternalException, "Out of memory" );
102     return retval;
103 }
104
105 /**************************************************************************
106  * Playback management
107  **************************************************************************/
108 mediacontrol_Position*
109 mediacontrol_get_media_position( mediacontrol_Instance *self,
110                                  const mediacontrol_PositionOrigin an_origin,
111                                  const mediacontrol_PositionKey a_key,
112                                  mediacontrol_Exception *exception )
113 {
114     mediacontrol_Position* retval = NULL;
115     int64_t pos;
116
117     mediacontrol_exception_init( exception );
118
119     retval = ( mediacontrol_Position* )malloc( sizeof( mediacontrol_Position ) );
120     retval->origin = an_origin;
121     retval->key = a_key;
122
123     if(  an_origin != mediacontrol_AbsolutePosition )
124     {
125         free( retval );
126         /* Relative or ModuloPosition make no sense */
127         RAISE_NULL( mediacontrol_PositionOriginNotSupported,
128                     "Only absolute position is valid." );
129     }
130
131     /* We are asked for an AbsolutePosition. */
132     pos = libvlc_media_player_get_time( self->p_media_player );
133
134     if( a_key == mediacontrol_MediaTime )
135     {
136         retval->value = pos;
137     }
138     else
139     {
140         retval->value = private_mediacontrol_unit_convert( self->p_media_player,
141                                                            mediacontrol_MediaTime,
142                                                            a_key,
143                                                            pos );
144     }
145     return retval;
146 }
147
148 /* Sets the media position */
149 void
150 mediacontrol_set_media_position( mediacontrol_Instance *self,
151                                  const mediacontrol_Position * a_position,
152                                  mediacontrol_Exception *exception )
153 {
154     int64_t i_pos;
155
156     mediacontrol_exception_init( exception );
157
158     i_pos = private_mediacontrol_position2microsecond( self->p_media_player, a_position );
159     libvlc_media_player_set_time( self->p_media_player, i_pos / 1000 );
160 }
161
162 /* Starts playing a stream */
163 /*
164  * Known issues: since moving in the playlist using playlist_Next
165  * or playlist_Prev implies starting to play items, the a_position
166  * argument will be only honored for the 1st item in the list.
167  *
168  * XXX:FIXME split moving in the playlist and playing items two
169  * different actions or make playlist_<Next|Prev> accept a time
170  * value to start to play from.
171  */
172 void
173 mediacontrol_start( mediacontrol_Instance *self,
174                     const mediacontrol_Position * a_position,
175                     mediacontrol_Exception *exception )
176 {
177     libvlc_media_t * p_media;
178     char * psz_name;
179     libvlc_exception_t ex;
180
181     mediacontrol_exception_init( exception );
182     libvlc_exception_init( &ex );
183
184     p_media = libvlc_media_player_get_media( self->p_media_player );
185
186     if ( ! p_media )
187     {
188         /* No media was defined. */
189         RAISE( mediacontrol_PlaylistException, "No defined media." );
190     }
191     else
192     {
193         /* A media was defined. Get its mrl to reuse it, but reset the options
194            (because start-time may have been set on the previous invocation */
195         psz_name = libvlc_media_get_mrl( p_media );
196         HANDLE_LIBVLC_EXCEPTION_VOID( &ex );
197
198         /* Create a new media */
199         p_media = libvlc_media_new_location( self->p_instance, psz_name, &ex );
200         HANDLE_LIBVLC_EXCEPTION_VOID( &ex );
201
202         if( a_position->value )
203         {
204             char * psz_from;
205             libvlc_time_t i_from;
206
207             /* A start position was specified. Add it to media options */
208             psz_from = ( char * )malloc( 20 * sizeof( char ) );
209             i_from = private_mediacontrol_position2microsecond( self->p_media_player, a_position ) / 1000000;
210             snprintf( psz_from, 20, "start-time=%"PRId64, i_from );
211             libvlc_media_add_option( p_media, psz_from );
212             HANDLE_LIBVLC_EXCEPTION_VOID( &ex );
213         }
214
215         libvlc_media_player_set_media( self->p_media_player, p_media );
216
217         libvlc_media_player_play( self->p_media_player );
218     }
219 }
220
221 void
222 mediacontrol_pause( mediacontrol_Instance *self,
223                     mediacontrol_Exception *exception )
224 {
225     mediacontrol_exception_init( exception );
226     libvlc_media_player_pause( self->p_media_player );
227 }
228
229 void
230 mediacontrol_resume( mediacontrol_Instance *self,
231                      mediacontrol_Exception *exception )
232 {
233     mediacontrol_exception_init( exception );
234     libvlc_media_player_pause( self->p_media_player );
235 }
236
237 void
238 mediacontrol_stop( mediacontrol_Instance *self,
239                    mediacontrol_Exception *exception )
240 {
241     mediacontrol_exception_init( exception );
242     libvlc_media_player_stop( self->p_media_player );
243 }
244
245 /**************************************************************************
246  * File management
247  **************************************************************************/
248
249 void
250 mediacontrol_set_mrl( mediacontrol_Instance *self,
251                       const char * psz_file,
252                       mediacontrol_Exception *exception )
253 {
254     libvlc_media_t * p_media;
255     libvlc_exception_t ex;
256
257     mediacontrol_exception_init( exception );
258     libvlc_exception_init( &ex );
259
260     p_media = libvlc_media_new_location( self->p_instance, psz_file, &ex );
261     HANDLE_LIBVLC_EXCEPTION_VOID( &ex );
262
263     libvlc_media_player_set_media( self->p_media_player, p_media );
264 }
265
266 char *
267 mediacontrol_get_mrl( mediacontrol_Instance *self,
268                       mediacontrol_Exception *exception )
269 {
270     libvlc_media_t * p_media;
271     libvlc_exception_t ex;
272
273     mediacontrol_exception_init( exception );
274     libvlc_exception_init( &ex );
275
276     p_media = libvlc_media_player_get_media( self->p_media_player );
277
278     if ( ! p_media )
279     {
280         return strdup( "" );
281     }
282     else
283     {
284         char * psz_mrl;
285
286         psz_mrl = libvlc_media_get_mrl( p_media );
287         HANDLE_LIBVLC_EXCEPTION_NULL( &ex );
288         return psz_mrl;
289     }
290 }
291
292 /***************************************************************************
293  * Status feedback
294  ***************************************************************************/
295
296 mediacontrol_StreamInformation *
297 mediacontrol_get_stream_information( mediacontrol_Instance *self,
298                                      mediacontrol_PositionKey a_key,
299                                      mediacontrol_Exception *exception )
300 {
301     (void)a_key;
302     mediacontrol_StreamInformation *retval = NULL;
303     libvlc_media_t * p_media;
304     libvlc_exception_t ex;
305
306     libvlc_exception_init( &ex );
307
308     retval = ( mediacontrol_StreamInformation* )
309                             malloc( sizeof( mediacontrol_StreamInformation ) );
310     if( ! retval )
311     {
312         RAISE( mediacontrol_InternalException, "Out of memory" );
313         return NULL;
314     }
315
316     p_media = libvlc_media_player_get_media( self->p_media_player );
317     if( ! p_media )
318     {
319         /* No p_media defined */
320         retval->streamstatus = mediacontrol_UndefinedStatus;
321         retval->url          = strdup( "" );
322         retval->position     = 0;
323         retval->length       = 0;
324     }
325     else
326     {
327         libvlc_state_t state;
328
329         state = libvlc_media_player_get_state( self->p_media_player );
330         switch( state )
331         {
332         case libvlc_NothingSpecial:
333             retval->streamstatus = mediacontrol_UndefinedStatus;
334             break;
335         case libvlc_Opening :
336             retval->streamstatus = mediacontrol_InitStatus;
337             break;
338         case libvlc_Buffering:
339             retval->streamstatus = mediacontrol_BufferingStatus;
340             break;
341         case libvlc_Playing:
342             retval->streamstatus = mediacontrol_PlayingStatus;
343             break;
344         case libvlc_Paused:
345             retval->streamstatus = mediacontrol_PauseStatus;
346             break;
347         case libvlc_Stopped:
348             retval->streamstatus = mediacontrol_StopStatus;
349             break;
350         case libvlc_Ended:
351             retval->streamstatus = mediacontrol_EndStatus;
352             break;
353         case libvlc_Error:
354             retval->streamstatus = mediacontrol_ErrorStatus;
355             break;
356         default :
357             retval->streamstatus = mediacontrol_UndefinedStatus;
358             break;
359         }
360
361         retval->url = libvlc_media_get_mrl( p_media );
362
363         retval->position = libvlc_media_player_get_time( self->p_media_player );
364         retval->length = libvlc_media_player_get_length( self->p_media_player );
365     }
366     return retval;
367 }