oaubert / python-vlc

Python vlc bindings
GNU Lesser General Public License v2.1
387 stars 111 forks source link

Call libvlc_log_get_context invoke exception. #25

Open fingul opened 7 years ago

fingul commented 7 years ago

Thanks for great app.

When call libvlc_log_get_context invoke exception.

I think, in below line, ListPOINTER must be replaced with ctypes.POINTER.

https://github.com/oaubert/python-vlc/blob/master/generated/vlc.py#L4363

Have a nice day!

oaubert commented 7 years ago

ListPOINTER is used to simplify passing a list of elements as parameters. I have some fixes in mind, but do you have a small test case that I could run against? It would help ensuring it works.

fingul commented 7 years ago

Here is some test case. Thanks!

on log callback handler, it need to use libc. I`ve test @ linux and macOS / python 3.6

import logging
import platform
import ctypes
import time
import vlc
from vlc import _Cfunction, _Cfunctions, Log_ptr

logging.basicConfig(level=logging.DEBUG)
libc = ctypes.cdll.LoadLibrary("libc.{}".format("so.6" if platform.uname()[0] != "Darwin" else "dylib"))

# https://github.com/oaubert/python-vlc/issues/25
def libvlc_log_get_context_patch(ctx):
    # patch of vlc.libvlc_log_get_context(ctx)
    f = _Cfunctions.get('libvlc_log_get_context', None) or \
        _Cfunction('libvlc_log_get_context', ((1,), (2,), (2,), (2,),), None,
                   None, Log_ptr, ctypes.POINTER(ctypes.c_char_p), ctypes.POINTER(ctypes.c_char_p),
                   ctypes.POINTER(ctypes.c_uint))
    return f(ctx)

@vlc.CallbackDecorators.LogCb
def log_handler(instance, log_level, ctx, fmt, va_list):
    bufferString = ctypes.create_string_buffer(4096)
    libc.vsprintf(bufferString, fmt, ctypes.cast(va_list, ctypes.c_void_p))
    msg = bufferString.value.decode('utf8')
    module, _file, _line = libvlc_log_get_context_patch(ctx)
    module = module.decode('utf8')
    logging.info(
        "log_level={log_level}, module={module}, msg={msg}".format(log_level=log_level, module=module, msg=msg))

@vlc.CallbackDecorators.LogCb
def log_handler_need_patch(instance, log_level, ctx, fmt, va_list):
    try:
        module, _file, _line = vlc.libvlc_log_get_context(ctx)
    except TypeError:
        logging.exception("vlc.libvlc_log_get_context(ctx)")

def test_callback(cb):
    url = 'rtmp://184.72.239.149/vod/BigBuckBunny_115k.mov'

    instance = vlc.Instance('--vout dummy --aout dummy')
    # instance.log_set(log_handler, None)
    instance.log_set(cb, None)
    player = instance.media_player_new()
    media = instance.media_new(url)
    player.set_media(media)
    player.play()
    time.sleep(3)

if __name__ == '__main__':
    test_callback(log_handler)
    # test_callback(log_handler_need_patch)
sovetov commented 5 years ago

Got the same issue with the latest version by now. Are there any changes it will be fixed?

For now, ended up with this:

_libvlc_log_get_context_type = ctypes.CFUNCTYPE(
    None, vlc.Log_ptr, ctypes.POINTER(ctypes.c_char_p),
    ctypes.POINTER(ctypes.c_char_p),
    ctypes.POINTER(ctypes.c_uint),
    )
_libvlc_log_get_context = _libvlc_log_get_context_type(
    ('libvlc_log_get_context', vlc.dll),
    ((1,), (2,), (2,), (2,),),
    )

Thank you, @fingul.

oaubert commented 5 years ago

It is half-fixed now: the correct type mapping is generated for the function. But the test function (disabled for now in the tests/test.py file) crashes after displaying some messages. If you manage to find the error, I will gladly merge the outcome.