@@ -7,6 +7,7 @@ class Instance:
77 - a list of strings as first parameters
88 - the parameters given as the constructor parameters (must be strings)
99 """
10+
1011 def __new__ (cls , * args ):
1112 if len (args ) == 1 :
1213 # Only 1 arg. It is either a C pointer, or an arg string,
@@ -142,6 +143,52 @@ def video_filter_list_get(self):
142143 """
143144 return module_description_list (libvlc_video_filter_list_get (self ))
144145
146+ def set_logger (self , logger , max_log_message_size = 4096 ):
147+ """Links a logging.Logger object to the libVLC Instance
148+
149+ Along with the log level and message, each libVLC log will also include
150+ The following extra info:
151+ - vlc_module: the name of the VLC module (str).
152+ - file: the VLC source filename (str).
153+ - line: the VLC source file line number (int).
154+ These variables can be used in the logger formatter.
155+
156+ @param logger: a logging.Logger object
157+ @param max_log_message_size: defines the maximum size that will be
158+ copied from VLC log messages. If you experience truncated log
159+ messages, raise this number (default 4096).
160+ """
161+ # libVLC provides the log message through a printf format + va_list.
162+ # Unfortunately, there is no simple way to use a
163+ # printf format + va_list in Python outside of the use of a C format
164+ # function.
165+ # As there is no guarantee to have access to a C `vasprintf`, we use
166+ # `vsnprintf` with a log message max size.
167+ libc = find_libc ()
168+ self ._vsnprintf = libc .vsnprintf
169+ self ._max_log_message_size = max_log_message_size
170+ self ._logger = logger
171+ # The log_handler is meant to be the "real" callback for libvlc_log_set().
172+ @CallbackDecorators .LogCb
173+ def log_handler (instance , log_level , ctx , fmt , va_list ):
174+ bufferString = ctypes .create_string_buffer (self ._max_log_message_size )
175+ self ._vsnprintf (bufferString , self ._max_log_message_size , fmt ,
176+ ctypes .cast (va_list , ctypes .c_void_p ))
177+ msg = bufferString .value .decode ('utf-8' )
178+ module , file , line = libvlc_log_get_context (ctx )
179+ module = module .decode ('utf-8' )
180+ file = file .decode ('utf-8' )
181+ self ._logger .log (loglevel_to_logging (LogLevel (log_level )),
182+ msg , extra = {"vlc_module" : module , "file" : file , "line" : line })
183+ # We need to keep a reference to the log_handler function that persists
184+ # after the end of the set_logger.
185+ # If we do not do that, there is a (high) chance the python garbage
186+ # collector will destroy the callback function and produce segfault in
187+ # libVLC.
188+ # To avoid that, link the log_handler lifetime to the Instance's one.
189+ self ._log_handler = log_handler
190+ self .log_set (self ._log_handler , None )
191+
145192class Media :
146193 """Create a new Media instance.
147194
0 commit comments