AnyEvent-MPV

 view release on metacpan or  search on metacpan

README  view on Meta::CPAN

                 my ($mpv, $name, $value) = @_;
                 print "property sid (=$name) has changed to $value\n";
              });

              () # ensure the above method is called in void context
           }

  SUBCLASSING
    Like most perl objects, "AnyEvent::MPV" objects are implemented as
    hashes, with the constructor simply storing all passed key-value pairs
    in the object. If you want to subclass to provide your own "on_*"
    methods, be my guest and rummage around in the internals as much as you
    wish - the only guarantee that this module dcoes is that it will not use
    keys with double colons in the name, so youc an use those, or chose to
    simply not care and deal with the breakage.

    If you don't want to go to the effort of subclassing this module, you
    can also specify all event handlers as constructor keys.

EXAMPLES
    Here are some real-world code snippets, thrown in here mainly to give
    you some example code to copy.

  doomfrontend
    At one point I replaced mythtv-frontend by my own terminal-based video
    player (based on rxvt-unicode). I toyed with the diea of using mpv's
    subtitle engine to create the user interface, but that is hard to use
    since you don't know how big your letters are. It is also where most of
    this modules code has originally been developed in.

    It uses a unified input queue to handle various remote controls, so its
    event handling needs are very simple - it simply feeds all events into
    the input queue:

       my $mpv = AnyEvent::MPV->new (
          mpv   => $MPV,
          args  => \@MPV_ARGS,
          on_event => sub {
             input_feed "mpv/$_[1]", $_[2];
          },
          on_key => sub {
             input_feed $_[1];
          },
          on_eof => sub {
             input_feed "mpv/quit";
          },
       );

       ...

       $mpv->start ("--idle=yes", "--pause", "--force-window=no");

    It also doesn't use complicated command line arguments - the file search
    options have the most impact, as they prevent mpv from scanning
    directories with tens of thousands of files for subtitles and more:

       --audio-client-name=doomfrontend
       --osd-on-seek=msg-bar --osd-bar-align-y=-0.85 --osd-bar-w=95
       --sub-auto=exact --audio-file-auto=exact

    Since it runs on a TV without a desktop environemnt, it tries to keep
    complications such as dbus away and the screensaver happy:

       # prevent xscreensaver from doing something stupid, such as starting dbus
       $ENV{DBUS_SESSION_BUS_ADDRESS} = "/"; # prevent dbus autostart for sure
       $ENV{XDG_CURRENT_DESKTOP} = "generic";

    It does bind a number of keys to internal (to doomfrontend) commands:

       for (
          List::Util::pairs qw(
             ESC   return
             q     return
             ENTER enter
             SPACE pause
             [     steprev
             ]     stepfwd
             j     subtitle
             BS    red
             i     green
             o     yellow
             b     blue
             D     triangle
             UP    up
             DOWN  down
             RIGHT right
             LEFT  left
          ),
          (map { ("KP$_" => "num$_") } 0..9),
          KP_INS => 0, # KP0, but different
       ) {
          $mpv->bind_key ($_->[0] => $_->[1]);
       }

    It also reacts to sponsorblock chapters, so it needs to know when vidoe
    chapters change. Preadting "AnyEvent::MPV", it handles observers
    manually:

       $mpv->cmd (observe_property => 1, "chapter-metadata");

    It also tries to apply an mpv profile, if it exists:

       eval {
          # the profile is optional
          $mpv->cmd ("apply-profile" => "doomfrontend");
       };

    Most of the complicated parts deal with saving and restoring per-video
    data, such as bookmarks, playing position, selected audio and subtitle
    tracks and so on. However, since it uses Coro, it can conveniently block
    and wait for replies, which is n ot possible in purely event based
    programs, as you are not allowed to block inside event callbacks in most
    event loops. This simplifies the code quite a bit.

    When the file to be played is a Tv recording done by mythtv, it uses the
    "appending" protocol and deinterlacing:

       if (is_myth $mpv_path) {
          $mpv_path = "appending://$mpv_path";
          $initial_deinterlace = 1;
       }



( run in 0.832 second using v1.01-cache-2.11-cpan-5837b0d9d2c )