# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
#
+"""This module provides bindings for the
+U{libvlc<http://wiki.videolan.org/ExternalAPI>} and
+U{MediaControl<http://wiki.videolan.org/MediaControlAPI>} APIs.
+
+You can find documentation at U{http://www.advene.org/download/python-ctypes/}.
+
+Basically, the most important class is L{Instance}, which is used to
+create a libvlc Instance. From this instance, you can then create
+L{MediaPlayer} and L{MediaListPlayer} instances.
+"""
+
import ctypes
import sys
if sys.platform == 'linux2':
dll=ctypes.CDLL('libvlc.so')
elif sys.platform == 'win32':
- dll=ctypes.CDLL('libvlc.dll')
+ import ctypes.util
+ import os
+ plugin_path=None
+ path=ctypes.util.find_library('libvlc.dll')
+ if path is None:
+ # Try to use registry settings
+ import _winreg
+ plugin_path_found = None
+ subkey, name = 'Software\\VideoLAN\\VLC','InstallDir'
+ for hkey in _winreg.HKEY_LOCAL_MACHINE, _winreg.HKEY_CURRENT_USER:
+ try:
+ reg = _winreg.OpenKey(hkey, subkey)
+ plugin_path_found, type_id = _winreg.QueryValueEx(reg, name)
+ _winreg.CloseKey(reg)
+ break
+ except _winreg.error:
+ pass
+ if plugin_path_found:
+ plugin_path = plugin_path_found
+ else:
+ # Try a standard location.
+ p='c:\\Program Files\\VideoLAN\\VLC\\libvlc.dll'
+ if os.path.exists(p):
+ plugin_path=os.path.dirname(p)
+ os.chdir(plugin_path)
+ # If chdir failed, this will not work and raise an exception
+ path='libvlc.dll'
+ else:
+ plugin_path=os.path.dirname(path)
+ dll=ctypes.CDLL(path)
elif sys.platform == 'darwin':
# FIXME: should find a means to configure path
dll=ctypes.CDLL('/Applications/VLC.app/Contents/MacOS/lib/libvlc.2.dylib')
if isinstance(param, (list,tuple)):
return (self.etype * len(param))(*param)
+class LibVLCException(Exception):
+ """Python exception raised by libvlc methods.
+ """
+ pass
+
# From libvlc_structures.h
-class VLCException(ctypes.Structure):
- _fields_= [
- ('raised', ctypes.c_int),
- ('code', ctypes.c_int),
- ('message', ctypes.c_char_p),
- ]
- def init(self):
- libvlc_exception_init(self)
- def clear(self):
- libvlc_exception_clear(self)
+# This is version-dependent, depending on the presence of libvlc_exception_get_message.
+
+if hasattr(dll, 'libvlc_exception_get_message'):
+ # New-style message passing
+ class VLCException(ctypes.Structure):
+ """libvlc exception.
+ """
+ _fields_= [
+ ('raised', ctypes.c_int),
+ ]
+
+ @property
+ def message(self):
+ return dll.libvlc_exception_get_message()
+
+ def init(self):
+ libvlc_exception_init(self)
+
+ def clear(self):
+ libvlc_exception_clear(self)
+else:
+ # Old-style exceptions
+ class VLCException(ctypes.Structure):
+ """libvlc exception.
+ """
+ _fields_= [
+ ('raised', ctypes.c_int),
+ ('code', ctypes.c_int),
+ ('message', ctypes.c_char_p),
+ ]
+ def init(self):
+ libvlc_exception_init(self)
+
+ def clear(self):
+ libvlc_exception_clear(self)
class PlaylistItem(ctypes.Structure):
_fields_= [
('name', ctypes.c_char_p),
]
+ def __str__(self):
+ return "PlaylistItem #%d %s (%uri)" % (self.id, self.name, self.uri)
+
class LogMessage(ctypes.Structure):
_fields_= [
('size', ctypes.c_uint),
('message', ctypes.c_char_p),
]
+ def __str__(self):
+ return "vlc.LogMessage(%d:%s): %s" % (self.severity, self.type, self.message)
+
class MediaControlPosition(ctypes.Structure):
_fields_= [
- ('origin', ctypes.c_ushort),
- ('key', ctypes.c_ushort),
+ ('origin', ctypes.c_int),
+ ('key', ctypes.c_int),
('value', ctypes.c_longlong),
]
+ def __str__(self):
+ return "MediaControlPosition %ld (%s, %s)" % (
+ self.value,
+ str(PositionOrigin(self.origin)),
+ str(PositionKey(self.key))
+ )
+
@staticmethod
def from_param(arg):
if isinstance(arg, (int, long)):
else:
return arg
-class MediaControlPositionOrigin(ctypes.c_uint):
- enum=(
- 'AbsolutePosition',
- 'RelativePosition',
- 'ModuloPosition',
- )
- def __repr__(self):
- return self.enum[self.value]
-
-class State(ctypes.c_uint):
- # FIXME: should be improved (State.NothingSpecial should hold the value)
- # and maybe auto-generated from typedefs
- enum=(
- 'NothingSpecial',
- 'Opening',
- 'Buffering',
- 'Playing',
- 'Paused',
- 'Stopped',
- 'Ended',
- 'Error',
- )
- def __repr__(self):
- return self.enum[self.value]
-
class MediaControlException(ctypes.Structure):
_fields_= [
('code', ctypes.c_int),
class MediaControlStreamInformation(ctypes.Structure):
_fields_= [
- ('code', ctypes.c_int),
- ('message', ctypes.c_char_p),
+ ('status', ctypes.c_int),
+ ('url', ctypes.c_char_p),
+ ('position', ctypes.c_longlong),
+ ('length', ctypes.c_longlong),
]
+ def __str__(self):
+ return "%s (%s) : %ld / %ld" % (self.url,
+ str(PlayerStatus(self.status)),
+ self.position,
+ self.length)
+
class RGBPicture(ctypes.Structure):
_fields_= [
('width', ctypes.c_int),
('height', ctypes.c_int),
('type', ctypes.c_uint32),
- ('date', ctypes.c_longlong),
+ ('date', ctypes.c_ulonglong),
('size', ctypes.c_int),
- ('data', ctypes.c_char_p),
+ ('data_pointer', ctypes.c_void_p),
]
+ @property
+ def data(self):
+ return ctypes.string_at(self.data_pointer, self.size)
+
+ def __str__(self):
+ return "RGBPicture (%d, %d) - %ld ms - %d bytes" % (self.width, self.height, self.date, self.size)
+
def free(self):
mediacontrol_RGBPicture__free(self)
-# Decorator for callback methods
-callbackmethod=ctypes.CFUNCTYPE(None, ctypes.c_void_p, ctypes.c_void_p)
-
def check_vlc_exception(result, func, args):
"""Error checking method for functions using an exception in/out parameter.
"""
ex=args[-1]
- # Take into account both VLCException and MediacontrolException
+ # Take into account both VLCException and MediacontrolException:
c=getattr(ex, 'raised', getattr(ex, 'code', 0))
if c:
- raise Exception(args[-1].message)
+ raise LibVLCException(args[-1].message)
return result
+
+### End of header.py ###