1 /*****************************************************************************
2 * vlm.c: libvlc new API VLM handling functions
3 *****************************************************************************
4 * Copyright (C) 2005 the VideoLAN team
7 * Authors: Clément Stenac <zorglub@videolan.org>
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.
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.
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 *****************************************************************************/
24 #include "libvlc_internal.h"
26 #include <vlc/libvlc.h>
28 #include <vlc_input.h>
32 /* local function to be used in libvlc_vlm_show_media only */
33 static char* recurse_answer( char* psz_prefix, vlm_message_t *p_answer ) {
34 char* psz_childprefix;
35 char* psz_response="";
38 vlm_message_t *aw_child, **paw_child;
40 asprintf( &psz_childprefix, "%s%s.", psz_prefix, p_answer->psz_name );
42 if ( p_answer->i_child )
44 paw_child = p_answer->child;
45 aw_child = *( paw_child );
46 for( i = 0; i < p_answer->i_child; i++ )
48 asprintf( &response_tmp, "%s%s%s:%s\n",
49 psz_response, psz_prefix, aw_child->psz_name,
50 aw_child->psz_value );
52 psz_response = response_tmp;
53 if ( aw_child->i_child )
55 asprintf(&response_tmp, "%s%s", psz_response,
56 recurse_answer(psz_childprefix, aw_child));
58 psz_response = response_tmp;
61 aw_child = *( paw_child );
64 free( psz_childprefix );
68 char* libvlc_vlm_show_media( libvlc_instance_t *p_instance, char *psz_name,
69 libvlc_exception_t *p_exception )
72 vlm_message_t *answer;
76 asprintf( &psz_message, "show %s", psz_name );
77 asprintf( &psz_response, "", psz_name );
78 vlm_ExecuteCommand( p_instance->p_vlm, psz_message, &answer );
79 if( answer->psz_value )
81 libvlc_exception_raise( p_exception, "Unable to call show %s: %s",
82 psz_name, answer->psz_value );
88 psz_response = recurse_answer( "", answer );
92 return(psz_response );
96 char* libvlc_vlm_show_media( libvlc_instance_t *p_instance,
98 libvlc_exception_t *p_exception )
101 /* FIXME is it needed ? */
102 libvlc_exception_raise( p_exception, "Unable to call show %s", psz_name );
108 static int libvlc_vlm_init( libvlc_instance_t *p_instance,
109 libvlc_exception_t *p_exception )
111 if( !p_instance->p_vlm )
112 p_instance->p_vlm = vlm_New( p_instance->p_libvlc_int );
114 if( !p_instance->p_vlm )
116 libvlc_exception_raise( p_exception,
117 "Unable to create VLM." );
122 #define VLM_RET(p,ret) do { \
123 if( libvlc_vlm_init( p_instance, p_exception ) ) return ret;\
124 (p) = p_instance->p_vlm; \
126 #define VLM(p) VLM_RET(p,)
128 static vlm_media_instance_t *
129 libvlc_vlm_get_media_instance( libvlc_instance_t *p_instance,
130 const char *psz_name, int i_minstance_idx,
131 libvlc_exception_t *p_exception )
134 vlm_media_instance_t **pp_minstance;
135 vlm_media_instance_t *p_minstance;
139 VLM_RET(p_vlm, NULL);
141 if( vlm_Control( p_vlm, VLM_GET_MEDIA_ID, psz_name, &id ) ||
142 vlm_Control( p_vlm, VLM_GET_MEDIA_INSTANCES, id, &pp_minstance,
145 libvlc_exception_raise( p_exception, "Unable to get %s instances",
150 if( i_minstance_idx >= 0 && i_minstance_idx < i_minstance )
152 p_minstance = pp_minstance[i_minstance_idx];
153 TAB_REMOVE( i_minstance, pp_minstance, p_minstance );
155 while( i_minstance > 0 )
156 vlm_media_instance_Delete( pp_minstance[--i_minstance] );
157 TAB_CLEAN( i_minstance, pp_minstance );
162 void libvlc_vlm_release( libvlc_instance_t *p_instance,
163 libvlc_exception_t *p_exception)
172 void libvlc_vlm_add_broadcast( libvlc_instance_t *p_instance,
173 const char *psz_name,
174 const char *psz_input,
175 const char *psz_output, int i_options,
176 const char * const *ppsz_options,
177 int b_enabled, int b_loop,
178 libvlc_exception_t *p_exception )
186 vlm_media_Init( &m );
187 m.psz_name = strdup( psz_name );
188 m.b_enabled = b_enabled;
190 m.broadcast.b_loop = b_loop;
192 TAB_APPEND( m.i_input, m.ppsz_input, strdup(psz_input) );
194 m.psz_output = strdup( psz_output );
195 for( n = 0; n < i_options; n++ )
196 TAB_APPEND( m.i_option, m.ppsz_option, strdup(ppsz_options[n]) );
198 n = vlm_Control( p_vlm, VLM_ADD_MEDIA, &m, NULL );
199 vlm_media_Clean( &m );
201 libvlc_exception_raise( p_exception, "Media %s creation failed",
205 void libvlc_vlm_add_vod( libvlc_instance_t *p_instance, const char *psz_name,
206 const char *psz_input, int i_options,
207 const char * const *ppsz_options, int b_enabled,
208 const char *psz_mux, libvlc_exception_t *p_exception )
216 vlm_media_Init( &m );
217 m.psz_name = strdup( psz_name );
218 m.b_enabled = b_enabled;
220 m.vod.psz_mux = psz_mux ? strdup( psz_mux ) : NULL;
222 TAB_APPEND( m.i_input, m.ppsz_input, strdup(psz_input) );
223 for( n = 0; n < i_options; n++ )
224 TAB_APPEND( m.i_option, m.ppsz_option, strdup(ppsz_options[n]) );
226 n = vlm_Control( p_vlm, VLM_ADD_MEDIA, &m, NULL );
227 vlm_media_Clean( &m );
229 libvlc_exception_raise( p_exception, "Media %s creation failed",
233 void libvlc_vlm_del_media( libvlc_instance_t *p_instance, const char *psz_name,
234 libvlc_exception_t *p_exception )
241 if( vlm_Control( p_vlm, VLM_GET_MEDIA_ID, psz_name, &id ) ||
242 vlm_Control( p_vlm, VLM_DEL_MEDIA, id ) )
244 libvlc_exception_raise( p_exception, "Unable to delete %s", psz_name );
248 #define VLM_CHANGE(psz_error, code ) do { \
249 vlm_media_t *p_media; \
253 if( vlm_Control( p_vlm, VLM_GET_MEDIA_ID, psz_name, &id ) || \
254 vlm_Control( p_vlm, VLM_GET_MEDIA, id, &p_media ) ) { \
255 libvlc_exception_raise( p_exception, psz_error, psz_name ); \
258 if( !p_media ) goto error; \
262 if( vlm_Control( p_vlm, VLM_CHANGE_MEDIA, p_media ) ) { \
263 vlm_media_Delete( p_media ); \
266 vlm_media_Delete( p_media ); \
269 libvlc_exception_raise( p_exception, psz_error, psz_name );\
272 void libvlc_vlm_set_enabled( libvlc_instance_t *p_instance,
273 const char *psz_name, int b_enabled,
274 libvlc_exception_t *p_exception )
276 #define VLM_CHANGE_CODE { p_media->b_enabled = b_enabled; }
277 VLM_CHANGE( "Unable to delete %s", VLM_CHANGE_CODE );
278 #undef VLM_CHANGE_CODE
281 void libvlc_vlm_set_loop( libvlc_instance_t *p_instance, const char *psz_name,
282 int b_loop, libvlc_exception_t *p_exception )
284 #define VLM_CHANGE_CODE { p_media->broadcast.b_loop = b_loop; }
285 VLM_CHANGE( "Unable to change %s loop property", VLM_CHANGE_CODE );
286 #undef VLM_CHANGE_CODE
289 void libvlc_vlm_set_mux( libvlc_instance_t *p_instance, const char *psz_name,
290 const char *psz_mux, libvlc_exception_t *p_exception )
292 #define VLM_CHANGE_CODE { if( p_media->b_vod ) { \
293 free( p_media->vod.psz_mux ); \
294 p_media->vod.psz_mux = psz_mux \
295 ? strdup( psz_mux ) : NULL; \
297 VLM_CHANGE( "Unable to change %s mux property", VLM_CHANGE_CODE );
298 #undef VLM_CHANGE_CODE
301 void libvlc_vlm_set_output( libvlc_instance_t *p_instance,
302 const char *psz_name, const char *psz_output,
303 libvlc_exception_t *p_exception )
305 #define VLM_CHANGE_CODE { free( p_media->psz_output ); \
306 p_media->psz_output = strdup( psz_output ); }
307 VLM_CHANGE( "Unable to change %s output property", VLM_CHANGE_CODE );
308 #undef VLM_CHANGE_CODE
311 void libvlc_vlm_set_input( libvlc_instance_t *p_instance,
312 const char *psz_name, const char *psz_input,
313 libvlc_exception_t *p_exception )
315 #define VLM_CHANGE_CODE { while( p_media->i_input > 0 ) \
316 free( p_media->ppsz_input[--p_media->i_input] );\
317 TAB_APPEND( p_media->i_input, p_media->ppsz_input, \
318 strdup(psz_input) ); }
319 VLM_CHANGE( "Unable to change %s input property", VLM_CHANGE_CODE );
320 #undef VLM_CHANGE_CODE
323 void libvlc_vlm_add_input( libvlc_instance_t *p_instance,
324 const char *psz_name, const char *psz_input,
325 libvlc_exception_t *p_exception )
327 #define VLM_CHANGE_CODE { TAB_APPEND( p_media->i_input, p_media->ppsz_input, \
328 strdup(psz_input) ); }
329 VLM_CHANGE( "Unable to change %s input property", VLM_CHANGE_CODE );
330 #undef VLM_CHANGE_CODE
333 void libvlc_vlm_change_media( libvlc_instance_t *p_instance,
334 const char *psz_name, const char *psz_input,
335 const char *psz_output, int i_options,
336 const char * const *ppsz_options, int b_enabled,
337 int b_loop, libvlc_exception_t *p_exception )
339 #define VLM_CHANGE_CODE { int n; \
340 p_media->b_enabled = b_enabled; \
341 p_media->broadcast.b_loop = b_loop; \
342 while( p_media->i_input > 0 ) \
343 free( p_media->ppsz_input[--p_media->i_input] ); \
345 TAB_APPEND( p_media->i_input, p_media->ppsz_input, strdup(psz_input) ); \
346 free( p_media->psz_output ); \
347 p_media->psz_output = psz_output ? strdup( psz_output ) : NULL; \
348 while( p_media->i_option > 0 ) \
349 free( p_media->ppsz_option[--p_media->i_option] ); \
350 for( n = 0; n < i_options; n++ ) \
351 TAB_APPEND( p_media->i_option, p_media->ppsz_option, \
352 strdup(ppsz_options[n]) ); \
354 VLM_CHANGE( "Unable to change %s properties", VLM_CHANGE_CODE );
355 #undef VLM_CHANGE_CODE
358 void libvlc_vlm_play_media( libvlc_instance_t *p_instance,
359 const char *psz_name,
360 libvlc_exception_t *p_exception )
367 if( vlm_Control( p_vlm, VLM_GET_MEDIA_ID, psz_name, &id ) ||
368 vlm_Control( p_vlm, VLM_START_MEDIA_BROADCAST_INSTANCE, id, NULL, 0 ) )
370 libvlc_exception_raise( p_exception, "Unable to play %s", psz_name );
374 void libvlc_vlm_stop_media( libvlc_instance_t *p_instance,
375 const char *psz_name,
376 libvlc_exception_t *p_exception )
383 if( vlm_Control( p_vlm, VLM_GET_MEDIA_ID, psz_name, &id ) ||
384 vlm_Control( p_vlm, VLM_STOP_MEDIA_INSTANCE, id, NULL ) )
386 libvlc_exception_raise( p_exception, "Unable to stop %s", psz_name );
390 void libvlc_vlm_pause_media( libvlc_instance_t *p_instance,
391 const char *psz_name,
392 libvlc_exception_t *p_exception )
399 if( vlm_Control( p_vlm, VLM_GET_MEDIA_ID, psz_name, &id ) ||
400 vlm_Control( p_vlm, VLM_PAUSE_MEDIA_INSTANCE, id, NULL ) )
402 libvlc_exception_raise( p_exception, "Unable to pause %s", psz_name );
406 void libvlc_vlm_seek_media( libvlc_instance_t *p_instance,
407 const char *psz_name, float f_percentage,
408 libvlc_exception_t *p_exception )
415 if( vlm_Control( p_vlm, VLM_GET_MEDIA_ID, psz_name, &id ) ||
416 vlm_Control( p_vlm, VLM_SET_MEDIA_INSTANCE_POSITION, id, NULL,
418 libvlc_exception_raise( p_exception, "Unable to seek %s to %f",
419 psz_name, f_percentage );
422 float libvlc_vlm_get_media_instance_position( libvlc_instance_t *p_instance,
423 const char *psz_name,
425 libvlc_exception_t *p_exception )
427 vlm_media_instance_t *p_mi;
430 p_mi = libvlc_vlm_get_media_instance( p_instance, psz_name,
431 i_instance, p_exception );
434 result = p_mi->d_position;
435 vlm_media_instance_Delete( p_mi );
440 int libvlc_vlm_get_media_instance_time( libvlc_instance_t *p_instance,
441 const char *psz_name, int i_instance,
442 libvlc_exception_t *p_exception )
444 vlm_media_instance_t *p_mi;
447 p_mi = libvlc_vlm_get_media_instance( p_instance, psz_name,
448 i_instance, p_exception );
451 result = p_mi->i_time;
452 vlm_media_instance_Delete( p_mi );
457 int libvlc_vlm_get_media_instance_length( libvlc_instance_t *p_instance,
458 const char *psz_name,
460 libvlc_exception_t *p_exception )
462 vlm_media_instance_t *p_mi;
465 p_mi = libvlc_vlm_get_media_instance( p_instance, psz_name,
466 i_instance, p_exception );
469 result = p_mi->i_length;
470 vlm_media_instance_Delete( p_mi );
475 int libvlc_vlm_get_media_instance_rate( libvlc_instance_t *p_instance,
476 const char *psz_name, int i_instance,
477 libvlc_exception_t *p_exception )
479 vlm_media_instance_t *p_mi;
482 p_mi = libvlc_vlm_get_media_instance( p_instance, psz_name,
483 i_instance, p_exception );
486 result = p_mi->i_rate;
487 vlm_media_instance_Delete( p_mi );
492 int libvlc_vlm_get_media_instance_title( libvlc_instance_t *p_instance,
493 const char *psz_name, int i_instance,
494 libvlc_exception_t *p_exception )
496 vlm_media_instance_t *p_mi;
498 p_mi = libvlc_vlm_get_media_instance( p_instance, psz_name,
499 i_instance, p_exception );
501 vlm_media_instance_Delete( p_mi );
502 return p_mi ? 0 : -1;
505 int libvlc_vlm_get_media_instance_chapter( libvlc_instance_t *p_instance,
506 const char *psz_name,
508 libvlc_exception_t *p_exception )
510 vlm_media_instance_t *p_mi;
512 p_mi = libvlc_vlm_get_media_instance( p_instance, psz_name,
513 i_instance, p_exception );
515 vlm_media_instance_Delete( p_mi );
516 return p_mi ? 0 : -1;
519 int libvlc_vlm_get_media_instance_seekable( libvlc_instance_t *p_instance,
520 const char *psz_name,
522 libvlc_exception_t *p_exception )
524 vlm_media_instance_t *p_mi;
526 p_mi = libvlc_vlm_get_media_instance( p_instance, psz_name,
527 i_instance, p_exception );
529 vlm_media_instance_Delete( p_mi );
530 return p_mi ? 0 : -1;