AnyEvent-MPV

 view release on metacpan or  search on metacpan

MPV.pm  view on Meta::CPAN


   $mpv->cmd_recv ("stop");
   $position = $mpv->cmd_recv ("get_property", "playback-time");

=cut

sub cmd_recv {
   &cmd->recv
}

=item $mpv->bind_key ($INPUT => $string)

This is an extension implement by this module to make it easy to get key
events. The way this is implemented is to bind a C<client-message> witha
first argument of C<AnyEvent::MPV> and the C<$string> you passed. This
C<$string> is then passed to the C<on_key> handle when the key is
proessed, e.g.:

   my $mpv = AnyEvent::MPV->new (
      on_key => sub {
         my ($mpv, $key) = @_;

MPV.pm  view on Meta::CPAN

   $mpv->cmd ("set", "vid", "auto");
   $mpv->cmd ("set", "aid", "auto");
   $mpv->cmd ("set", "sid", "no");
   $mpv->cmd ("set", "file-local-options/chapters-file", $mpv->escape_binary ("$mpv_path.chapters"));
   $mpv->cmd ("loadfile", $mpv->escape_binary ($mpv_path));
   $mpv->cmd ("script-message", "osc-visibility", "auto", "dummy");

Handling events makes the main bulk of video playback code. For example,
various ways of ending playback:

      if ($INPUT eq "mpv/quit") { # should not happen, but allows user to kill etc. without consequence
         $status = 1;
         mpv_init; # try reinit
         last;

      } elsif ($INPUT eq "mpv/idle") { # normal end-of-file
         last;

      } elsif ($INPUT eq "return") {
         $status = 1;
         last;

Or the code that actually starts playback, once the file is loaded:

   our %SAVE_PROPERTY = (aid => 1, sid => 1, "audio-delay" => 1);
   
   ...

   my $oid = 100;

      } elsif ($INPUT eq "mpv/file-loaded") { # start playing, configure video
         $mpv->cmd ("seek", $playback_start, "absolute+exact") if $playback_start > 0;

         my $target_fps = eval { $mpv->cmd_recv ("get_property", "container-fps") } || 60;
         $target_fps *= play_video_speed_mult;
         set_fps $target_fps;

         unless (eval { $mpv->cmd_recv ("get_property", "video-format") }) {
            $mpv->cmd ("set", "file-local-options/lavfi-complex", "[aid1] asplit [ao], showcqt=..., format=yuv420p [vo]");
         };

MPV.pm  view on Meta::CPAN


Also, a number of properties are not global, but per-file. At the moment,
this is C<audio-delay>, and the current audio/subtitle track, which it
sets, and also creates an observer. Again, this doesn'T use the observe
functionality of this module, but handles it itself, assigning obsevrer
ids 100+ to temporary/per-file observers.

Lastly, it sets some global (or per-youtube-uploader) parameters, such as
speed, and unpauses. Property changes are handled like other input events:

      } elsif ($INPUT eq "mpv/property-change") {
         my $prop = $INPUT_DATA->{name};

         if ($prop eq "chapter-metadata") {
            if ($INPUT_DATA->{data}{TITLE} =~ /^\[SponsorBlock\]: (.*)/) {
               my $section = $1;
               my $skip;

               $skip ||= $SPONSOR_SKIP{$_}
                  for split /\s*,\s*/, $section;

               if (defined $skip) {
                  if ($skip) {
                     # delay a bit, in case we get two metadata changes in quick succession, e.g.
                     # because we have a skip at file load time.

MPV.pm  view on Meta::CPAN

                  }
               } else {
                  $mpv->cmd ("show-text", "UNRECOGNIZED sponsorblock section \"$section\"", 60000);
               }
            } else {
               # cancel a queued skip
               undef $skip_delay;
            }

         } elsif (exists $SAVE_PROPERTY{$prop}) {
            $PLAYING_STATE->{"mpv_$prop"} = $INPUT_DATA->{data};
            ::state_save;
         }

This saves back the per-file properties, and also handles chapter changes
in a hacky way.

Most of the handlers are very simple, though. For example:

      } elsif ($INPUT eq "pause") {
         $mpv->cmd ("cycle", "pause");
         $PLAYING_STATE->{curpos} = $mpv->cmd_recv ("get_property", "playback-time");
      } elsif ($INPUT eq "right") {
         $mpv->cmd ("osd-msg-bar", "seek",  30, "relative+exact");
      } elsif ($INPUT eq "left") {
         $mpv->cmd ("osd-msg-bar", "seek", -5, "relative+exact");
      } elsif ($INPUT eq "up") {
         $mpv->cmd ("osd-msg-bar", "seek", +600, "relative+exact");
      } elsif ($INPUT eq "down") {
         $mpv->cmd ("osd-msg-bar", "seek", -600, "relative+exact");
      } elsif ($INPUT eq "select") {
         $mpv->cmd ("osd-msg-bar", "add", "audio-delay", "-0.100");
      } elsif ($INPUT eq "start") {
         $mpv->cmd ("osd-msg-bar", "add", "audio-delay", "0.100");
      } elsif ($INPUT eq "intfwd") {
         $mpv->cmd ("no-osd", "frame-step");
      } elsif ($INPUT eq "audio") {
         $mpv->cmd ("osd-auto", "cycle", "audio");
      } elsif ($INPUT eq "subtitle") {
         $mpv->cmd ("osd-auto", "cycle", "sub");
      } elsif ($INPUT eq "triangle") {
         $mpv->cmd ("osd-auto", "cycle", "deinterlace");

Once a file has finished playing (or the user strops playback), it pauses,
unobserves the per-file observers, and saves the current position for to
be able to resume:

   $mpv->cmd ("set", "pause", "yes");

   while ($oid > 100) {
      $mpv->cmd ("unobserve_property", $oid--);

README  view on Meta::CPAN

        On error, the condvar will croak when "recv" is called.

    $result = $mpv->cmd_recv ($command => $arg, $arg...)
        The same as calling "cmd" and immediately "recv" on its return
        value. Useful when you don't want to mess with mpv asynchronously or
        simply needs to have the result:

           $mpv->cmd_recv ("stop");
           $position = $mpv->cmd_recv ("get_property", "playback-time");

    $mpv->bind_key ($INPUT => $string)
        This is an extension implement by this module to make it easy to get
        key events. The way this is implemented is to bind a
        "client-message" witha first argument of "AnyEvent::MPV" and the
        $string you passed. This $string is then passed to the "on_key"
        handle when the key is proessed, e.g.:

           my $mpv = AnyEvent::MPV->new (
              on_key => sub {
                 my ($mpv, $key) = @_;

README  view on Meta::CPAN

       $mpv->cmd ("set", "vid", "auto");
       $mpv->cmd ("set", "aid", "auto");
       $mpv->cmd ("set", "sid", "no");
       $mpv->cmd ("set", "file-local-options/chapters-file", $mpv->escape_binary ("$mpv_path.chapters"));
       $mpv->cmd ("loadfile", $mpv->escape_binary ($mpv_path));
       $mpv->cmd ("script-message", "osc-visibility", "auto", "dummy");

    Handling events makes the main bulk of video playback code. For example,
    various ways of ending playback:

          if ($INPUT eq "mpv/quit") { # should not happen, but allows user to kill etc. without consequence
             $status = 1;
             mpv_init; # try reinit
             last;

          } elsif ($INPUT eq "mpv/idle") { # normal end-of-file
             last;

          } elsif ($INPUT eq "return") {
             $status = 1;
             last;

    Or the code that actually starts playback, once the file is loaded:

       our %SAVE_PROPERTY = (aid => 1, sid => 1, "audio-delay" => 1);
   
       ...

       my $oid = 100;

          } elsif ($INPUT eq "mpv/file-loaded") { # start playing, configure video
             $mpv->cmd ("seek", $playback_start, "absolute+exact") if $playback_start > 0;

             my $target_fps = eval { $mpv->cmd_recv ("get_property", "container-fps") } || 60;
             $target_fps *= play_video_speed_mult;
             set_fps $target_fps;

             unless (eval { $mpv->cmd_recv ("get_property", "video-format") }) {
                $mpv->cmd ("set", "file-local-options/lavfi-complex", "[aid1] asplit [ao], showcqt=..., format=yuv420p [vo]");
             };

README  view on Meta::CPAN

    Also, a number of properties are not global, but per-file. At the
    moment, this is "audio-delay", and the current audio/subtitle track,
    which it sets, and also creates an observer. Again, this doesn'T use the
    observe functionality of this module, but handles it itself, assigning
    obsevrer ids 100+ to temporary/per-file observers.

    Lastly, it sets some global (or per-youtube-uploader) parameters, such
    as speed, and unpauses. Property changes are handled like other input
    events:

          } elsif ($INPUT eq "mpv/property-change") {
             my $prop = $INPUT_DATA->{name};

             if ($prop eq "chapter-metadata") {
                if ($INPUT_DATA->{data}{TITLE} =~ /^\[SponsorBlock\]: (.*)/) {
                   my $section = $1;
                   my $skip;

                   $skip ||= $SPONSOR_SKIP{$_}
                      for split /\s*,\s*/, $section;

                   if (defined $skip) {
                      if ($skip) {
                         # delay a bit, in case we get two metadata changes in quick succession, e.g.
                         # because we have a skip at file load time.

README  view on Meta::CPAN

                      }
                   } else {
                      $mpv->cmd ("show-text", "UNRECOGNIZED sponsorblock section \"$section\"", 60000);
                   }
                } else {
                   # cancel a queued skip
                   undef $skip_delay;
                }

             } elsif (exists $SAVE_PROPERTY{$prop}) {
                $PLAYING_STATE->{"mpv_$prop"} = $INPUT_DATA->{data};
                ::state_save;
             }

    This saves back the per-file properties, and also handles chapter
    changes in a hacky way.

    Most of the handlers are very simple, though. For example:

          } elsif ($INPUT eq "pause") {
             $mpv->cmd ("cycle", "pause");
             $PLAYING_STATE->{curpos} = $mpv->cmd_recv ("get_property", "playback-time");
          } elsif ($INPUT eq "right") {
             $mpv->cmd ("osd-msg-bar", "seek",  30, "relative+exact");
          } elsif ($INPUT eq "left") {
             $mpv->cmd ("osd-msg-bar", "seek", -5, "relative+exact");
          } elsif ($INPUT eq "up") {
             $mpv->cmd ("osd-msg-bar", "seek", +600, "relative+exact");
          } elsif ($INPUT eq "down") {
             $mpv->cmd ("osd-msg-bar", "seek", -600, "relative+exact");
          } elsif ($INPUT eq "select") {
             $mpv->cmd ("osd-msg-bar", "add", "audio-delay", "-0.100");
          } elsif ($INPUT eq "start") {
             $mpv->cmd ("osd-msg-bar", "add", "audio-delay", "0.100");
          } elsif ($INPUT eq "intfwd") {
             $mpv->cmd ("no-osd", "frame-step");
          } elsif ($INPUT eq "audio") {
             $mpv->cmd ("osd-auto", "cycle", "audio");
          } elsif ($INPUT eq "subtitle") {
             $mpv->cmd ("osd-auto", "cycle", "sub");
          } elsif ($INPUT eq "triangle") {
             $mpv->cmd ("osd-auto", "cycle", "deinterlace");

    Once a file has finished playing (or the user strops playback), it
    pauses, unobserves the per-file observers, and saves the current
    position for to be able to resume:

       $mpv->cmd ("set", "pause", "yes");

       while ($oid > 100) {
          $mpv->cmd ("unobserve_property", $oid--);



( run in 0.339 second using v1.01-cache-2.11-cpan-4e96b696675 )