Racket
Example of Racket ( https://racket-lang.org/ ) FFI. Racket is a programming language of the Lisp-Scheme family. I was surprised by how easy it was to get this working. The documentation is pretty good ( http://docs.racket-lang.org/foreign/intro.html )
#lang racket (require racket/gui/base) (require ffi/unsafe ffi/unsafe/define) ; Set libvlc location (define-ffi-definer define-vlc (ffi-lib "libvlc")) ; Define some libvlc types (define _libvlc_instance_t-pointer (_cpointer/null 'libvlc_instance_t)) (define _libvlc_media_player_t-pointer (_cpointer/null 'libvlc_media_player_t)) (define _libvlc_media_t-pointer (_cpointer/null 'libvlc_media_t)) (define _libvlc_time_t _int64) ; libvlc definitions (define-vlc libvlc_new (_fun _int (_list i _string) -> _libvlc_instance_t-pointer)) (define-vlc libvlc_release (_fun _libvlc_instance_t-pointer -> _void)) ; libvlc media_player definitions (define-vlc libvlc_media_player_new (_fun _libvlc_instance_t-pointer -> _libvlc_media_player_t-pointer)) (define-vlc libvlc_media_new_location (_fun _libvlc_instance_t-pointer _string -> _libvlc_media_t-pointer)) (define-vlc libvlc_media_new_path (_fun _libvlc_instance_t-pointer _string -> _libvlc_media_t-pointer)) (define-vlc libvlc_media_player_set_media (_fun _libvlc_media_player_t-pointer _libvlc_media_t-pointer -> _void)) (define-vlc libvlc_media_player_set_time (_fun _libvlc_media_player_t-pointer _libvlc_time_t -> _void)) (define-vlc libvlc_media_player_get_time (_fun _libvlc_media_player_t-pointer -> _libvlc_time_t )) (define-vlc libvlc_media_player_pause (_fun _libvlc_media_player_t-pointer -> _void)) (define-vlc libvlc_media_player_play (_fun _libvlc_media_player_t-pointer -> _int)) (define-vlc libvlc_media_player_stop (_fun _libvlc_media_player_t-pointer -> _void)) (define-vlc libvlc_media_player_release (_fun _libvlc_media_player_t-pointer -> _void)) (define (vlc-time-command media-player sign minutes seconds) (let ((current-time (libvlc_media_player_get_time media-player)) (arg-time-ms (* (+ seconds (* minutes 60)) 1000)) ) (match sign ["=" (libvlc_media_player_set_time media-player arg-time-ms)] ["+" (libvlc_media_player_set_time media-player (+ current-time arg-time-ms))] ["-" (libvlc_media_player_set_time media-player (- current-time arg-time-ms))] [_ 'nop] )) ) ; Make a frame by instantiating the frame% class (define frame (new frame% [label "Example"])) ; Make a static text message in the frame (define msg (new message% [parent frame] [label "No events so far..."] [auto-resize #t])) (define command-field ; Make a button in the frame (new text-field% [parent frame] [label "Command:"] ; Callback procedure for a button click: [callback (lambda (field event) (let ((text (send field get-value))) (match text ["p;" (send msg set-label "play/pause") (void (libvlc_media_player_pause media-player))] ["s;" (send msg set-label "stop") (void (libvlc_media_player_stop media-player))] ["q;" (void (libvlc_media_player_stop media-player)) (void (libvlc_media_player_release media-player)) (void (libvlc_release vlc)) (send msg set-label "quit...") (exit 0) ] ["o;" (let* ((path (get-file "")) (media (libvlc_media_new_path vlc path)) ) (if path (void (send msg set-label (~a "Path: " path)) (void (libvlc_media_player_set_media media-player media)) (void (libvlc_media_player_play media-player)) ) 'nop ) ) ] [(regexp #px"^[+-=]{1}\\d+:\\d+;") (let* ((groups (regexp-match #px"^([+-=]{1})(\\d+):(\\d+);" text)) (sign (second groups)) (minutes (string->number (third groups))) (seconds (string->number (fourth groups)))) (vlc-time-command media-player sign minutes seconds) (send msg set-label (~a sign minutes "minutes" "and" seconds "seconds" #:separator " ") )) ] [(regexp #px"^o(.+);") (let* ((groups (regexp-match #px"^o(.+);" text)) (path (second groups)) (media (libvlc_media_new_path vlc path)) ) (send msg set-label (~a "Path: " path)) (void (libvlc_media_player_set_media media-player media)) (void (libvlc_media_player_play media-player)) ) ] [_ 'nop]) ))]) ) ; Show the frame by calling its show method (send frame show #t) (define vlc (libvlc_new 0 '(""))) (define media-player (libvlc_media_player_new vlc)) (define big-buck-bunny-url "http://download.blender.org/peach/bigbuckbunny_movies/big_buck_bunny_480p_surround-fix.avi") (define media (libvlc_media_new_location vlc big-buck-bunny-url)) (void (libvlc_media_player_set_media media-player media)) (void (libvlc_media_player_play media-player))
Lua
LuaJIT requires some installation steps
- Download LuaJIT http://luajit.org/download/LuaJIT-2.0.4.zip
-
Follow LuaJIT installation instructions
http://luajit.org/install.html
- Open a VS2015 command prompt
- Run msvcbuild.bat
-
Test
local ffi = require("ffi") ffi.cdef[[ int MessageBoxA(void *w, const char *txt, const char *cap, int type); ]] ffi.C.MessageBoxA(nil, "Hello world!", "Test", 0)
- It works!
Example using LuaJIT FFI
-- http://stackoverflow.com/questions/17987618/how-to-add-a-sleep-or-wait-to-my-lua-script local ffi = require("ffi") ffi.cdef[[ typedef struct libvlc_instance_t libvlc_instance_t; typedef int64_t libvlc_time_t; libvlc_instance_t * libvlc_new( int argc , const char *const *argv ); void libvlc_release( libvlc_instance_t *p_instance ); typedef struct libvlc_media_t libvlc_media_t; typedef struct libvlc_media_player_t libvlc_media_player_t; libvlc_media_t *libvlc_media_new_location( libvlc_instance_t *p_instance, const char * psz_mrl ); libvlc_media_t *libvlc_media_new_path( libvlc_instance_t *p_instance, const char *path ); libvlc_media_player_t * libvlc_media_player_new( libvlc_instance_t *p_libvlc_instance ); void libvlc_media_player_release( libvlc_media_player_t *p_mi ); void libvlc_media_player_set_media( libvlc_media_player_t *p_mi, libvlc_media_t *p_md ); void libvlc_media_player_stop ( libvlc_media_player_t *p_mi ); int libvlc_media_player_play ( libvlc_media_player_t *p_mi ); void libvlc_media_player_release( libvlc_media_player_t *p_mi ); int MessageBoxA(void *w, const char *txt, const char *cap, int type); ]] ffi.cdef[[ void Sleep(int ms); int poll(struct pollfd *fds, unsigned long nfds, int timeout); ]] local sleep if ffi.os == "Windows" then function sleep(s) ffi.C.Sleep(s*1000) end else function sleep(s) ffi.C.poll(nil, 0, s*1000) end end ffi.C.MessageBoxA(nil, "Hello world!", "Test", 0) local vlc = ffi.load("libvlc") local vlc_instance = vlc.libvlc_new(0, nil) local big_buck_bunny_url = "http://download.blender.org/peach/bigbuckbunny_movies/big_buck_bunny_480p_surround-fix.avi" local media = vlc.libvlc_media_new_location(vlc_instance, big_buck_bunny_url) local media_player = vlc.libvlc_media_player_new(vlc_instance) vlc.libvlc_media_player_set_media(media_player,media) vlc.libvlc_media_player_play(media_player) sleep(10) vlc.libvlc_media_player_stop(media_player) vlc.libvlc_media_player_release(media_player) vlc.libvlc_release(vlc_instance)