Tuesday 6 June 2017

Node.js c++ addon async librarary(libvlc) callback segmentation fault

I'm triing to create wrapper for libvlc for node.js (most of them are deprecated). LibLVC generaate it's events asynchronously, but if I try to call js callback in such event, it encounter segmentation fault. I found sollutions for libuv and Nan's AsyncWorker but neither can help.

Segmentation fault happends in function on_media_player_end_reached on Nan::MakeCallback(Nan::GetCurrentContext()->Global(), Nan::New(_cb), 0, 0);.

#include <node.h>
#include <nan.h>
#include <vlc/vlc.h>

namespace libvlc {

    using v8::Handle;
    using v8::Persistent;
    using v8::Function;
    using v8::FunctionCallbackInfo;
    using v8::Isolate;
    using v8::Local;
    using v8::Object;
    using v8::String;
    using v8::Value;
    using v8::Context;
    using v8::Primitive;
    using node::AtExit;

    int isPlaying = 1;

    libvlc_instance_t *inst;
    libvlc_media_player_t *mp;
    libvlc_media_t *m;
    libvlc_event_manager_t *evm;

    void Play(const FunctionCallbackInfo <Value> &args) {
        v8::String::Utf8Value str(args[0]->ToString());
        char *link = (char*) *str;

        m = libvlc_media_new_location(inst, link);
        libvlc_media_player_set_media(mp, m);
        libvlc_media_release(m);
        libvlc_media_player_play (mp);
    }

    static Nan::CopyablePersistentTraits<v8::Function>::CopyablePersistent _cb;

    void on_media_player_end_reached(const libvlc_event_t*, void *data) {
        Nan::MakeCallback(Nan::GetCurrentContext()->Global(), Nan::New(_cb), 0, 0);
        _cb.Reset();
    }

    void OnMediaPlayerEndReached(const Nan::FunctionCallbackInfo<Value> &args) {
        _cb = Nan::Persistent<Function>(args[0].As<Function>());
        libvlc_event_attach(evm, libvlc_MediaPlayerEndReached, on_media_player_end_reached, NULL);
    }

    void release_vlc(void *) {
        libvlc_media_player_release(mp);
        libvlc_release(inst);
    }

    void init(Local <Object> exports) {
        char const *vlc_argv[] = {"--no-video"};
        inst = libvlc_new(1, vlc_argv);
        mp = libvlc_media_player_new(inst);
        evm = libvlc_media_player_event_manager(mp);

        NODE_SET_METHOD(exports, "play", Play);
        Nan::SetMethod(exports, "onMediaPlayerEndReached", OnMediaPlayerEndReached);

        AtExit(release_vlc);
    }

    NODE_MODULE(libvlc, init)
}



via tino415

No comments:

Post a Comment