Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
vlc-2-2
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Redmine
Redmine
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
videolan
vlc-2-2
Commits
f83867bb
Commit
f83867bb
authored
Jul 30, 2009
by
Olivier Aubert
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
New python bindings, using ctypes, automatically generated from include files.
parent
c3f18518
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
715 additions
and
0 deletions
+715
-0
bindings/python-ctypes/Makefile
bindings/python-ctypes/Makefile
+12
-0
bindings/python-ctypes/README
bindings/python-ctypes/README
+52
-0
bindings/python-ctypes/TODO
bindings/python-ctypes/TODO
+11
-0
bindings/python-ctypes/generate.py
bindings/python-ctypes/generate.py
+448
-0
bindings/python-ctypes/header.py
bindings/python-ctypes/header.py
+161
-0
bindings/python-ctypes/override.py
bindings/python-ctypes/override.py
+31
-0
No files found.
bindings/python-ctypes/Makefile
0 → 100644
View file @
f83867bb
MODULE_NAME
=
vlc.py
all
:
$(MODULE_NAME)
$(MODULE_NAME)
:
generate.py header.py override.py ../../include/vlc/*.h
./generate.py ../../include/vlc/
*
.h
>
$@
doc
:
$(MODULE_NAME)
-
epydoc
-v
-o
doc
$<
clean
:
-
$(RM)
$(MODULE_NAME)
bindings/python-ctypes/README
0 → 100644
View file @
f83867bb
* Python ctypes-based bindings
The bindings use ctypes to directly call the libvlc dynamic lib, and
the code is generated from the include files defining the public API.
** Building
To generate the vlc.py module and its documentation, use
make
Documentation building needs epydoc.
** Layout
The module offers two ways of accessing the API - a raw access to all
exported methods, and more convenient wrapper classes :
- Raw access: methods are available as attributes of the vlc
module. Use their docstring (introspective shells like ipython are
your friends) to explore them.
- Wrapper classes: most major structures of the libvlc API (Instance,
Media, MediaPlayer, etc) are wrapped as classes, with shorter method
names.
** Using the module
On win32, the simplest way is to put the vlc.py file in the same
directory as the libvlc.dll file (standard location:
c:\Program Files\VideoLAN\VLC ).
- Using raw access:
>>> import vlc
>>> vlc.libvlc_get_version()
'1.0.0 Goldeneye'
>>> e=vlc.VLCException()
>>> i=vlc.libvlc_new(0, [], e)
>>> i
<vlc.Instance object at 0x8384a4c>
>>> vlc.libvlc_audio_get_volume(i,e)
50
- Using wrapper classes:
>>> i=vlc.Instance.new()
>>> i.audio_get_volume()
50
>>> m=i.media_new('/tmp/foo.avi')
>>> m.get_mrl()
'/tmp/foo.avi'
bindings/python-ctypes/TODO
0 → 100644
View file @
f83867bb
* Check cross-platform (win32, MacOSX) support
* Investigate memory management
* Find how to properly define enums
* Autogenerate enums from include files
* Implement event callbacks
* Write a test suite
bindings/python-ctypes/generate.py
0 → 100755
View file @
f83867bb
#! /usr/bin/python
debug
=
False
#
# Code generator for python ctypes bindings for VLC
# Copyright (C) 2009 the VideoLAN team
# $Id: $
#
# Authors: Olivier Aubert <olivier.aubert at liris.cnrs.fr>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
#
"""This module parses VLC public API include files and generates
corresponding python/ctypes code. Moreover, it generates class
wrappers for most methods.
"""
import
sys
import
re
import
time
import
operator
import
itertools
# DefaultDict from ASPN python cookbook
import
copy
class
DefaultDict
(
dict
):
"""Dictionary with a default value for unknown keys."""
def
__init__
(
self
,
default
=
None
,
**
items
):
dict
.
__init__
(
self
,
**
items
)
self
.
default
=
default
def
__getitem__
(
self
,
key
):
if
key
in
self
:
return
self
.
get
(
key
)
else
:
## Need copy in case self.default is something like []
return
self
.
setdefault
(
key
,
copy
.
deepcopy
(
self
.
default
))
def
__copy__
(
self
):
return
DefaultDict
(
self
.
default
,
**
self
)
# Methods not decorated/not referenced
blacklist
=
[
"libvlc_exception_raise"
,
"libvlc_exception_raised"
,
"libvlc_exception_get_message"
,
"libvlc_get_vlc_instance"
,
"libvlc_media_add_option_flag"
,
"libvlc_media_list_view_index_of_item"
,
"libvlc_media_list_view_insert_at_index"
,
"libvlc_media_list_view_remove_at_index"
,
"libvlc_media_list_view_add_item"
,
# In svn but not in current 1.0.0
'libvlc_video_set_deinterlace'
,
'libvlc_video_get_marquee_option_as_int'
,
'libvlc_video_get_marquee_option_as_string'
,
'libvlc_video_set_marquee_option_as_int'
,
'libvlc_video_set_marquee_option_as_string'
,
'libvlc_vlm_get_event_manager'
,
'mediacontrol_PlaylistSeq__free'
,
# TODO
"libvlc_event_detach"
,
"libvlc_event_attach"
,
]
# Precompiled regexps
api_re
=
re
.
compile
(
'VLC_PUBLIC_API
\
s+(
\
S+
\
s+.+?)
\
s*
\
(
\
s*(.+?)
\
s*
\
)'
)
param_re
=
re
.
compile
(
'
\
s*(co
n
st
\
s*|u
n
signed
\
s*|s
t
ruct
\
s*)?(
\
S+
\
s*
\
**)
\
s+(.+)
'
)
paramlist_re=re.compile('
\
s
*
,
\
s
*
')
comment_re=re.compile('
\\
param
\
s
+
(
\
S
+
)
')
python_param_re=re.compile('
(
@
param
\
s
+
\
S
+
)(.
+
)
')
forward_re=re.compile('
.
+
\
(
\
s
*
(.
+
?
)
\
s
*
\
)(
\
s
*
\
S
+
)
')
# Definition of parameter passing mode for types. This should not be
# hardcoded this way, but works alright ATM.
parameter_passing=DefaultDict(default=1)
parameter_passing['
libvlc_exception_t
*
']=3
# C-type to ctypes/python type conversion
typ2class={
'
libvlc_exception_t
*
': '
ctypes
.
POINTER
(
VLCException
)
',
'
libvlc_media_player_t
*
': '
MediaPlayer
',
'
libvlc_instance_t
*
': '
Instance
',
'
libvlc_media_t
*
': '
Media
',
'
libvlc_log_t
*
': '
Log
',
'
libvlc_log_iterator_t
*
': '
LogIterator
',
'
libvlc_log_message_t
*
': '
LogMessage
',
'
libvlc_event_type_t
': '
EventType
',
'
libvlc_event_manager_t
*
': '
EventManager
',
'
libvlc_media_discoverer_t
*
': '
MediaDiscoverer
',
'
libvlc_media_library_t
*
': '
MediaLibrary
',
'
libvlc_media_list_t
*
': '
MediaList
',
'
libvlc_media_list_player_t
*
': '
MediaListPlayer
',
'
libvlc_media_list_view_t
*
': '
MediaListView
',
'
libvlc_track_description_t
*
': '
TrackDescription
',
'
libvlc_audio_output_t
*
': '
AudioOutput
',
'
mediacontrol_Instance
*
': '
MediaControl
',
'
mediacontrol_Exception
*
': '
MediaControlException
',
'
mediacontrol_RGBPicture
*
': '
RGBPicture
',
'
mediacontrol_PlaylistSeq
*
': '
MediaControlPlaylistSeq
',
'
mediacontrol_Position
*
': '
MediaControlPosition
',
'
mediacontrol_StreamInformation
*
': '
MediaControlStreamInformation
',
'
mediacontrol_PositionOrigin
': '
ctypes
.
c_uint
',
'
mediacontrol_PositionKey
': '
ctypes
.
c_uint
',
'
WINDOWHANDLE
': '
ctypes
.
c_ulong
',
'
short
': '
ctypes
.
c_short
',
'
char
*
': '
ctypes
.
c_char_p
',
'
char
**
': '
ListPOINTER
(
ctypes
.
c_char_p
)
',
'
uint32_t
': '
ctypes
.
c_uint
',
'
float
': '
ctypes
.
c_float
',
'
unsigned
': '
ctypes
.
c_uint
',
'
void
': '
None
',
'
void
*
': '
ctypes
.
c_void_p
',
'
int
': '
ctypes
.
c_int
',
'
...
': '
FIXMEva_list
',
'
libvlc_callback_t
': '
FIXMEcallback
',
'
libvlc_time_t
': '
ctypes
.
c_longlong
',
'
libvlc_video_marquee_int_option_t
': '
ctypes
.
c_int
',
'
libvlc_video_marquee_string_option_t
': '
ctypes
.
c_char_p
',
# FIXME: enums -> to be processed
'
libvlc_media_option_t
': '
ctypes
.
c_uint
',
'
libvlc_meta_t
': '
ctypes
.
c_uint
',
'
libvlc_state_t
': '
State
',
}
# Defined python classes, i.e. classes for which we want to generate
# class wrappers around libvlc functions
defined_classes=(
'
MediaPlayer
',
'
Instance
',
'
Media
',
'
Log
',
'
LogIterator
',
#'
LogMessage
',
'
EventType
',
'
EventManager
',
'
MediaDiscoverer
',
'
MediaLibrary
',
'
MediaList
',
'
MediaListPlayer
',
'
MediaListView
',
'
TrackDescription
',
'
AudioOutput
',
'
MediaControl
',
#'
RGBPicture
',
#'
MediaControlPosition
',
#'
MediaControlStreamInformation
',
)
# Definition of prefixes that we can strip from method names when
# wrapping them into class methods
prefixes=dict( (v, k[:-2]) for (k, v) in typ2class.iteritems() if v in defined_classes )
prefixes['
MediaControl
']='
mediacontrol_
'
def parse_param(s):
"""Parse a C parameter expression.
It is used to parse both the type/name for methods, and type/name
for their parameters.
It returns a tuple (type, name).
"""
s=s.strip()
s=s.replace('
const
', '')
if '
VLC_FORWARD
' in s:
m=forward_re.match(s)
s=m.group(1)+m.group(2)
m=param_re.search(s)
if m:
const, typ, name=m.groups()
while name.startswith('
*
'):
typ += '
*
'
name=name[1:]
if name == '
const
*
':
# K&R definition: const char * const*
name=''
typ=typ.replace('
', '')
return typ, name
else:
# K&R definition: only type
return s.replace('
', ''), ''
def generate_header(classes=None):
"""Generate header code.
"""
f=open('
header
.
py
', 'r')
for l in f:
if '
build_date
' in l:
print '
build_date
=
"%s"' % time.ctime()
else:
print l,
f.close()
def parse_include(name):
"""Parse include file.
This generates a tuple for each function:
(return_type, method_name, parameter_list, comment)
with parameter_list being a list of tuples (parameter_type, parameter_name).
"""
f=open(name, 'r')
accumulator=''
comment=''
for l in f:
# Note: lstrip() should not be necessary, but there is 1 badly
# formatted comment in vlc1.0.0 includes
if l.lstrip().startswith('
/**
'):
comment=''
continue
elif l.startswith('
*
'):
comment = comment + l[3:]
continue
l=l.strip()
if accumulator:
accumulator=" ".join( (accumulator, l) )
if l.endswith('
);
'):
# End of definition
l=accumulator
accumulator=''
elif l.startswith('
VLC_PUBLIC_API
') and not l.endswith('
);
'):
# Multiline definition. Accumulate until end of definition
accumulator=l
continue
m=api_re.match(l)
if m:
(ret, param)=m.groups()
rtype, method=parse_param(ret)
params=[]
for p in paramlist_re.split(param):
params.append( parse_param(p) )
if len(params) == 1 and params[0][0] == '
void
':
# Empty parameter list
params=[]
if list(p for p in params if not p[1]):
# Empty parameter names. Have to poke into comment.
names=comment_re.findall(comment)
if len(names) < len(params):
# Bad description: all parameters are not specified.
# Generate default parameter names
badnames=[ "param%d" % i for i in xrange(len(params)) ]
# Put in the existing ones
for (i, p) in enumerate(names):
badnames[i]=names[i]
names=badnames
print "### Error ###"
print "### Cannot get parameter names from comment for %s: %s" % (method, comment.replace("
\
n
", '
'))
# Note: this was previously
# raise Exception("Cannot get parameter names from comment for %s: %s" % (method, comment))
# but it prevented code generation for a minor detail (some bad descriptions).
params=[ (p[0], names[i]) for (i, p) in enumerate(params) ]
for typ, name in params:
if not typ in typ2class:
raise Exception("No conversion for %s (from %s:%s)" % (typ, method, name))
# Transform Doxygen syntax into epydoc syntax
comment=comment.replace('
\\
param
', '
@
param
').replace('
\\
return
', '
@
return
')
if debug:
print '
********************
'
print l
print '
-------->
'
print "%s (%s)" % (method, rtype)
for typ, name in params:
print " %s (%s)" % (name, typ)
print '
********************
'
yield (rtype,
method,
params,
comment)
def output_ctypes(rtype, method, params, comment):
"""Output ctypes decorator for the given method.
"""
if method in blacklist:
# FIXME
return
if params:
print "prototype=ctypes.CFUNCTYPE(%s, %s)" % (typ2class.get(rtype, '
FIXME_
%
s
' % rtype),
",".join( typ2class[p[0]] for p in params ))
else:
print "prototype=ctypes.CFUNCTYPE(%s)" % typ2class.get(rtype, '
FIXME_
%
s
' % rtype)
if not params:
flags='
paramflags
=
tuple
()
'
elif len(params) == 1:
flags="paramflags=( (%d, ), )" % parameter_passing[params[0][0]]
else:
flags="paramflags=%s" % ",".join( '
(
%
d
,)
' % parameter_passing[p[0]] for p in params )
print flags
print '
%
s
=
prototype
(
(
"%s"
,
dll
),
paramflags
)
' % (method, method)
if '
3
' in flags:
# A VLCException is present. Process it.
print "%s.errcheck = check_vlc_exception" % method
print '
%
s
.
__doc__
=
"""%s"""' % (method, comment)
print
def parse_override(name):
"""Parse override definitions file.
It is possible to override methods definitions in classes.
"""
res={}
data=[]
current=None
f=open(name, 'r')
for l in f:
m=re.match('
class
(\
S
+
):
', l)
if m:
# Dump old data
if current is not None:
res[current]="
\
n
".join(data)
current=m.group(1)
data=[]
continue
data.append(l)
res[current]="
\
n
".join(data)
f.close()
return res
def fix_python_comment(c):
"""Fix comment by removing first and last parameters (self and exception)
"""
data=c.splitlines()
body=itertools.takewhile(lambda l: not '
@
param
' in l, data)
param=[ python_param_re.sub('
\\
1
:
\\
2
', l) for l in itertools.ifilter(lambda l: '
@
param
' in l, data) ]
ret=[ l.replace('
@
return
', '
@
return
:
') for l in itertools.ifilter(lambda l: '
@
return
' in l, data) ]
if len(param) >= 2:
param=param[1:-1]
elif len(param) == 1:
param=[]
return "
\
n
".join(itertools.chain(body, param, ret))
def generate_wrappers(methods):
"""Generate class wrappers for all appropriate methods.
@return: the set of wrapped method names
"""
ret=set()
# Sort methods against the element they apply to.
elements=sorted( ( (typ2class.get(params[0][0]), rt, met, params, c)
for (rt, met, params, c) in methods
if params and typ2class.get(params[0][0], '
_
') in defined_classes
),
key=operator.itemgetter(0))
overrides=parse_override('
override
.
py
')
for classname, el in itertools.groupby(elements, key=operator.itemgetter(0)):
print """
class %(name)s(object):
def __init__(self, pointer=None):
'''Internal method used for instanciating wrappers from ctypes.
'''
if pointer is None:
raise Exception("Internal method. You should instanciate objects through other class methods (probably named '
new
' or ending with '
new
')")
self._as_parameter_=ctypes.c_void_p(pointer)
@staticmethod
def from_param(arg):
'''(INTERNAL) ctypes parameter conversion method.
'''
return arg._as_parameter_
""" % {'
name
': classname}
if classname in overrides:
print overrides[classname]
prefix=prefixes.get(classname, '')
for cl, rtype, method, params, comment in el:
if method in blacklist:
continue
# Strip prefix
name=method.replace(prefix, '').replace('
libvlc_
', '')
ret.add(method)
if params:
params[0]=(params[0][0], '
self
')
if params and params[-1][0] in ('
libvlc_exception_t
*
', '
mediacontrol_Exception
*
'):
args=", ".join( p[1] for p in params[:-1] )
else:
args=", ".join( p[1] for p in params )
print " def %s(%s):" % (name, args)
print '
"""%s
\
n
"""' % fix_python_comment(comment)
if params and params[-1][0] == '
libvlc_exception_t
*
':
# Exception handling
print " e=VLCException()"
print " return %s(%s, e)" % (method, args)
elif params and params[-1][0] == '
mediacontrol_Exception
*
':
# Exception handling
print " e=MediaControlException()"
print " return %s(%s, e)" % (method, args)
else:
print " return %s(%s)" % (method, args)
print
return ret
if __name__ == '
__main__
':
methods=[]
for name in sys.argv[1:]:
methods.extend(list(parse_include(name)))
if debug:
sys.exit(0)
generate_header()
wrapped=generate_wrappers(methods)
for l in methods:
output_ctypes(*l)
all=set( t[1] for t in methods )
not_wrapped=all.difference(wrapped)
print "# Not wrapped methods:"
for m in not_wrapped:
print "# ", m
bindings/python-ctypes/header.py
0 → 100755
View file @
f83867bb
#! /usr/bin/python
#
# Python ctypes bindings for VLC
# Copyright (C) 2009 the VideoLAN team
# $Id: $
#
# Authors: Olivier Aubert <olivier.aubert at liris.cnrs.fr>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
#
import
ctypes
import
sys
build_date
=
"This will be replaced by the build date"
if
sys
.
platform
==
'linux2'
:
dll
=
ctypes
.
CDLL
(
'libvlc.so'
)
elif
sys
.
platform
==
'win32'
:
dll
=
ctypes
.
CDLL
(
'libvlc.dll'
)
elif
sys
.
platform
==
'darwin'
:
# FIXME: should find a means to configure path
dll
=
ctypes
.
CDLL
(
'/Applications/VLC.app/Contents/MacOS/lib/libvlc.2.dylib'
)
class
ListPOINTER
(
object
):
'''Just like a POINTER but accept a list of ctype as an argument.
'''
def
__init__
(
self
,
etype
):
self
.
etype
=
etype
def
from_param
(
self
,
param
):
if
isinstance
(
param
,
(
list
,
tuple
)):
return
(
self
.
etype
*
len
(
param
))(
*
param
)
# 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
)
class
PlaylistItem
(
ctypes
.
Structure
):
_fields_
=
[
(
'id'
,
ctypes
.
c_int
),
(
'uri'
,
ctypes
.
c_char_p
),
(
'name'
,
ctypes
.
c_char_p
),
]
class
LogMessage
(
ctypes
.
Structure
):
_fields_
=
[
(
'size'
,
ctypes
.
c_uint
),
(
'severity'
,
ctypes
.
c_int
),
(
'type'
,
ctypes
.
c_char_p
),
(
'name'
,
ctypes
.
c_char_p
),
(
'header'
,
ctypes
.
c_char_p
),
(
'message'
,
ctypes
.
c_char_p
),
]
class
MediaControlPosition
(
ctypes
.
Structure
):
_fields_
=
[
(
'origin'
,
ctypes
.
c_ushort
),
(
'key'
,
ctypes
.
c_ushort
),
(
'value'
,
ctypes
.
c_longlong
),
]
@
staticmethod
def
from_param
(
arg
):
if
isinstance
(
arg
,
(
int
,
long
)):
p
=
MediaControlPosition
()
p
.
value
=
arg
p
.
key
=
2
return
p
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
),
(
'message'
,
ctypes
.
c_char_p
),
]
def
init
(
self
):
mediacontrol_exception_init
(
self
)
def
clear
(
self
):
mediacontrol_exception_free
(
self
)
class
MediaControlStreamInformation
(
ctypes
.
Structure
):
_fields_
=
[
(
'code'
,
ctypes
.
c_int
),
(
'message'
,
ctypes
.
c_char_p
),
]
class
RGBPicture
(
ctypes
.
Structure
):
_fields_
=
[
(
'width'
,
ctypes
.
c_int
),
(
'height'
,
ctypes
.
c_int
),
(
'type'
,
ctypes
.
c_uint32
),
(
'date'
,
ctypes
.
c_longlong
),
(
'size'
,
ctypes
.
c_int
),
(
'data'
,
ctypes
.
c_char_p
),
]
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
c
=
getattr
(
ex
,
'raised'
,
getattr
(
ex
,
'code'
,
0
))
if
c
:
raise
Exception
(
args
[
-
1
].
message
)
return
result
bindings/python-ctypes/override.py
0 → 100644
View file @
f83867bb
class
Instance
:
@
staticmethod
def
new
(
*
p
):
"""Create a new Instance.
"""
e
=
VLCException
()
return
libvlc_new
(
len
(
p
),
p
,
e
)
class
MediaControl
:
@
staticmethod
def
new
(
*
p
):
"""Create a new MediaControl
"""
e
=
MediaControlException
()
return
mediacontrol_new
(
len
(
p
),
p
,
e
)
@
staticmethod
def
new_from_instance
(
i
):
"""Create a new MediaControl from an existing Instance.
"""
e
=
MediaControlException
()
return
mediacontrol_new_from_instance
(
i
,
e
)
class
MediaList
:
def
__len__
(
self
):
e
=
VLCException
()
return
libvlc_media_list_count
(
self
,
e
)
def
__getitem__
(
self
,
i
):
e
=
VLCException
()
return
libvlc_media_list_item_at_index
(
self
,
i
,
e
)
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment