1 /*****************************************************************************
2 * vlc_mediacontrol.c: vlc.MediaControl binding
3 *****************************************************************************
4 * Copyright (C) 2006 the VideoLAN team
7 * Authors: Olivier Aubert <oaubert at bat710.univ-lyon1.fr>
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 *****************************************************************************/
25 /*****************************************************************************
26 * VLC MediaControl object implementation
27 *****************************************************************************/
29 /* The MediaControl constructor takes either an existing vlc.Instance or a
32 MediaControl_new( PyTypeObject *type, PyObject *args, PyObject *kwds )
35 mediacontrol_Exception *exception = NULL;
36 PyObject* py_param = NULL;
37 char** ppsz_args = NULL;
38 libvlc_instance_t* p_instance = NULL;
39 Py_ssize_t i_size = 0;
41 self = PyObject_New( MediaControl, &MediaControl_Type );
43 if( PyArg_ParseTuple( args, "O", &py_param ) )
45 if( PyObject_TypeCheck( py_param, &vlcInstance_Type ) == 1 )
47 p_instance = ((vlcInstance*)py_param)->p_instance;
53 Py_INCREF( py_param );
54 if( ! PySequence_Check( py_param ) )
56 PyErr_SetString( PyExc_TypeError, "Parameter must be a vlc.Instance or a sequence of strings." );
57 Py_DECREF( py_param );
60 i_size = PySequence_Size( py_param );
61 ppsz_args = malloc( ( i_size + 1 ) * sizeof( char * ) );
64 PyErr_SetString( PyExc_MemoryError, "Out of memory" );
65 Py_DECREF( py_param );
69 for ( i_index = 0; i_index < i_size; i_index++ )
72 strdup( PyString_AsString( PyObject_Str(
73 PySequence_GetItem( py_param,
76 ppsz_args[i_size] = NULL;
77 Py_DECREF( py_param );
82 /* No arguments were given. Clear the exception raised
83 by PyArg_ParseTuple. */
87 Py_BEGIN_ALLOW_THREADS
91 self->mc = mediacontrol_new_from_instance( p_instance, exception );
92 Py_INCREF( py_param );
93 self->vlc_instance = ( vlcInstance* ) py_param;
97 self->mc = mediacontrol_new( i_size, ppsz_args, exception );
98 self->vlc_instance = PyObject_New( vlcInstance, &vlcInstance_Type );
99 self->vlc_instance->p_instance = mediacontrol_get_libvlc_instance( SELF->mc );
105 return ( PyObject * )self;
109 MediaControl_dealloc( PyObject *self )
111 Py_DECREF( SELF->vlc_instance );
112 PyObject_DEL( self );
116 MediaControl_get_vlc_instance( PyObject *self, PyObject *args )
120 p_ret = SELF->vlc_instance;
122 return ( PyObject * )p_ret;
126 * Return the current position in the stream. The returned value can
127 be relative or absolute ( according to PositionOrigin ) and the unit
128 is set by PositionKey
131 MediaControl_get_media_position( PyObject *self, PyObject *args )
133 mediacontrol_Position* pos;
134 mediacontrol_Exception* exception = NULL;
138 mediacontrol_PositionOrigin origin;
139 mediacontrol_PositionKey key;
141 if( !PyArg_ParseTuple( args, "OO", &py_origin, &py_key ) )
144 origin = positionOrigin_py_to_c( py_origin );
145 key = positionKey_py_to_c( py_key );
147 Py_BEGIN_ALLOW_THREADS
149 pos = mediacontrol_get_media_position( SELF->mc, origin, key, exception );
153 py_retval = ( PyObject* )position_c_to_py( pos );
158 /** Set the media position */
160 MediaControl_set_media_position( PyObject *self, PyObject *args )
162 mediacontrol_Exception* exception = NULL;
163 mediacontrol_Position *a_position;
166 if( !PyArg_ParseTuple( args, "O", &py_pos ) )
169 a_position = position_py_to_c( py_pos );
172 PyErr_SetString( PyExc_MemoryError, "Out of memory" );
176 Py_BEGIN_ALLOW_THREADS
178 mediacontrol_set_media_position( SELF->mc, a_position, exception );
183 Py_INCREF( Py_None );
188 MediaControl_start( PyObject *self, PyObject *args )
190 mediacontrol_Position *a_position;
191 mediacontrol_Exception *exception = NULL;
194 if( !PyArg_ParseTuple( args, "O", &py_pos ) )
196 /* No argument. Use a default 0 value. */
200 a_position = position_py_to_c( py_pos );
204 Py_BEGIN_ALLOW_THREADS
206 mediacontrol_start( SELF->mc, a_position, exception );
211 Py_INCREF( Py_None );
216 MediaControl_pause( PyObject *self, PyObject *args )
218 mediacontrol_Position *a_position;
219 mediacontrol_Exception *exception = NULL;
222 if( !PyArg_ParseTuple( args, "O", &py_pos ) )
224 /* No argument. Use a default 0 value. */
228 a_position = position_py_to_c( py_pos );
232 Py_BEGIN_ALLOW_THREADS
234 mediacontrol_pause( SELF->mc, a_position, exception );
239 Py_INCREF( Py_None );
244 MediaControl_resume( PyObject *self, PyObject *args )
246 mediacontrol_Position *a_position;
247 mediacontrol_Exception *exception = NULL;
250 if( !PyArg_ParseTuple( args, "O", &py_pos ) )
252 /* No argument. Use a default 0 value. */
256 a_position = position_py_to_c( py_pos );
260 Py_BEGIN_ALLOW_THREADS
262 mediacontrol_start( SELF->mc, a_position, exception );
267 Py_INCREF( Py_None );
272 MediaControl_stop( PyObject *self, PyObject *args )
274 mediacontrol_Position *a_position;
275 mediacontrol_Exception *exception = NULL;
278 if( !PyArg_ParseTuple( args, "O", &py_pos ) )
280 /* No argument. Use a default 0 value. */
284 a_position = position_py_to_c( py_pos );
288 Py_BEGIN_ALLOW_THREADS
290 mediacontrol_stop( SELF->mc, a_position, exception );
295 Py_INCREF( Py_None );
300 MediaControl_exit( PyObject *self, PyObject *args )
302 mediacontrol_exit( SELF->mc );
303 Py_INCREF( Py_None );
308 MediaControl_playlist_add_item( PyObject *self, PyObject *args )
311 mediacontrol_Exception *exception = NULL;
313 if( !PyArg_ParseTuple( args, "s", &psz_file ) )
316 Py_BEGIN_ALLOW_THREADS
318 mediacontrol_playlist_add_item( SELF->mc, psz_file, exception );
322 Py_INCREF( Py_None );
327 MediaControl_playlist_clear( PyObject *self, PyObject *args )
329 mediacontrol_Exception *exception = NULL;
331 Py_BEGIN_ALLOW_THREADS
333 mediacontrol_playlist_clear( SELF->mc, exception );
337 Py_INCREF( Py_None );
342 MediaControl_playlist_get_list( PyObject *self, PyObject *args )
345 mediacontrol_Exception *exception = NULL;
346 mediacontrol_PlaylistSeq* pl;
348 Py_ssize_t i_playlist_size;
350 Py_BEGIN_ALLOW_THREADS
352 pl = mediacontrol_playlist_get_list( SELF->mc, exception );
356 i_playlist_size = pl->size;
358 py_retval = PyList_New( i_playlist_size );
360 for ( i_index = 0 ; i_index < i_playlist_size ; i_index++ )
362 PyList_SetItem( py_retval, i_index,
363 Py_BuildValue( "s", pl->data[i_index] ) );
365 mediacontrol_PlaylistSeq__free( pl );
372 MediaControl_snapshot( PyObject *self, PyObject *args )
374 mediacontrol_RGBPicture *p_retval = NULL;
375 mediacontrol_Exception* exception = NULL;
376 mediacontrol_Position *a_position = NULL;
377 PyObject *py_pos = NULL;
378 PyObject *py_obj = NULL;
380 if( !PyArg_ParseTuple( args, "O", &py_pos ) )
383 a_position = position_py_to_c( py_pos );
385 Py_BEGIN_ALLOW_THREADS
387 p_retval = mediacontrol_snapshot( SELF->mc, a_position, exception );
394 Py_INCREF( Py_None );
398 /* FIXME: create a real RGBPicture object */
399 py_obj = PyDict_New();
401 PyDict_SetItemString( py_obj, "width",
402 Py_BuildValue( "i", p_retval->width ) );
403 PyDict_SetItemString( py_obj, "height",
404 Py_BuildValue( "i", p_retval->height ) );
405 PyDict_SetItemString( py_obj, "type",
406 Py_BuildValue( "i", p_retval->type ) );
407 PyDict_SetItemString( py_obj, "data",
408 Py_BuildValue( "s#", p_retval->data, p_retval->size ) );
409 PyDict_SetItemString( py_obj, "date",
410 Py_BuildValue( "L", p_retval->date ) );
412 mediacontrol_RGBPicture__free( p_retval );
418 MediaControl_display_text( PyObject *self, PyObject *args )
420 mediacontrol_Exception* exception = NULL;
421 PyObject *py_begin, *py_end;
423 mediacontrol_Position * begin;
424 mediacontrol_Position * end;
426 if( !PyArg_ParseTuple( args, "sOO", &message, &py_begin, &py_end ) )
429 begin = position_py_to_c( py_begin );
430 end = position_py_to_c( py_end );
432 Py_BEGIN_ALLOW_THREADS
434 mediacontrol_display_text( SELF->mc, message, begin, end, exception );
441 Py_INCREF( Py_None );
446 MediaControl_get_stream_information( PyObject *self, PyObject *args )
448 mediacontrol_StreamInformation *retval = NULL;
449 mediacontrol_Exception* exception = NULL;
452 Py_BEGIN_ALLOW_THREADS
454 retval = mediacontrol_get_stream_information(
455 SELF->mc, mediacontrol_MediaTime, exception );
459 py_obj = PyDict_New( );
461 /* FIXME: create a real StreamInformation object */
462 PyDict_SetItemString( py_obj, "status",
463 Py_BuildValue( "i", retval->streamstatus ) );
464 PyDict_SetItemString( py_obj, "url",
465 Py_BuildValue( "s", retval->url ) );
466 PyDict_SetItemString( py_obj, "position",
467 Py_BuildValue( "L", retval->position ) );
468 PyDict_SetItemString( py_obj, "length",
469 Py_BuildValue( "L", retval->length ) );
471 mediacontrol_StreamInformation__free( retval );
477 MediaControl_sound_set_volume( PyObject *self, PyObject *args )
479 mediacontrol_Exception* exception = NULL;
480 unsigned short volume;
482 if( !PyArg_ParseTuple( args, "H", &volume ) )
485 Py_BEGIN_ALLOW_THREADS
487 mediacontrol_sound_set_volume( SELF->mc, volume, exception );
491 Py_INCREF( Py_None );
496 MediaControl_sound_get_volume( PyObject *self, PyObject *args )
498 mediacontrol_Exception* exception = NULL;
500 unsigned short volume;
502 Py_BEGIN_ALLOW_THREADS
504 volume = mediacontrol_sound_get_volume( SELF->mc, exception );
508 py_retval = Py_BuildValue( "H", volume );
513 MediaControl_set_rate( PyObject *self, PyObject *args )
515 mediacontrol_Exception* exception = NULL;
518 if( !PyArg_ParseTuple( args, "i", &rate ) )
521 Py_BEGIN_ALLOW_THREADS
523 mediacontrol_set_rate( SELF->mc, rate, exception );
527 Py_INCREF( Py_None );
532 MediaControl_get_rate( PyObject *self, PyObject *args )
534 mediacontrol_Exception* exception = NULL;
538 Py_BEGIN_ALLOW_THREADS
540 rate = mediacontrol_get_rate( SELF->mc, exception );
544 py_retval = Py_BuildValue( "i", rate );
549 MediaControl_set_fullscreen( PyObject *self, PyObject *args )
551 mediacontrol_Exception* exception = NULL;
554 if( !PyArg_ParseTuple( args, "i", &fs ) )
557 Py_BEGIN_ALLOW_THREADS
559 mediacontrol_set_fullscreen( SELF->mc, fs, exception );
563 Py_INCREF( Py_None );
568 MediaControl_get_fullscreen( PyObject *self, PyObject *args )
570 mediacontrol_Exception* exception = NULL;
574 Py_BEGIN_ALLOW_THREADS
576 fs = mediacontrol_get_fullscreen( SELF->mc, exception );
580 py_retval = Py_BuildValue( "i", fs );
585 MediaControl_set_visual( PyObject *self, PyObject *args )
587 mediacontrol_Exception* exception = NULL;
590 if( !PyArg_ParseTuple( args, "i", &visual ) )
593 Py_BEGIN_ALLOW_THREADS
595 mediacontrol_set_visual( SELF->mc, visual, exception );
599 Py_INCREF( Py_None );
603 static PyMethodDef MediaControl_methods[] =
605 { "get_vlc_instance", MediaControl_get_vlc_instance, METH_VARARGS,
606 "get_vlc_instance( ) -> Instance Get matching vlc.Instance." },
607 { "get_media_position", MediaControl_get_media_position, METH_VARARGS,
608 "get_media_position( origin, key ) -> Position Get current media position." },
609 { "set_media_position", MediaControl_set_media_position, METH_VARARGS,
610 "set_media_position( Position ) Set media position" },
611 { "start", MediaControl_start, METH_VARARGS,
612 "start( Position ) Start the player." },
613 { "pause", MediaControl_pause, METH_VARARGS,
614 "pause( Position ) Pause the player." },
615 { "resume", MediaControl_resume, METH_VARARGS,
616 "resume( Position ) Resume the player" },
617 { "stop", MediaControl_stop, METH_VARARGS,
618 "stop( Position ) Stop the player" },
619 { "exit", MediaControl_exit, METH_VARARGS,
620 "exit( ) Exit the player" },
621 { "playlist_add_item", MediaControl_playlist_add_item, METH_VARARGS,
622 "playlist_add_item( str ) Add an item to the playlist" },
623 { "playlist_get_list", MediaControl_playlist_get_list, METH_VARARGS,
624 "playlist_get_list( ) -> list Get the contents of the playlist" },
625 { "playlist_clear", MediaControl_playlist_clear, METH_VARARGS,
626 "clear( ) Clear the playlist." },
627 { "snapshot", MediaControl_snapshot, METH_VARARGS,
628 "snapshot( Position ) -> dict Take a snapshot" },
629 { "display_text", MediaControl_display_text, METH_VARARGS,
630 "display_text( str, Position, Position ) Display a text on the video" },
631 { "get_stream_information", MediaControl_get_stream_information,
633 "get_stream_information( ) -> dict Get information about the stream"},
634 { "sound_get_volume", MediaControl_sound_get_volume, METH_VARARGS,
635 "sound_get_volume( ) -> int Get the volume" },
636 { "sound_set_volume", MediaControl_sound_set_volume, METH_VARARGS,
637 "sound_set_volume( int ) Set the volume" },
638 { "set_visual", MediaControl_set_visual, METH_VARARGS,
639 "set_visual( int ) Set the embedding window visual ID" },
640 { "get_rate", MediaControl_get_rate, METH_VARARGS,
641 "get_rate( ) -> int Get the rate" },
642 { "set_rate", MediaControl_set_rate, METH_VARARGS,
643 "set_rate( int ) Set the rate" },
644 { "get_fullscreen", MediaControl_get_fullscreen, METH_VARARGS,
645 "get_fullscreen( ) -> int Get the fullscreen status" },
646 { "set_fullscreen", MediaControl_set_fullscreen, METH_VARARGS,
647 "set_fullscreen( int ) Set the fullscreen status" },
648 { NULL, NULL, 0, NULL },
651 static PyTypeObject MediaControl_Type =
653 PyObject_HEAD_INIT( NULL )
655 "vlc.MediaControl", /*tp_name*/
656 sizeof( MediaControl_Type ), /*tp_basicsize*/
658 ( destructor )MediaControl_dealloc, /*tp_dealloc*/
665 0, /*tp_as_sequence*/
673 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
674 "Control of a VLC instance.\n\nvlc.MediaControl(args): initialisation with a list of VLC parameters.\nvlc.MediaControl(instance): initialisation with an existing vlc.Instance", /* tp_doc */
677 0, /* tp_richcompare */
678 0, /* tp_weaklistoffset */
681 MediaControl_methods, /* tp_methods */
686 0, /* tp_descr_get */
687 0, /* tp_descr_set */
688 0, /* tp_dictoffset */
691 MediaControl_new, /* tp_new */