NAME
VideoLAN::LibVLC::MediaPlayer - Media Player
VERSION
version 0.06
SYNOPSIS
my $p= VideoLAN::LibVLC->new->new_media_player();
$p->media("FunnyCatVideo.mp4");
$p->play;
DESCRIPTION
This object wraps libvlc_media_player_t. This is the primary object for media playback.
ATTRIBUTES
libvlc
Read-only reference to the library instance that created this player.
media
The VideoLAN::LibVLC::Media object being played
is_playing
Boolean, whether playback is active
will_play
Boolean, whether the media player is able to play
is_seekable
Boolean, whether media is seekable
can_pause
Boolean, whether playback can be paused
rate
The requested playback rate. (multiple or fraction of real-time)
Writing this attribute calls "set_rate".
length
The length in seconds of the media
title_count
Number if subtitle tracks in the media, or undef.
title
Number of the subtitle track currently playing, or undef.
"title" is the official language of libvlc, but "subtitle" is what English speakers probably expect to find. I decided to stick with the API's terminology.
chapter_count
Number of chapters in media, or undef
chapter
Chapter number currently playing, or undef if no media is playing. Setting this attribute changes the chapter.
time
The position within the media file, measured in seconds. Undef until playback begins. Setting this attribute performs a seek.
position
The position within the media file, measured as a fraction of media length. (0..1). Undef until playback begins. Setting this attribute performs a seek.
METHODS
new
my $player= VideoLAN::LibVLC::MediaPlayer->new(
libvlc => $vlc,
);
set_media
Set the player's active media soruce. May be an instance of VideoLAN::LibVLC::Media or any valid argument for "new_media" in VideoLAN::LibVLC.
This can also be called by setting the "media" attribute.
play
pause
set_pause
Requires libvlc 1.1.1
stop
set_rate
set_video_title_display
$player->set_video_title_display( $position, $timeout );
Specify where and how long subtitles should be displayed. Position is one of:
use VideoLAN::LibVLC ':position_t';
# POSITION_DISABLE
# POSITION_CENTER
# POSITION_LEFT
# POSITION_RIGHT
# POSITION_TOP
# POSITION_TOP_LEFT
# POSITION_TOP_RIGHT
# POSITION_BOTTOM
# POSITION_BOTTOM_LEFT
# POSITION_BOTTOM_RIGHT
but may also be an uppercase or lowercase string of one of those minus the leading "POSITION_".
Timeout is in seconds.
Requires host libvlc 2.1, but only warns if this method is not supported.
VIDEO CALLBACK API
The primary motivation for using LibVLC rather than shelling out to the actual VLC binary is that you can capture the decoded video or audio and do something with it. Here's an overview of how to process the video frames generated by VLC:
- Prepare to Dispatch Messages
-
VLC runs in a separate thread from the main program. In order to handle callbacks, you need to pump a message queue that this module uses to ferry the events back and forth. The most direct way is with
$vlc= $player->libvlc; while ($main_loop) { ... # dispatch each pending message 1 while $vlc->callback_dispatch; ... }
If you are using an event library like AnyEvent, it can simply be
AE::io $vlc->callback_fh, 0, sub { $vlc->callback_dispatch };
- Choose Video Format
-
Decide whether you want to force a specific video format, or use the native format of the media, or a little of both. Using the native format of the media requires VLC 2.0 or higher.
To specify your own format, call
set_video_callbacks
without theformat
callback, and then call "set_video_format" with the desired chroma, width, height, and pitch.$p->set_video_callbacks(display => sub { ... }); $p->set_video_format({ chroma => "RGBA", width => 640, height => 480, pitch => 640*4 });
To adapt to the format of the media (especially for width/height, even if you plan to force RGB or something) set the
format
callback, and then call "set_video_format" from within that callback. You can also allocate the pictures after setting the format, though you might want to wait for thelock
callback since VLC sometimes calls this multiple times before playback begins.$p->set_video_callbacks( format => sub { my ($p, $event)= @_; $p->set_video_format({ chroma => "RGBA", width => $event->{width}, height => $event->{height}, pitch => $event->{width}*4 }); }, lock => sub { # allocate pictures here, if it hasn't been done yet # See below. } display => sub { ... }, );
- Create Picture Buffers
-
Once you know the format, you can create picture buffers for VLC to render into. These are instances of VideoLAN::LibVLC::Picture. If you only specify the dimensions of the picture buffer, it will allocate memory internally. You may also provide the memory of the planes as scalar-refs, but this is likely to crash your program if you're not careful, and should only be done if you have special requirements like rendering into a memory-map (such as created by File::Map or OpenGL::Sandbox::Buffer).
After creating a picture buffer, pass it to queue_picture. This gives the internal VLC thread access to them.
$p->queue_new_picture(id => $_) for 0..7; # which is shorthand for: for (0..7) { my $pic= VideoLAN::LibVLC::Picture->new( $p->video_format->%*, id => $_ ); $p->queue_picture($pic); }
Picture IDs aren't required but it helps when debugging with "trace_pictures".
- Handle the Lock and Unlock events
-
The VLC thread runs asynchronous to the main Perl program. It notifies you when it needs a new buffer, and when it has filled that buffer. These events can be handled with callbacks, if you want. Note that you'll need a really fast turnaround time for the
lock
callback, and it is much better to queue pictures in advance. But, you can queue in advance and still receive thelock
callback for bookkeeping purposes. Theunlock
callback lets you know when the VLC thread has filled a buffer, but it is not necessarily time to display the buffer. Depending on the video codec, the images might be created in a different order than they get displayed. - Handle the Display event
-
The most important callback is the
display
callback. This tells you when it is time to show a picture. This event is also the moment that aPicture
object becomes detached from theMediaPlayer
object. You need to call "queue_picture" again afterward if you want to recycle the picture. - Handle the Cleanup event
-
Using the VLC 2.0 API also gives you a
cleanup
event when VLC is done rendering pictures. The way the API works, you must also use theformat
callback to be able to use thecleanup
callback.
set_video_callbacks
This method sets up the player to render into user-supplied picture buffers. it accepts a hash of callbacks:
- format
-
format => sub { my ($player, $event)= @_; # event contains all the same attributes as ->set_video_format takes }
Called (sometimes multiple times) when VLC builds its decoding pipeline.
- lock
-
lock => sub { my ($player, $event)= @_; ... $player->queue_picture(...); }
Called when the decoding threads wants a new picture. Respond with "queue_pictue", or better, maintain the queue of pictures by checking "queued_picture_count" and queueing them in advance.
- unlock
-
unlock => sub { my ($player, $event)= @_; # do something with $event->{picture} }
Called wien the decoding thread has filled a picture, though it might not be the next picture that should be displayed. (this event would mainly be useful to begin syncing the data to somewhere)
- display
-
display => sub { my ($player, $event)= @_; # do something with $event->{picture} }
This is called when it is time to show the picture. If you are done displaying the previous picture, now is a good time to recycle it with
$player->queue_picture($prev_picture)
. - cleanup
-
cleanup => sub { my ($player, $event)= @_; ... }
You can release resources of the pictures here, but the player might still hold references to a few of of the Picture objects.
- discard
-
discard => sub { my ($player, $event)= @_; ... # free resources of $event->{picture} }
This is called for any picture which the decoder wasn't able to use, either due being the wrong format, or at the end of playback of there were extra pictures queued.
- opaque
-
opaque => $my_object
Not a callback; this option allows you to specify some other object which will be passed to your callbacks as the first argument, rather than
$player
.
set_video_format
$p->set_video_format(
chroma => "....", # VLC four-CC code. required
width => $width, # in pixels. requird.
height => $height, # in pixels. required.
pitch => \@pitch, # may also be single value for single-plane images
lines => \@lines, # may also be single value for single-plane images
alloc_count => $n # number of concurrent buffers you plan to provide
);
If this is called without registering a format
callback, it will call libvlc_video_set_format
which forces VLC to rescale the pictures to your desired format. If called after registering a format
callback, it will send this as a reply to the video thread, with mostly the same effect (but after you've had the opportunity to see what the native format is).
See VideoLAN::LibVLC::Picture for discussion of the parameters other than alloc_count
. alloc_count
is the number of pictures you plan to make available to the decoder at one time, and might be used by the decoder to decide whether to allocate its own temporary buffers if it can't get enough supplied by the application.
If you are using the format
callback, this should only be called in response to the callback. You should also set $alloc_count
, and $lines[0..2]
and $pitch[0..2]
.
If not using the callback, this should only be called once, and $lines
and $alloc_count
and <$pitch[1..2]
> are ignored due to limitations of the older API.
new_picture
my $picture= $player->new_picture( %overrides );
Retun a new VideoLAN::LibVLC::Picture object, defaulting to the format last registered with "set_video_format". Any arguments to this function will be merged with those format parameters.
queue_picture
$player->queue_picture($picture);
Push a picture onto the queue to the VLC decoding thread. Once pushed, you may not alter the picture in any way, or else risk crashing your program. It is best to drop any reference you had to the picture and let the Player hold onto it until time for a display
event.
queue_new_picture
A shorthand combination of the above methods.
queued_picture_count
Number of pictures which have been given to the decoder thread and have not yet come back for display
. This does include pictures which have been seen by the "unlock" callback.
trace_pictures
This is an attribute of the player that, when enabled, causes all exchange of pictures to be logged on file descriptor 2 (stderr). Note that due to the multi-threaded nature of the VLC decoder, this won't be synchronized with changes to STDERR by perl, and could result in garbled messages in some cases. This is only intended for debugging use.
AUDIO CALLBACK API (TODO)
I have not implemented this yet. Patches welcome.
AUTHOR
Michael Conrad <mike@nrdvana.net>
COPYRIGHT AND LICENSE
This software is copyright (c) 2023 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.