4 # Python ctypes bindings for VLC
5 # Copyright (C) 2009 the VideoLAN team
8 # Authors: Olivier Aubert <olivier.aubert at liris.cnrs.fr>
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.
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.
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.
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.
29 You can find documentation at U{http://www.advene.org/download/python-ctypes/}.
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.
40 build_date="This will be replaced by the build date"
42 # Used for win32 and MacOS X
43 detected_plugin_path=None
45 if sys.platform == 'linux2':
46 dll=ctypes.CDLL('libvlc.so')
47 elif sys.platform == 'win32':
50 detected_plugin_path=None
51 path=ctypes.util.find_library('libvlc.dll')
53 # Try to use registry settings
55 detected_plugin_path_found = None
56 subkey, name = 'Software\\VideoLAN\\VLC','InstallDir'
57 for hkey in _winreg.HKEY_LOCAL_MACHINE, _winreg.HKEY_CURRENT_USER:
59 reg = _winreg.OpenKey(hkey, subkey)
60 detected_plugin_path_found, type_id = _winreg.QueryValueEx(reg, name)
65 if detected_plugin_path_found:
66 detected_plugin_path = detected_plugin_path_found
68 # Try a standard location.
69 p='c:\\Program Files\\VideoLAN\\VLC\\libvlc.dll'
71 detected_plugin_path=os.path.dirname(p)
72 os.chdir(detected_plugin_path)
73 # If chdir failed, this will not work and raise an exception
76 detected_plugin_path=os.path.dirname(path)
78 elif sys.platform == 'darwin':
79 # FIXME: should find a means to configure path
80 d='/Applications/VLC.app'
83 dll=ctypes.CDLL(d+'/Contents/MacOS/lib/libvlc.2.dylib')
84 detected_plugin_path=d+'/Contents/MacOS/modules'
86 # Hope some default path is set...
87 dll=ctypes.CDLL('libvlc.2.dylib')
90 # Generated enum types.
96 # End of generated enum types.
99 class ListPOINTER(object):
100 '''Just like a POINTER but accept a list of ctype as an argument.
102 def __init__(self, etype):
105 def from_param(self, param):
106 if isinstance(param, (list, tuple)):
107 return (self.etype * len(param))(*param)
109 class LibVLCException(Exception):
110 """Python exception raised by libvlc methods.
114 # From libvlc_structures.h
116 # This is version-dependent, depending on the presence of libvlc_errmsg
118 if hasattr(dll, 'libvlc_errmsg'):
119 # New-style message passing
120 class VLCException(ctypes.Structure):
124 ('raised', ctypes.c_int),
129 return dll.libvlc_errmsg()
132 libvlc_exception_init(self)
135 libvlc_exception_clear(self)
137 # Old-style exceptions
138 class VLCException(ctypes.Structure):
142 ('raised', ctypes.c_int),
143 ('code', ctypes.c_int),
144 ('message', ctypes.c_char_p),
147 libvlc_exception_init(self)
150 libvlc_exception_clear(self)
152 class MediaStats(ctypes.Structure):
154 ('read_bytes', ctypes.c_int ),
155 ('input_bitrate', ctypes.c_float),
156 ('demux_read_bytes', ctypes.c_int ),
157 ('demux_bitrate', ctypes.c_float),
158 ('demux_corrupted', ctypes.c_int ),
159 ('demux_discontinuity', ctypes.c_int ),
160 ('decoded_video', ctypes.c_int ),
161 ('decoded_audio', ctypes.c_int ),
162 ('displayed_pictures', ctypes.c_int ),
163 ('lost_pictures', ctypes.c_int ),
164 ('played_abuffers', ctypes.c_int ),
165 ('lost_abuffers', ctypes.c_int ),
166 ('sent_packets', ctypes.c_int ),
167 ('sent_bytes', ctypes.c_int ),
168 ('send_bitrate', ctypes.c_float),
172 return "MediaStats\n%s" % "\n".join( "%s:\t%s" % (n, getattr(self, n)) for n in self._fields_ )
174 class PlaylistItem(ctypes.Structure):
176 ('id', ctypes.c_int),
177 ('uri', ctypes.c_char_p),
178 ('name', ctypes.c_char_p),
182 return "PlaylistItem #%d %s (%uri)" % (self.id, self.name, self.uri)
184 class LogMessage(ctypes.Structure):
186 ('size', ctypes.c_uint),
187 ('severity', ctypes.c_int),
188 ('type', ctypes.c_char_p),
189 ('name', ctypes.c_char_p),
190 ('header', ctypes.c_char_p),
191 ('message', ctypes.c_char_p),
195 super(LogMessage, self).__init__()
196 self.size=ctypes.sizeof(self)
199 return "vlc.LogMessage(%d:%s): %s" % (self.severity, self.type, self.message)
201 class MediaControlPosition(ctypes.Structure):
203 ('origin', PositionOrigin),
204 ('key', PositionKey),
205 ('value', ctypes.c_longlong),
208 def __init__(self, value=0, origin=None, key=None):
209 # We override the __init__ method so that instanciating the
210 # class with an int as parameter will create the appropriate
211 # default position (absolute position, media time, with the
213 super(MediaControlPosition, self).__init__()
216 origin=PositionOrigin.AbsolutePosition
218 key=PositionKey.MediaTime
223 return "MediaControlPosition %ld (%s, %s)" % (
231 if isinstance(arg, (int, long)):
232 return MediaControlPosition(arg)
236 class MediaControlException(ctypes.Structure):
238 ('code', ctypes.c_int),
239 ('message', ctypes.c_char_p),
242 mediacontrol_exception_init(self)
245 mediacontrol_exception_free(self)
247 class MediaControlStreamInformation(ctypes.Structure):
249 ('status', PlayerStatus),
250 ('url', ctypes.c_char_p),
251 ('position', ctypes.c_longlong),
252 ('length', ctypes.c_longlong),
256 return "%s (%s) : %ld / %ld" % (self.url or "<No defined URL>",
261 class RGBPicture(ctypes.Structure):
263 ('width', ctypes.c_int),
264 ('height', ctypes.c_int),
265 ('type', ctypes.c_uint32),
266 ('date', ctypes.c_ulonglong),
267 ('size', ctypes.c_int),
268 ('data_pointer', ctypes.c_void_p),
273 return ctypes.string_at(self.data_pointer, self.size)
276 return "RGBPicture (%d, %d) - %ld ms - %d bytes" % (self.width, self.height, self.date, self.size)
279 mediacontrol_RGBPicture__free(self)
281 def check_vlc_exception(result, func, args):
282 """Error checking method for functions using an exception in/out parameter.
285 if not isinstance(ex, (VLCException, MediaControlException)):
286 logging.warn("python-vlc: error when processing function %s. Please report this as a bug to vlc-devel@videolan.org" % str(func))
288 # Take into account both VLCException and MediacontrolException:
289 c=getattr(ex, 'raised', getattr(ex, 'code', 0))
291 raise LibVLCException(ex.message)
294 ### End of header.py ###