]> git.sesse.net Git - vlc/blob - bindings/python-ctypes/header.py
python-ctypes: improve enum conversion
[vlc] / bindings / python-ctypes / header.py
1 #! /usr/bin/python
2
3 #
4 # Python ctypes bindings for VLC
5 # Copyright (C) 2009 the VideoLAN team
6 # $Id: $
7 #
8 # Authors: Olivier Aubert <olivier.aubert at liris.cnrs.fr>
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 """This module provides bindings for the
26 U{libvlc<http://wiki.videolan.org/ExternalAPI>} and
27 U{MediaControl<http://wiki.videolan.org/MediaControlAPI>} APIs.
28
29 You can find documentation at U{http://www.advene.org/download/python-ctypes/}.
30
31 Basically, the most important class is L{Instance}, which is used to
32 create a libvlc Instance. From this instance, you can then create
33 L{MediaPlayer} and L{MediaListPlayer} instances.
34 """
35
36 import logging
37 import ctypes
38 import sys
39
40 build_date="This will be replaced by the build date"
41
42 if sys.platform == 'linux2':
43     dll=ctypes.CDLL('libvlc.so')
44 elif sys.platform == 'win32':
45     import ctypes.util
46     import os
47     plugin_path=None
48     path=ctypes.util.find_library('libvlc.dll')
49     if path is None:
50         # Try to use registry settings
51         import _winreg
52         plugin_path_found = None
53         subkey, name = 'Software\\VideoLAN\\VLC','InstallDir'
54         for hkey in _winreg.HKEY_LOCAL_MACHINE, _winreg.HKEY_CURRENT_USER:
55             try:
56                 reg = _winreg.OpenKey(hkey, subkey)
57                 plugin_path_found, type_id = _winreg.QueryValueEx(reg, name)
58                 _winreg.CloseKey(reg)
59                 break
60             except _winreg.error:
61                 pass
62         if plugin_path_found:
63             plugin_path = plugin_path_found
64         else:
65             # Try a standard location.
66             p='c:\\Program Files\\VideoLAN\\VLC\\libvlc.dll'
67             if os.path.exists(p):
68                 plugin_path=os.path.dirname(p)
69         os.chdir(plugin_path)
70         # If chdir failed, this will not work and raise an exception
71         path='libvlc.dll'
72     else:
73         plugin_path=os.path.dirname(path)
74     dll=ctypes.CDLL(path)
75 elif sys.platform == 'darwin':
76     # FIXME: should find a means to configure path
77     dll=ctypes.CDLL('/Applications/VLC.app/Contents/MacOS/lib/libvlc.2.dylib')
78
79 #
80 # Generated enum types.
81 #
82
83 # GENERATED_ENUMS
84
85 #
86 # End of generated enum types.
87 #
88
89 class ListPOINTER(object):
90     '''Just like a POINTER but accept a list of ctype as an argument.
91     '''
92     def __init__(self, etype):
93         self.etype = etype
94
95     def from_param(self, param):
96         if isinstance(param, (list,tuple)):
97             return (self.etype * len(param))(*param)
98
99 class LibVLCException(Exception):
100     """Python exception raised by libvlc methods.
101     """
102     pass
103
104 # From libvlc_structures.h
105
106 # This is version-dependent, depending on the presence of libvlc_errmsg
107
108 if hasattr(dll, 'libvlc_errmsg'):
109     # New-style message passing
110     class VLCException(ctypes.Structure):
111         """libvlc exception.
112         """
113         _fields_= [
114                     ('raised', ctypes.c_int),
115                     ]
116
117         @property
118         def message(self):
119             return dll.libvlc_errmsg()
120
121         def init(self):
122             libvlc_exception_init(self)
123
124         def clear(self):
125             libvlc_exception_clear(self)
126 else:
127     # Old-style exceptions
128     class VLCException(ctypes.Structure):
129         """libvlc exception.
130         """
131         _fields_= [
132                     ('raised', ctypes.c_int),
133                     ('code', ctypes.c_int),
134                     ('message', ctypes.c_char_p),
135                     ]
136         def init(self):
137             libvlc_exception_init(self)
138
139         def clear(self):
140             libvlc_exception_clear(self)
141
142 class PlaylistItem(ctypes.Structure):
143     _fields_= [
144                 ('id', ctypes.c_int),
145                 ('uri', ctypes.c_char_p),
146                 ('name', ctypes.c_char_p),
147                 ]
148
149     def __str__(self):
150         return "PlaylistItem #%d %s (%uri)" % (self.id, self.name, self.uri)
151
152 class LogMessage(ctypes.Structure):
153     _fields_= [
154                 ('size', ctypes.c_uint),
155                 ('severity', ctypes.c_int),
156                 ('type', ctypes.c_char_p),
157                 ('name', ctypes.c_char_p),
158                 ('header', ctypes.c_char_p),
159                 ('message', ctypes.c_char_p),
160                 ]
161
162     def __init__(self):
163         self.size=ctypes.sizeof(self)
164
165     def __str__(self):
166         return "vlc.LogMessage(%d:%s): %s" % (self.severity, self.type, self.message)
167
168 class MediaControlPosition(ctypes.Structure):
169     _fields_= [
170                 ('origin', PositionOrigin),
171                 ('key', PositionKey),
172                 ('value', ctypes.c_longlong),
173                 ]
174
175     def __init__(self, value=0, origin=None, key=None):
176         # We override the __init__ method so that instanciating the
177         # class with an int as parameter will create the appropriate
178         # default position (absolute position, media time, with the
179         # int as value).
180         self.value=value
181         if origin is None:
182             origin=PositionOrigin.AbsolutePosition
183         if key is None:
184             key=PositionKey.MediaTime
185         self.origin=origin
186         self.key=key
187
188     def __str__(self):
189         return "MediaControlPosition %ld (%s, %s)" % (
190             self.value,
191             str(self.origin),
192             str(self.key)
193             )
194
195     @staticmethod
196     def from_param(arg):
197         if isinstance(arg, (int, long)):
198             p=MediaControlPosition(arg)
199             return p
200         else:
201             return arg
202
203 class MediaControlException(ctypes.Structure):
204     _fields_= [
205                 ('code', ctypes.c_int),
206                 ('message', ctypes.c_char_p),
207                 ]
208     def init(self):
209         mediacontrol_exception_init(self)
210
211     def clear(self):
212         mediacontrol_exception_free(self)
213
214 class MediaControlStreamInformation(ctypes.Structure):
215     _fields_= [
216                 ('status', PlayerStatus),
217                 ('url', ctypes.c_char_p),
218                 ('position', ctypes.c_longlong),
219                 ('length', ctypes.c_longlong),
220                 ]
221
222     def __str__(self):
223         return "%s (%s) : %ld / %ld" % (self.url or "<No defined URL>",
224                                         str(self.status),
225                                         self.position,
226                                         self.length)
227
228 class RGBPicture(ctypes.Structure):
229     _fields_= [
230                 ('width', ctypes.c_int),
231                 ('height', ctypes.c_int),
232                 ('type', ctypes.c_uint32),
233                 ('date', ctypes.c_ulonglong),
234                 ('size', ctypes.c_int),
235                 ('data_pointer', ctypes.c_void_p),
236                 ]
237
238     @property
239     def data(self):
240         return ctypes.string_at(self.data_pointer, self.size)
241
242     def __str__(self):
243         return "RGBPicture (%d, %d) - %ld ms - %d bytes" % (self.width, self.height, self.date, self.size)
244
245     def free(self):
246         mediacontrol_RGBPicture__free(self)
247
248 def check_vlc_exception(result, func, args):
249     """Error checking method for functions using an exception in/out parameter.
250     """
251     ex=args[-1]
252     if not isinstance(ex, (VLCException, MediaControlException)):
253         logging.warn("python-vlc: error when processing function %s. Please report this as a bug to vlc-devel@videolan.org" % str(func))
254         return result
255     # Take into account both VLCException and MediacontrolException:
256     c=getattr(ex, 'raised', getattr(ex, 'code', 0))
257     if c:
258         raise LibVLCException(ex.message)
259     return result
260
261 ### End of header.py ###