AnyEvent-MPV
view release on metacpan or search on metacpan
$quit->recv;
=head1 DESCRIPTION
This module allows you to remote control F<mpv> (a video player). It also
is an L<AnyEvent> user, you need to make sure that you use and run a
supported event loop.
There are other modules doing this, and I haven't looked much at them
other than to decide that they don't handle encodings correctly, and since
none of them use AnyEvent, I wrote my own. When in doubt, have a look at
them, too.
Knowledge of the L<mpv command
interface|https://mpv.io/manual/stable/#command-interface> is required to
use this module.
Features of this module are:
=over
=item F<--force-window=no> (or similar), to keep F<mpv> from instantly opening a window, or to force it to do so.
=item F<--audio-client-name=yourappname>, to make sure audio streams are associated witht eh right program.
=item F<--wid=id>, to embed F<mpv> into another application.
=item F<--no-terminal>, F<--no-input-default-bindings>, F<--no-input-cursor>, F<--input-conf=/dev/null>, F<--input-vo-keyboard=no> - to ensure only you control input.
=back
The return value can be used to decide whether F<mpv> needs initializing:
if ($mpv->start) {
$mpv->bind_key (...);
$mpv->cmd (set => property => value);
...
}
You can immediately starting sending commands when this method returns,
even if F<mpv> has not yet started.
And thats most of the F<mpv>-related code.
=head2 F<Gtk2::CV>
F<Gtk2::CV> is low-feature image viewer that I use many times daily
because it can handle directories with millions of files without falling
over. It also had the ability to play videos for ages, but it used an
older, crappier protocol to talk to F<mpv> and used F<ffprobe> before
playing each file instead of letting F<mpv> handle format/size detection.
After writing this module, I decided to upgprade Gtk2::CV by making use
of it, with the goal of getting rid of F<ffprobe> and being ablew to
reuse F<mpv> processes, which would have a multitude of speed benefits
(for example, fork+exec of F<mpv> caused the kernel to close all file
descriptors, which could take minutes if a large file was being copied via
NFS, as the kernel waited for thr buffers to be flushed on close - not
having to start F<mpv> gets rid of this issue).
Setting up is only complicated by the fact that F<mpv> needs to be
embedded into an existing window. To keep control of all inputs,
F<Gtk2::CV> puts an eventbox in front of F<mpv>, so F<mpv> receives no
}
} elsif ($type eq "video/iso-bluray") {
$mpv->cmd (set => "bluray-device" => $path);
$mpv->cmd (loadfile => "bd://");
} else {
$mpv->cmd (loadfile => $mpv->escape_binary ($path));
}
After this, C<Gtk2::CV> waits for the file to be loaded, video to be
configured, and then queries the video size (to resize its own window)
and video format (to decide whether an audio visualizer is needed for
audio playback). The problematic word here is "wait", as this needs to be
imploemented using callbacks.
This made the code much harder to write, as the whole setup is very
asynchronous (C<Gtk2::CV> talks to the command interface in F<mpv>, which
talks to the decode and playback parts, all of which run asynchronously
w.r.t. each other. In practise, this can mean that C<Gtk2::CV> waits for
a file to be loaded by F<mpv> while the command interface of F<mpv> still
deals with the previous file and the decoder still handles an even older
file). Adding to this fact is that Gtk2::CV is bound by the glib event
my $quit = AE::cv;
$mpv->register_event (end_file => $quit);
$quit->recv;
DESCRIPTION
This module allows you to remote control mpv (a video player). It also
is an AnyEvent user, you need to make sure that you use and run a
supported event loop.
There are other modules doing this, and I haven't looked much at them
other than to decide that they don't handle encodings correctly, and
since none of them use AnyEvent, I wrote my own. When in doubt, have a
look at them, too.
Knowledge of the mpv command interface
<https://mpv.io/manual/stable/#command-interface> is required to use
this module.
Features of this module are:
uses AnyEvent, so integrates well into most event-based programs
you want to inspect/change properties first.
--force-window=no (or similar), to keep mpv from instantly opening a
window, or to force it to do so.
--audio-client-name=yourappname, to make sure audio streams are
associated witht eh right program.
--wid=id, to embed mpv into another application.
--no-terminal, --no-input-default-bindings, --no-input-cursor,
--input-conf=/dev/null, --input-vo-keyboard=no - to ensure only you
control input.
The return value can be used to decide whether mpv needs
initializing:
if ($mpv->start) {
$mpv->bind_key (...);
$mpv->cmd (set => property => value);
...
}
You can immediately starting sending commands when this method
returns, even if mpv has not yet started.
And thats most of the mpv-related code.
Gtk2::CV
Gtk2::CV is low-feature image viewer that I use many times daily because
it can handle directories with millions of files without falling over.
It also had the ability to play videos for ages, but it used an older,
crappier protocol to talk to mpv and used ffprobe before playing each
file instead of letting mpv handle format/size detection.
After writing this module, I decided to upgprade Gtk2::CV by making use
of it, with the goal of getting rid of ffprobe and being ablew to reuse
mpv processes, which would have a multitude of speed benefits (for
example, fork+exec of mpv caused the kernel to close all file
descriptors, which could take minutes if a large file was being copied
via NFS, as the kernel waited for thr buffers to be flushed on close -
not having to start mpv gets rid of this issue).
Setting up is only complicated by the fact that mpv needs to be embedded
into an existing window. To keep control of all inputs, Gtk2::CV puts an
eventbox in front of mpv, so mpv receives no input events:
}
} elsif ($type eq "video/iso-bluray") {
$mpv->cmd (set => "bluray-device" => $path);
$mpv->cmd (loadfile => "bd://");
} else {
$mpv->cmd (loadfile => $mpv->escape_binary ($path));
}
After this, "Gtk2::CV" waits for the file to be loaded, video to be
configured, and then queries the video size (to resize its own window)
and video format (to decide whether an audio visualizer is needed for
audio playback). The problematic word here is "wait", as this needs to
be imploemented using callbacks.
This made the code much harder to write, as the whole setup is very
asynchronous ("Gtk2::CV" talks to the command interface in mpv, which
talks to the decode and playback parts, all of which run asynchronously
w.r.t. each other. In practise, this can mean that "Gtk2::CV" waits for
a file to be loaded by mpv while the command interface of mpv still
deals with the previous file and the decoder still handles an even older
file). Adding to this fact is that Gtk2::CV is bound by the glib event
( run in 0.893 second using v1.01-cache-2.11-cpan-de7293f3b23 )