ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/AnyEvent-MPV/MPV.pm
(Generate patch)

Comparing AnyEvent-MPV/MPV.pm (file contents):
Revision 1.10 by root, Mon Mar 20 12:31:03 2023 UTC vs.
Revision 1.11 by root, Mon Mar 20 13:32:52 2023 UTC

147 my $quit = AE::cv; 147 my $quit = AE::cv;
148 148
149 my $mpv = AnyEvent::MPV->new ( 149 my $mpv = AnyEvent::MPV->new (
150 trace => 1, 150 trace => 1,
151 args => ["--pause", "--idle=yes"], 151 args => ["--pause", "--idle=yes"],
152 on_event => sub {
153 my ($mpv, $event, $data) = @_;
154
155 if ($event eq "start-file") {
156 $mpv->cmd ("set", "pause", "no");
157 } elsif ($event eq "end-file") {
158 print "end-file<$data->{reason}>\n";
159 $quit->send;
160 }
161 },
162 ); 152 );
163 153
164 $mpv->start; 154 $mpv->start;
155
156 $mpv->register_event (start_file => sub {
157 $mpv->cmd ("set", "pause", "no");
158 });
159
160 $mpv->register_event (end_file => sub {
161 my ($mpv, $event, $data) = @_;
162
163 print "end-file<$data->{reason}>\n";
164 $quit->send;
165 });
166
165 $mpv->cmd (loadfile => $mpv->escape_binary ($videofile)); 167 $mpv->cmd (loadfile => $mpv->escape_binary ($videofile));
166 168
167 $quit->recv; 169 $quit->recv;
168 170
169This example uses a global condvar C<$quit> to wait for the file to finish 171This example uses a global condvar C<$quit> to wait for the file to finish
170playing. Also, most of the logic is now in an C<on_event> callback, which 172playing. Also, most of the logic is now implement in event handlers.
171receives an event name and the actual event object.
172 173
173The two events we handle are C<start-file>, which is emitted by F<mpv> 174The two events handlers we register are C<start-file>, which is emitted by
174once it has loaded a new file, and C<end-file>, which signals the end 175F<mpv> once it has loaded a new file, and C<end-file>, which signals the
175of a file. 176end of a file (underscores are internally replaced by minus signs, so you
177cna speicfy event names with either).
176 178
177In the former event, we again set the C<pause> property to C<no> so the 179In the C<start-file> event, we again set the C<pause> property to C<no>
178movie starts playing. For the latter event, we tell the main program to 180so the movie starts playing. For the C<end-file> event, we tell the main
179quit by invoking C<$quit>. 181program to quit by invoking C<$quit>.
180 182
181This should conclude the basics of operation. There are a few more 183This should conclude the basics of operation. There are a few more
182examples later in the documentation. 184examples later in the documentation.
183 185
184=head2 ENCODING CONVENTIONS 186=head2 ENCODING CONVENTIONS
352 354
353sub start { 355sub start {
354 my ($self, @extra_args) = @_; 356 my ($self, @extra_args) = @_;
355 357
356 return 0 if $self->{fh}; 358 return 0 if $self->{fh};
357
358 $self->{obscb} = {};
359 359
360 # cache optionlist for same "path" 360 # cache optionlist for same "path"
361 ($mpv_path, $mpv_optionlist) = ($self->{mpv}, scalar qx{\Q$self->{mpv}\E --list-options}) 361 ($mpv_path, $mpv_optionlist) = ($self->{mpv}, scalar qx{\Q$self->{mpv}\E --list-options})
362 if $self->{mpv} ne $mpv_path; 362 if $self->{mpv} ne $mpv_path;
363 363
402 402
403 if ("{" eq substr $1, 0, 1) { 403 if ("{" eq substr $1, 0, 1) {
404 eval { 404 eval {
405 my $reply = $JSON->new->latin1->decode ($1); 405 my $reply = $JSON->new->latin1->decode ($1);
406 406
407 if (exists $reply->{event}) { 407 if (defined (my $event = delete $reply->{event})) {
408 if ( 408 if (
409 $reply->{event} eq "client-message" 409 $event eq "client-message"
410 and $reply->{args}[0] eq "AnyEvent::MPV" 410 and $reply->{args}[0] eq "AnyEvent::MPV"
411 ) { 411 ) {
412 if ($reply->{args}[1] eq "key") { 412 if ($reply->{args}[1] eq "key") {
413 (my $key = $reply->{args}[2]) =~ s/\\x(..)/chr hex $1/ge; 413 (my $key = $reply->{args}[2]) =~ s/\\x(..)/chr hex $1/ge;
414 $self->on_key ($key); 414 $self->on_key ($key);
415 } 415 }
416 } elsif ( 416 } elsif (
417 $reply->{event} eq "property-change" 417 $event eq "property-change"
418 and OBSID <= $reply->{id} 418 and OBSID <= $reply->{id}
419 ) { 419 ) {
420 if (my $cb = $self->{obscb}{$reply->{id}}) { 420 if (my $cb = $self->{obscb}{$reply->{id}}) {
421 $cb->($self, $reply->{name}, $reply->{data}); 421 $cb->($self, $event, $reply->{data});
422 } 422 }
423 } else { 423 } else {
424 if (my $cbs = $self->{evtcb}{$event}) {
425 for my $evtid (keys %$cbs) {
426 my $cb = $cbs->{$evtid}
427 or next;
428 $cb->($self, $event, $reply);
429 }
430 }
431
424 $self->on_event (delete $reply->{event}, $reply); 432 $self->on_event ($event, $reply);
425 } 433 }
426 } elsif (exists $reply->{request_id}) { 434 } elsif (exists $reply->{request_id}) {
427 my $cv = delete $self->{cmdcv}{$reply->{request_id}}; 435 my $cv = delete $self->{cmdcv}{$reply->{request_id}};
428 436
429 unless ($cv) { 437 unless ($cv) {
508 516
509 } 517 }
510 518
511 delete $self->{pid}; 519 delete $self->{pid};
512 delete $self->{cmdcv}; 520 delete $self->{cmdcv};
521 delete $self->{evtid};
522 delete $self->{evtcb};
513 delete $self->{obsid}; 523 delete $self->{obsid};
514 delete $self->{obscb}; 524 delete $self->{obscb};
515 delete $self->{wbuf}; 525 delete $self->{wbuf};
516} 526}
517 527
630 &cmd->recv 640 &cmd->recv
631} 641}
632 642
633=item $mpv->bind_key ($INPUT => $string) 643=item $mpv->bind_key ($INPUT => $string)
634 644
635This is an extension implement by this module to make it easy to get key events. The way this is implemented 645This is an extension implement by this module to make it easy to get key
636is to bind a C<client-message> witha first argument of C<AnyEvent::MPV> and the C<$string> you passed. This C<$string> is then 646events. The way this is implemented is to bind a C<client-message> witha
637passed to the C<on_key> handle when the key is proessed, e.g.: 647first argument of C<AnyEvent::MPV> and the C<$string> you passed. This
648C<$string> is then passed to the C<on_key> handle when the key is
649proessed, e.g.:
638 650
639 my $mpv = AnyEvent::MPV->new ( 651 my $mpv = AnyEvent::MPV->new (
640 on_key => sub { 652 on_key => sub {
641 my ($mpv, $key) = @_; 653 my ($mpv, $key) = @_;
642 654
646 }, 658 },
647 ); 659 );
648 660
649 $mpv_>bind_key (ESC => "letmeout"); 661 $mpv_>bind_key (ESC => "letmeout");
650 662
663You cna find a list of key names L<in the mpv
664documentation|https://mpv.io/manual/stable/#key-names>.
665
651The key configuration is lost when F<mpv> is stopped and must be (re-)done 666The key configuration is lost when F<mpv> is stopped and must be (re-)done
652after every C<start>. 667after every C<start>.
653 668
654=cut 669=cut
655 670
658 673
659 $event =~ s/([^A-Za-z0-9\-_])/sprintf "\\x%02x", ord $1/ge; 674 $event =~ s/([^A-Za-z0-9\-_])/sprintf "\\x%02x", ord $1/ge;
660 $self->cmd (keybind => $key => "no-osd script-message AnyEvent::MPV key $event"); 675 $self->cmd (keybind => $key => "no-osd script-message AnyEvent::MPV key $event");
661} 676}
662 677
678=item [$guard] = $mpv->register_event ($event => $coderef->($mpv, $event, $data))
679
680This method registers a callback to be invoked for a specific
681event. Whenever the event occurs, it calls the coderef with the C<$mpv>
682object, the C<$event> name and the event object, just like the C<on_event>
683method.
684
685For a lst of events, see L<the mpv
686documentation|https://mpv.io/manual/stable/#list-of-events>. Any
687underscore in the event name is replaced by a minus sign, so you can
688specify event names using underscores for easier quoting in Perl.
689
690In void context, the handler stays registered until C<stop> is called. In
691any other context, it returns a guard object that, when destroyed, will
692unregister the handler.
693
694You can register multiple handlers for the same event, and this method
695does not interfere with the C<on_event> mechanism. That is, you can
696completely ignore this method and handle events in a C<on_event> handler,
697or mix both approaches as you see fit.
698
699=cut
700
663sub AnyEvent::MPV::Unobserve::DESTROY { 701sub AnyEvent::MPV::Unevent::DESTROY {
664 my ($mpv, $obscb, $obsid) = @{$_[0]}; 702 my ($evtcb, $evtid) = @{$_[0]};
665
666 delete $obscb->{$obsid}; 703 delete $evtcb->{$evtid};
704}
667 705
668 if ($obscb == $mpv->{obscb}) { 706sub register_event {
669 $mpv->cmd (unobserve_property => $obsid+0); 707 my ($self, $event, $cb) = @_;
670 } 708
709 $event =~ y/_/-/;
710
711 my $evtid = ++$self->{evtid};
712 $self->{evtcb}{$event}{$evtid} = $cb;
713
714 defined wantarray
715 and bless [$self->{evtcb}, $evtid], AnyEvent::MPV::Unevent::
671} 716}
672 717
673=item [$guard] = $mpv->observe_property ($name => $coderef->($mpv, $name, $value)) 718=item [$guard] = $mpv->observe_property ($name => $coderef->($mpv, $name, $value))
674 719
675=item [$guard] = $mpv->observe_property_string ($name => $coderef->($mpv, $name, $value)) 720=item [$guard] = $mpv->observe_property_string ($name => $coderef->($mpv, $name, $value))
718 763
719 () # ensure the above method is called in void context 764 () # ensure the above method is called in void context
720 } 765 }
721 766
722=cut 767=cut
768
769sub AnyEvent::MPV::Unobserve::DESTROY {
770 my ($mpv, $obscb, $obsid) = @{$_[0]};
771
772 delete $obscb->{$obsid};
773
774 if ($obscb == $mpv->{obscb}) {
775 $mpv->cmd (unobserve_property => $obsid+0);
776 }
777}
723 778
724sub _observe_property { 779sub _observe_property {
725 my ($self, $type, $property, $cb) = @_; 780 my ($self, $type, $property, $cb) = @_;
726 781
727 my $obsid = OBSID + ++$self->{obsid}; 782 my $obsid = OBSID + ++$self->{obsid};

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines