3de106b9041875f4eba1ffc34a6fd16537576a88
[vlc/bindings/python.git] / generator / templates / override.py
1
2 class Instance:
3     """Create a new Instance instance.
4
5     It may take as parameter either:
6       - a string
7       - a list of strings as first parameters
8       - the parameters given as the constructor parameters (must be strings)
9     """
10     def __new__(cls, *args):
11         if len(args) == 1:
12             # Only 1 arg. It is either a C pointer, or an arg string,
13             # or a tuple.
14             i = args[0]
15             if isinstance(i, _Ints):
16                 return _Constructor(cls, i)
17             elif isinstance(i, basestring):
18                 args = i.strip().split()
19             elif isinstance(i, _Seqs):
20                 args = list(i)
21             else:
22                 raise VLCException('Instance %r' % (args,))
23         else:
24             args = list(args)
25
26         if not args:  # no parameters passed
27             args = ['vlc']
28         elif args[0] != 'vlc':
29             args.insert(0, 'vlc')
30
31         if plugin_path is not None:
32             # set plugin_path if detected, win32 and MacOS,
33             # if the user did not specify it itself.
34             os.environ.setdefault('VLC_PLUGIN_PATH', plugin_path)
35
36         if PYTHON3:
37             args = [ str_to_bytes(a) for a in args ]
38         return libvlc_new(len(args), args)
39
40     def media_player_new(self, uri=None):
41         """Create a new MediaPlayer instance.
42
43         @param uri: an optional URI to play in the player.
44         """
45         p = libvlc_media_player_new(self)
46         if uri:
47             p.set_media(self.media_new(uri))
48         p._instance = self
49         return p
50
51     def media_list_player_new(self):
52         """Create a new MediaListPlayer instance.
53         """
54         p = libvlc_media_list_player_new(self)
55         p._instance = self
56         return p
57
58     def media_new(self, mrl, *options):
59         """Create a new Media instance.
60
61         If mrl contains a colon (:) preceded by more than 1 letter, it
62         will be treated as a URL. Else, it will be considered as a
63         local path. If you need more control, directly use
64         media_new_location/media_new_path methods.
65
66         Options can be specified as supplementary string parameters,
67         but note that many options cannot be set at the media level,
68         and rather at the Instance level. For instance, the marquee
69         filter must be specified when creating the vlc.Instance or
70         vlc.MediaPlayer.
71
72         Alternatively, options can be added to the media using the
73         Media.add_options method (with the same limitation).
74
75         @param options: optional media option=value strings
76         """
77         if ':' in mrl and mrl.index(':') > 1:
78             # Assume it is a URL
79             m = libvlc_media_new_location(self, str_to_bytes(mrl))
80         else:
81             # Else it should be a local path.
82             m = libvlc_media_new_path(self, str_to_bytes(os.path.normpath(mrl)))
83         for o in options:
84             libvlc_media_add_option(m, str_to_bytes(o))
85         m._instance = self
86         return m
87
88     def media_list_new(self, mrls=None):
89         """Create a new MediaList instance.
90         @param mrls: optional list of MRL strings
91         """
92         l = libvlc_media_list_new(self)
93         # We should take the lock, but since we did not leak the
94         # reference, nobody else can access it.
95         if mrls:
96             for m in mrls:
97                 l.add_media(m)
98         l._instance = self
99         return l
100
101     def audio_output_enumerate_devices(self):
102         """Enumerate the defined audio output devices.
103
104         @return: list of dicts {name:, description:, devices:}
105         """
106         r = []
107         head = libvlc_audio_output_list_get(self)
108         if head:
109             i = head
110             while i:
111                 i = i.contents
112                 d = [{'id':       libvlc_audio_output_device_id      (self, i.name, d),
113                       'longname': libvlc_audio_output_device_longname(self, i.name, d)}
114                    for d in range(libvlc_audio_output_device_count   (self, i.name))]
115                 r.append({'name': i.name, 'description': i.description, 'devices': d})
116                 i = i.next
117             libvlc_audio_output_list_release(head)
118         return r
119
120     def audio_filter_list_get(self):
121         """Returns a list of available audio filters.
122
123         """
124         return module_description_list(libvlc_audio_filter_list_get(self))
125
126     def video_filter_list_get(self):
127         """Returns a list of available video filters.
128
129         """
130         return module_description_list(libvlc_video_filter_list_get(self))
131
132 class Media:
133     """Create a new Media instance.
134
135     Usage: Media(MRL, *options)
136
137     See vlc.Instance.media_new documentation for details.
138     """
139     def __new__(cls, *args):
140         if args:
141             i = args[0]
142             if isinstance(i, _Ints):
143                 return _Constructor(cls, i)
144             if isinstance(i, Instance):
145                 return i.media_new(*args[1:])
146
147         o = get_default_instance().media_new(*args)
148         return o
149
150     def get_instance(self):
151         return getattr(self, '_instance', None)
152
153     def add_options(self, *options):
154         """Add a list of options to the media.
155
156         Options must be written without the double-dash. Warning: most
157         audio and video options, such as text renderer, have no
158         effects on an individual media. These options must be set at
159         the vlc.Instance or vlc.MediaPlayer instanciation.
160
161         @param options: optional media option=value strings
162         """
163         for o in options:
164             self.add_option(o)
165
166     def tracks_get(self):
167         """Get media descriptor's elementary streams description
168         Note, you need to call L{parse}() or play the media at least once
169         before calling this function.
170         Not doing this will result in an empty array.
171         The result must be freed with L{tracks_release}.
172         @version: LibVLC 2.1.0 and later.
173         """
174         mediaTrack_pp = ctypes.POINTER(MediaTrack)()
175         n = libvlc_media_tracks_get(self, ctypes.byref(mediaTrack_pp))
176         info = ctypes.cast(mediaTrack_pp, ctypes.POINTER(ctypes.POINTER(MediaTrack) * n))
177         try:
178             contents = info.contents
179         except ValueError:
180             # Media not parsed, no info.
181             return None
182         tracks = ( contents[i].contents for i in range(len(contents)) )
183         # libvlc_media_tracks_release(mediaTrack_pp, n)
184         return tracks
185
186 class MediaList:
187     """Create a new MediaList instance.
188
189     Usage: MediaList(list_of_MRLs)
190
191     See vlc.Instance.media_list_new documentation for details.
192     """
193     def __new__(cls, *args):
194         if args:
195             i = args[0]
196             if isinstance(i, _Ints):
197                 return _Constructor(cls, i)
198             if isinstance(i, Instance):
199                 return i.media_list_new(*args[1:])
200
201         o = get_default_instance().media_list_new(*args)
202         return o
203
204     def get_instance(self):
205         return getattr(self, '_instance', None)
206
207     def add_media(self, mrl):
208         """Add media instance to media list.
209
210         The L{lock} should be held upon entering this function.
211         @param mrl: a media instance or a MRL.
212         @return: 0 on success, -1 if the media list is read-only.
213         """
214         if isinstance(mrl, basestring):
215             mrl = (self.get_instance() or get_default_instance()).media_new(mrl)
216         return libvlc_media_list_add_media(self, mrl)
217
218 class MediaPlayer:  #PYCHOK expected (comment is lost)
219     """Create a new MediaPlayer instance.
220
221     It may take as parameter either:
222       - a string (media URI), options... In this case, a vlc.Instance will be created.
223       - a vlc.Instance, a string (media URI), options...
224     """
225     def __new__(cls, *args):
226         if len(args) == 1 and isinstance(args[0], _Ints):
227             return _Constructor(cls, args[0])
228
229         if args and isinstance(args[0], Instance):
230             instance = args[0]
231             args = args[1:]
232         else:
233             instance = get_default_instance()
234
235         o = instance.media_player_new()
236         if args:
237             o.set_media(instance.media_new(*args))
238         return o
239
240     def get_instance(self):
241         """Return the associated Instance.
242         """
243         return self._instance  #PYCHOK expected
244
245     def set_mrl(self, mrl, *options):
246         """Set the MRL to play.
247
248         Warning: most audio and video options, such as text renderer,
249         have no effects on an individual media. These options must be
250         set at the vlc.Instance or vlc.MediaPlayer instanciation.
251
252         @param mrl: The MRL
253         @param options: optional media option=value strings
254         @return: the Media object
255         """
256         m = self.get_instance().media_new(mrl, *options)
257         self.set_media(m)
258         return m
259
260     def video_get_spu_description(self):
261         """Get the description of available video subtitles.
262         """
263         return track_description_list(libvlc_video_get_spu_description(self))
264
265     def video_get_title_description(self):
266         """Get the description of available titles.
267         """
268         return track_description_list(libvlc_video_get_title_description(self))
269
270     def video_get_chapter_description(self, title):
271         """Get the description of available chapters for specific title.
272
273         @param title: selected title (int)
274         """
275         return track_description_list(libvlc_video_get_chapter_description(self, title))
276
277     def video_get_track_description(self):
278         """Get the description of available video tracks.
279         """
280         return track_description_list(libvlc_video_get_track_description(self))
281
282     def audio_get_track_description(self):
283         """Get the description of available audio tracks.
284         """
285         return track_description_list(libvlc_audio_get_track_description(self))
286
287     def get_full_title_descriptions(self):
288         '''Get the full description of available titles.
289         @return: the titles list
290         @version: LibVLC 3.0.0 and later.
291         '''
292         titleDescription_pp = ctypes.POINTER(TitleDescription)()
293         n = libvlc_media_player_get_full_title_descriptions(self, ctypes.byref(titleDescription_pp))
294         info = ctypes.cast(titleDescription_pp, ctypes.POINTER(ctypes.POINTER(TitleDescription) * n))
295         try:
296             contents = info.contents
297         except ValueError:
298             # Media not parsed, no info.
299             return None
300         descr = ( contents[i].contents for i in range(len(contents)) )
301         return descr
302
303     def get_full_chapter_descriptions(self, i_chapters_of_title):
304         '''Get the full description of available chapters.
305         @param i_chapters_of_title: index of the title to query for chapters (uses current title if set to -1).
306         @return: the chapters list
307         @version: LibVLC 3.0.0 and later.
308         '''
309         chapterDescription_pp = ctypes.POINTER(ChapterDescription)()
310         n = libvlc_media_player_get_full_chapter_descriptions(self, ctypes.byref(chapterDescription_pp))
311         info = ctypes.cast(chapterDescription_pp, ctypes.POINTER(ctypes.POINTER(ChapterDescription) * n))
312         try:
313             contents = info.contents
314         except ValueError:
315             # Media not parsed, no info.
316             return None
317         descr = ( contents[i].contents for i in range(len(contents)) )
318         return descr
319
320     def video_get_size(self, num=0):
321         """Get the video size in pixels as 2-tuple (width, height).
322
323         @param num: video number (default 0).
324         """
325         r = libvlc_video_get_size(self, num)
326         if isinstance(r, tuple) and len(r) == 2:
327             return r
328         else:
329             raise VLCException('invalid video number (%s)' % (num,))
330
331     def set_hwnd(self, drawable):
332         """Set a Win32/Win64 API window handle (HWND).
333
334         Specify where the media player should render its video
335         output. If LibVLC was built without Win32/Win64 API output
336         support, then this has no effects.
337
338         @param drawable: windows handle of the drawable.
339         """
340         if not isinstance(drawable, ctypes.c_void_p):
341             drawable = ctypes.c_void_p(int(drawable))
342         libvlc_media_player_set_hwnd(self, drawable)
343
344     def video_get_width(self, num=0):
345         """Get the width of a video in pixels.
346
347         @param num: video number (default 0).
348         """
349         return self.video_get_size(num)[0]
350
351     def video_get_height(self, num=0):
352         """Get the height of a video in pixels.
353
354         @param num: video number (default 0).
355         """
356         return self.video_get_size(num)[1]
357
358     def video_get_cursor(self, num=0):
359         """Get the mouse pointer coordinates over a video as 2-tuple (x, y).
360
361         Coordinates are expressed in terms of the decoded video resolution,
362         B{not} in terms of pixels on the screen/viewport.  To get the
363         latter, you must query your windowing system directly.
364
365         Either coordinate may be negative or larger than the corresponding
366         size of the video, if the cursor is outside the rendering area.
367
368         @warning: The coordinates may be out-of-date if the pointer is not
369         located on the video rendering area.  LibVLC does not track the
370         mouse pointer if the latter is outside the video widget.
371
372         @note: LibVLC does not support multiple mouse pointers (but does
373         support multiple input devices sharing the same pointer).
374
375         @param num: video number (default 0).
376         """
377         r = libvlc_video_get_cursor(self, num)
378         if isinstance(r, tuple) and len(r) == 2:
379             return r
380         raise VLCException('invalid video number (%s)' % (num,))
381
382 class MediaListPlayer:
383     """Create a new MediaListPlayer instance.
384
385     It may take as parameter either:
386       - a vlc.Instance
387       - nothing
388     """
389     def __new__(cls, arg=None):
390         if arg is None:
391             i = get_default_instance()
392         elif isinstance(arg, Instance):
393             i = arg
394         elif isinstance(arg, _Ints):
395             return _Constructor(cls, arg)
396         else:
397             raise TypeError('MediaListPlayer %r' % (arg,))
398
399         return i.media_list_player_new()
400
401     def get_instance(self):
402         """Return the associated Instance.
403         """
404         return self._instance  #PYCHOK expected
405
406 class LogIterator:
407     """Create a new VLC log iterator.
408     """
409     def __iter__(self):
410         return self
411
412     def next(self):
413         if self.has_next():
414             b = LogMessage()
415             i = libvlc_log_iterator_next(self, b)
416             return i.contents
417         raise StopIteration
418
419     def __next__(self):
420         return self.next()
421
422 class Log:
423     """Create a new VLC log instance.
424     """
425     def __iter__(self):
426         return self.get_iterator()
427
428     def dump(self):
429         return [ str(m) for m in self ]
430
431 class EventManager:
432     """Create an event manager with callback handler.
433
434     This class interposes the registration and handling of
435     event notifications in order to (a) remove the need for
436     decorating each callback functions with the decorator
437     '@callbackmethod', (b) allow any number of positional
438     and/or keyword arguments to the callback (in addition
439     to the Event instance) and (c) to preserve the Python
440     objects such that the callback and argument objects
441     remain alive (i.e. are not garbage collected) until
442     B{after} the notification has been unregistered.
443
444     @note: Only a single notification can be registered
445     for each event type in an EventManager instance.
446     """
447     _callback_handler = None
448     _callbacks = {}
449
450     def __new__(cls, ptr=_internal_guard):
451         if ptr == _internal_guard:
452             raise VLCException("(INTERNAL) ctypes class.\nYou should get a reference to EventManager through the MediaPlayer.event_manager() method.")
453         return _Constructor(cls, ptr)
454
455     def event_attach(self, eventtype, callback, *args, **kwds):
456         """Register an event notification.
457
458         @param eventtype: the desired event type to be notified about.
459         @param callback: the function to call when the event occurs.
460         @param args: optional positional arguments for the callback.
461         @param kwds: optional keyword arguments for the callback.
462         @return: 0 on success, ENOMEM on error.
463
464         @note: The callback function must have at least one argument,
465         an Event instance.  Any other, optional positional and keyword
466         arguments are in B{addition} to the first one.
467         """
468         if not isinstance(eventtype, EventType):
469             raise VLCException("%s required: %r" % ('EventType', eventtype))
470         if not hasattr(callback, '__call__'):  # callable()
471             raise VLCException("%s required: %r" % ('callable', callback))
472          # check that the callback expects arguments
473         if not any(getargspec(callback)[:2]):  # list(...)
474             raise VLCException("%s required: %r" % ('argument', callback))
475
476         if self._callback_handler is None:
477             _called_from_ctypes = ctypes.CFUNCTYPE(None, ctypes.POINTER(Event), ctypes.c_void_p)
478             @_called_from_ctypes
479             def _callback_handler(event, k):
480                 """(INTERNAL) handle callback call from ctypes.
481
482                 @note: We cannot simply make this an EventManager
483                 method since ctypes does not prepend self as the
484                 first parameter, hence this closure.
485                 """
486                 try: # retrieve Python callback and arguments
487                     call, args, kwds = self._callbacks[k]
488                      # deref event.contents to simplify callback code
489                     call(event.contents, *args, **kwds)
490                 except KeyError:  # detached?
491                     pass
492             self._callback_handler = _callback_handler
493             self._callbacks = {}
494
495         k = eventtype.value
496         r = libvlc_event_attach(self, k, self._callback_handler, k)
497         if not r:
498             self._callbacks[k] = (callback, args, kwds)
499         return r
500
501     def event_detach(self, eventtype):
502         """Unregister an event notification.
503
504         @param eventtype: the event type notification to be removed.
505         """
506         if not isinstance(eventtype, EventType):
507             raise VLCException("%s required: %r" % ('EventType', eventtype))
508
509         k = eventtype.value
510         if k in self._callbacks:
511             del self._callbacks[k] # remove, regardless of libvlc return value
512             libvlc_event_detach(self, k, self._callback_handler, k)