VideoLAN::LibVLC - Wrapper for


version 0.05


  use VideoLAN::LibVLC::MediaPlayer;
  use AnyEvent; # or whatever your favorite event loop is
  my $exit_cv= AE::cv;
  # Tell event loop to call callback_dispatch any time callback_fh is readable
  my $vlc= VideoLAN::LibVLC->new;
  my $listen_vlc= AE::io $vlc->callback_fh, 0, sub { $vlc->callback_dispatch };
  my $player= $vlc->new_media_player("funny_cats.avi");
    # callback when player needs new picture buffer
    lock => sub ($player, $event) {
      # Allocate automatically using queue_new_picture
      $player->queue_new_picture(id => ++$next_pic_id)
        while $player->queued_picture_count < 8
    # callback when it is time to display a filled picture buffer
    display => sub ($player, $event) {
      do_stuff( $event->{picture} );  # do something with the picture
      $player->queue_picture($event->{picture});  # recycle the buffer
  $player->play; # start VLC thread that decodes and generates callbacks
  exit $exit_cv->recv; # give control to event loop


This module wraps LibVLC. The primary reason to use LibVLC instead of running VLC as a child process is to get programmatic access to the video frames coming from the decoder in real time. If you just want to iterate the frames of a video for some kind of non-realtime analysis, you probably want LibAV instead. LibVLC is primarily used to implement video players with alternate rendering, like sending the video frames to OpenGL textures, websockets, aalib, or other creative uses for which VLC doesn't have an output plugin.

LibVLC already has a very nice object-ish (yet still function-based) API, so this package wraps each group of functions into a perl object in the logical manner. One difficulty, however, is that LibVLC delivers audio and video via callbacks, and uses multiple threads for playback, which forces callbacks to deal with multithreading issues. Perl needs all callbacks to run from the main thread, so this module solves that by converting callbacks into events, and streaming them through a pipe. You can then fit this into an event loop of your choice by watching the read-state of the pipe and calling the dispatcher. You pretty much always need to integrate this into your event loop since even logging output is handled via callbacks. However, it only needs done for the top level VideoLAN::LibVLC instance, not for each player object. See "callback_dispatch" for details.


This module can export constants used by LibVLC, however I renamed them a bit because libvlc uses a mix of uppercase/lowercase/camel-case that is distracting and confusing when used as perl const-subs, the LIBVLC_ prefix is annoying for perl scripts, and some constants only differ by case.

The renaming rules are:

  • Remove any "LIBVLC_" or "libvlc_" prefix

  • If the constant does not begin with the same word as the enum it belongs to, add the enum's name to the beginning of the constant

  • Uppercase everything

for example:

  libvlc_Error      =>   STATE_ERROR
  libvlc_meta_Album =>   META_ALBUM

Each of LibVLC's enums can be exported individually:

  use VideoLAN::LibVLC qw( :log_level_t :media_parse_flag_t :media_parsed_status_t
   :media_slave_type_t :media_type_t :position_t :state_t :track_type_t
   :video_orient_t :video_projection_t );

Or get all of them with :constants.

However, be aware that the constants change significantly across libvlc versions, but this module always exports all of them. Accessing a constant not supported by your version of libvlc will throw an exception. (I figured it would be better to allow the exceptions at runtime than for programs to break at compile time due to the host's version of libvlc.)



Version of LibVLC. This is a package attribute.


Precise revision-control version of LibVLC. This is a package attribute.


Compiler used to create LibVLC. This is a package attribute.


A copy of the argv that you passed to the constructor. Read-only.


A java-style name identifying the application. Defaults to an empty string if you set app_version or app_icon.


The version of your application. Defaults to empty string if you assign an app_id or app_icon.


The name of the icon for your application. Defaults to empty string if you assign an app_id or app_version.


A human-facing description of your application as a user agent for web requests.


A HTTP UserAgent string for your application.


An arrayref of all audio filter modules built into LibVLC.


List accessor for audio_filters.


An arrayref of all video filter modules built into LibVLC.


List accessor for video_filters.


Whether or not this version of libvlc supports redirecting the log.


  # get
  my $current= $vlc->log
  # set to logger object
  $vlc->log( $log );
  $vlc->log( $log, \%options );
  # set to logging callback
  $vlc->log( sub { my ($event)= @_; ... } );
  $vlc->log( sub { my ($event)= @_; ... }, \%options );
  # disable logging

Set the logger object or logging callback or logging file handle for this LibVLC instance. It can be either a logger object like Log::Any, or a callback. The $event passed to the callback is a hashref containing message, level, and possibly other fields if requested by $options{fields}.

The optional second argument \%options can request more or less information about the log message. Available options are:

  fields => arrayref set of [ "module", "file", "line", "name", "header", "objid" ]
            or '*' to select all of them.  Each selected field will appear in the
            log $event.

for example,

  $vlc->log($log, { level => LOG_LEVEL_WARNING, fields => [qw( file line )] });

Note that logging can happen from other threads, so you won't see the messages until you call "callback_dispatch".



  my $vlc= VideoLAN::VLC->new( \@ARGV );
  my $vlc= VideoLAN::VLC->new( %attributes );
  my $vlc= VideoLAN::VLC->new( \%attributes );

Create a new instance of LibVLC (which directly corresponds to an initialization of libvlc via libvlc_new)

Note that libvlc suggests against passing command line arguments except for debugging, since they can differ by version and by platform.

The returned object is based on a hashref, and the libvlc pointer is magically attached.


  my $media= $vlc->new_media( $path );
  my $media= $vlc->new_media( $uri );
  my $media= $vlc->new_media( $file_handle );
  my $media= $vlc->new_media( %attributes );
  my $media= $vlc->new_media( \%attributes );

This nice heavily-overloaded method helps you quickly open new media streams. VLC can open paths, URIs, or file handles, and if you only pass one argument to this method it attempts to decide which of those three you intended.

You can instead pass a hash or hashref, and then it just passes them along to the Media constructor.


  my $player= $vlc->new_media_player();

Creates a new VideoLAN::LibVLC::MediaPlayer


The file handle of the read-end of the callback pipe. Watch the readable status of this file handle to know when to call "callback_dispatch". DO NOT READ OR WRITE IT FOR ANY REASON, lest ye incur the Wrath of the Segfault.


Read any pending callback messages from the pipe(s), and execute the callback. This method does not block (unless your callback does). You can wait for the file handle "callback_fh" to become readable to know when to call this method.

AnyEvent example:
  my $vlc= VideoLAN::LibVLC->new;
  my $watcher= AE::io $vlc->callback_fh, 0, sub { $vlc->callback_dispatch };  
IO::Async example:
  my $vlc= VideoLAN::LibVLC->new;
  $loop->add( IO::Async::Handle->new(
    handle => $vlc->callback_fh,
    on_read_ready => sub { $vlc->callback_dispatch },
Manual event loop example:
  my $vlc= VideoLAN::LibVLC->new;
  while (1) {
    if (IO::Select->new($vlc->callback_fh)->can_read) {

The "wire format" used to stream the callbacks is deliberately hidden within this module. It does not contain any user-servicable parts.


  libvlc_video_set_callbacks($player, $lock_cb, $unlock_cb, $display_cb, $opaque);

This is part of the LibVLC API, but you should use "set_video_callbacks" in VideoLAN::LibVLC::MediaPlayer instead.


  libvlc_video_set_format_callbacks($player, $format_cb, $cleanup_cb);

This is part of the LibVLC API, but you should use "set_video_callbacks" in VideoLAN::LibVLC::MediaPlayer instead.


Michael Conrad <>


This software is copyright (c) 2019 by Michael Conrad.

This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.