]> git.sesse.net Git - vlc/blob - bindings/python-ctypes/header.py
python-ctypes: accomodate both old and new message exception getter
[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 ctypes
37 import sys
38
39 build_date="This will be replaced by the build date"
40
41 if sys.platform == 'linux2':
42     dll=ctypes.CDLL('libvlc.so')
43 elif sys.platform == 'win32':
44     import ctypes.util
45     import os
46     plugin_path=None
47     path=ctypes.util.find_library('libvlc.dll')
48     if path is None:
49         # Try to use registry settings
50         import _winreg
51         plugin_path_found = None
52         subkey, name = 'Software\\VideoLAN\\VLC','InstallDir'
53         for hkey in _winreg.HKEY_LOCAL_MACHINE, _winreg.HKEY_CURRENT_USER:
54             try:
55                 reg = _winreg.OpenKey(hkey, subkey)
56                 plugin_path_found, type_id = _winreg.QueryValueEx(reg, name)
57                 _winreg.CloseKey(reg)
58                 break
59             except _winreg.error:
60                 pass
61         if plugin_path_found:
62             plugin_path = plugin_path_found
63         else:
64             # Try a standard location.
65             p='c:\\Program Files\\VideoLAN\\VLC\\libvlc.dll'
66             if os.path.exists(p):
67                 plugin_path=os.path.dirname(p)
68         os.chdir(plugin_path)
69         # If chdir failed, this will not work and raise an exception
70         path='libvlc.dll'
71     else:
72         plugin_path=os.path.dirname(path)
73     dll=ctypes.CDLL(path)
74 elif sys.platform == 'darwin':
75     # FIXME: should find a means to configure path
76     dll=ctypes.CDLL('/Applications/VLC.app/Contents/MacOS/lib/libvlc.2.dylib')
77
78 class ListPOINTER(object):
79     '''Just like a POINTER but accept a list of ctype as an argument.
80     '''
81     def __init__(self, etype):
82         self.etype = etype
83
84     def from_param(self, param):
85         if isinstance(param, (list,tuple)):
86             return (self.etype * len(param))(*param)
87
88 class LibVLCException(Exception):
89     """Python exception raised by libvlc methods.
90     """
91     pass
92
93 # From libvlc_structures.h
94
95 # This is version-dependent, depending on the presence of libvlc_exception_get_message.
96
97 if hasattr(dll, 'libvlc_exception_get_message'):
98     # New-style message passing
99     class VLCException(ctypes.Structure):
100         """libvlc exception.
101         """
102         _fields_= [
103                     ('raised', ctypes.c_int),
104                     ]
105
106         @property
107         def message(self):
108             return dll.libvlc_exception_get_message()
109
110         def init(self):
111             libvlc_exception_init(self)
112
113         def clear(self):
114             libvlc_exception_clear(self)
115 else:
116     # Old-style exceptions
117     class VLCException(ctypes.Structure):
118         """libvlc exception.
119         """
120         _fields_= [
121                     ('raised', ctypes.c_int),
122                     ('code', ctypes.c_int),
123                     ('message', ctypes.c_char_p),
124                     ]
125         def init(self):
126             libvlc_exception_init(self)
127
128         def clear(self):
129             libvlc_exception_clear(self)
130
131 class PlaylistItem(ctypes.Structure):
132     _fields_= [
133                 ('id', ctypes.c_int),
134                 ('uri', ctypes.c_char_p),
135                 ('name', ctypes.c_char_p),
136                 ]
137
138     def __str__(self):
139         return "PlaylistItem #%d %s (%uri)" % (self.id, self.name, self.uri)
140
141 class LogMessage(ctypes.Structure):
142     _fields_= [
143                 ('size', ctypes.c_uint),
144                 ('severity', ctypes.c_int),
145                 ('type', ctypes.c_char_p),
146                 ('name', ctypes.c_char_p),
147                 ('header', ctypes.c_char_p),
148                 ('message', ctypes.c_char_p),
149                 ]
150
151     def __str__(self):
152         return "vlc.LogMessage(%d:%s): %s" % (self.severity, self.type, self.message)
153
154 class MediaControlPosition(ctypes.Structure):
155     _fields_= [
156                 ('origin', ctypes.c_int),
157                 ('key', ctypes.c_int),
158                 ('value', ctypes.c_longlong),
159                 ]
160
161     def __str__(self):
162         return "MediaControlPosition %ld (%s, %s)" % (
163             self.value,
164             str(PositionOrigin(self.origin)),
165             str(PositionKey(self.key))
166             )
167
168     @staticmethod
169     def from_param(arg):
170         if isinstance(arg, (int, long)):
171             p=MediaControlPosition()
172             p.value=arg
173             p.key=2
174             return p
175         else:
176             return arg
177
178 class MediaControlException(ctypes.Structure):
179     _fields_= [
180                 ('code', ctypes.c_int),
181                 ('message', ctypes.c_char_p),
182                 ]
183     def init(self):
184         mediacontrol_exception_init(self)
185
186     def clear(self):
187         mediacontrol_exception_free(self)
188
189 class MediaControlStreamInformation(ctypes.Structure):
190     _fields_= [
191                 ('status', ctypes.c_int),
192                 ('url', ctypes.c_char_p),
193                 ('position', ctypes.c_longlong),
194                 ('length', ctypes.c_longlong),
195                 ]
196
197     def __str__(self):
198         return "%s (%s) : %ld / %ld" % (self.url,
199                                         str(PlayerStatus(self.status)),
200                                         self.position,
201                                         self.length)
202
203 class RGBPicture(ctypes.Structure):
204     _fields_= [
205                 ('width', ctypes.c_int),
206                 ('height', ctypes.c_int),
207                 ('type', ctypes.c_uint32),
208                 ('date', ctypes.c_ulonglong),
209                 ('size', ctypes.c_int),
210                 ('data_pointer', ctypes.c_void_p),
211                 ]
212
213     @property
214     def data(self):
215         return ctypes.string_at(self.data_pointer, self.size)
216
217     def __str__(self):
218         return "RGBPicture (%d, %d) - %ld ms - %d bytes" % (self.width, self.height, self.date, self.size)
219
220     def free(self):
221         mediacontrol_RGBPicture__free(self)
222
223 def check_vlc_exception(result, func, args):
224     """Error checking method for functions using an exception in/out parameter.
225     """
226     ex=args[-1]
227     # Take into account both VLCException and MediacontrolException:
228     c=getattr(ex, 'raised', getattr(ex, 'code', 0))
229     if c:
230         raise LibVLCException(args[-1].message)
231     return result
232
233 ### End of header.py ###