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

Comparing AnyEvent-MPV/README (file contents):
Revision 1.4 by root, Wed Mar 22 19:37:00 2023 UTC vs.
Revision 1.5 by root, Sun Aug 11 02:54:52 2024 UTC

99 my $timer = AE::timer 2, 0, my $quit = AE::cv; 99 my $timer = AE::timer 2, 0, my $quit = AE::cv;
100 $quit->recv; 100 $quit->recv;
101 101
102 This specifies extra arguments in the constructor - these arguments are 102 This specifies extra arguments in the constructor - these arguments are
103 used every time you "->start" mpv, while the arguments to "->start" are 103 used every time you "->start" mpv, while the arguments to "->start" are
104 only used for this specific clal to0 "start". The argument --pause keeps 104 only used for this specific call to "start". The argument --pause keeps
105 mpv in pause mode (i.e. it does not play the file after loading it), and 105 mpv in pause mode (i.e. it does not play the file after loading it), and
106 "--idle=yes" tells mpv to not quit when it does not have a playlist - as 106 "--idle=yes" tells mpv to not quit when it does not have a playlist - as
107 no files are specified on the command line. 107 no files are specified on the command line.
108 108
109 To load a file, we then send it a "loadfile" command, which accepts, as 109 To load a file, we then send it a "loadfile" command, which accepts, as
110 first argument, the URL or path to a video file. To make sure mpv does 110 first argument, the URL or path to a video file. To make sure mpv does
111 not misinterpret the path as a URL, it was prefixed with ./ (similarly 111 not misinterpret the path as a URL, it was prefixed with ./ (similarly
112 to "protecting" paths in perls "open"). 112 to "protecting" paths in perls "open").
113 113
114 Since commands send *to* mpv are send in UTF-8, we need to escape the 114 Since commands send *to* mpv are send in UTF-8, we need to escape the
115 filename (which might be in any encoding) using the "esscape_binary" 115 filename (which might be in any encoding) using the "escape_binary"
116 method - this is not needed if your filenames are just ascii, or 116 method - this is not needed if your filenames are just ASCII, or
117 magically get interpreted correctly, but if you accept arbitrary 117 magically get interpreted correctly, but if you accept arbitrary
118 filenamews (e.g. from the user), you need to do this. 118 filenames (e.g. from the user), you need to do this.
119 119
120 The "cmd_recv" method then queues the command, waits for a reply and 120 The "cmd_recv" method then queues the command, waits for a reply and
121 returns the reply data (or croaks on error). mpv would, at this point, 121 returns the reply data (or croaks on error). mpv would, at this point,
122 load the file and, if everything was successful, show the first frame 122 load the file and, if everything was successful, show the first frame
123 and pause. Note that, since mpv is implement rather synchronously 123 and pause. Note that, since mpv is implement rather synchronously
126 the "loadfile" command itself will run successfully. 126 the "loadfile" command itself will run successfully.
127 127
128 To unpause, we send another command, "set", to set the "pause" property 128 To unpause, we send another command, "set", to set the "pause" property
129 to "no", this time using the "cmd" method, which queues the command, but 129 to "no", this time using the "cmd" method, which queues the command, but
130 instead of waiting for a reply, it immediately returns a condvar that 130 instead of waiting for a reply, it immediately returns a condvar that
131 cna be used to receive results. 131 can be used to receive results.
132 132
133 This should then cause mpv to start playing the video. 133 This should then cause mpv to start playing the video.
134 134
135 It then again waits two seconds and quits. 135 It then again waits two seconds and quits.
136 136
170 playing. Also, most of the logic is now implement in event handlers. 170 playing. Also, most of the logic is now implement in event handlers.
171 171
172 The two events handlers we register are "start-file", which is emitted 172 The two events handlers we register are "start-file", which is emitted
173 by mpv once it has loaded a new file, and "end-file", which signals the 173 by mpv once it has loaded a new file, and "end-file", which signals the
174 end of a file (underscores are internally replaced by minus signs, so 174 end of a file (underscores are internally replaced by minus signs, so
175 you cna speicfy event names with either). 175 you can specify event names with either).
176 176
177 In the "start-file" event, we again set the "pause" property to "no" so 177 In the "start-file" event, we again set the "pause" property to "no" so
178 the movie starts playing. For the "end-file" event, we tell the main 178 the movie starts playing. For the "end-file" event, we tell the main
179 program to quit by invoking $quit. 179 program to quit by invoking $quit.
180 180
216 Enables tracing if true. In trace mode, output from mpv is 216 Enables tracing if true. In trace mode, output from mpv is
217 printed to standard error using a "mpv>" prefix, and commands 217 printed to standard error using a "mpv>" prefix, and commands
218 sent to mpv are printed with a ">mpv" prefix. 218 sent to mpv are printed with a ">mpv" prefix.
219 219
220 If a code reference is passed, then instead of printing to 220 If a code reference is passed, then instead of printing to
221 standard errort, this coderef is invoked with a first arfgument 221 standard error, this coderef is invoked with a first argument
222 being either "mpv>" or ">mpv", and the second argument being a 222 being either "mpv>" or ">mpv", and the second argument being a
223 string to display. The default implementation simply does this: 223 string to display. The default implementation simply does this:
224 224
225 sub { 225 sub {
226 warn "$_[0] $_[1]\n"; 226 warn "$_[0] $_[1]\n";
231 on_key => $coderef->($mpv, $string) 231 on_key => $coderef->($mpv, $string)
232 These are invoked by the default method implementation of the 232 These are invoked by the default method implementation of the
233 same name - see below. 233 same name - see below.
234 234
235 $string = $mpv->escape_binary ($string) 235 $string = $mpv->escape_binary ($string)
236 This module excects all command data sent to mpv to be in unicode. 236 This module expects all command data sent to mpv to be in unicode.
237 Some things are not, such as filenames. To pass binary data such as 237 Some things are not, such as filenames. To pass binary data such as
238 filenames through a comamnd, you need to escape it using this 238 filenames through a command, you need to escape it using this
239 method. 239 method.
240 240
241 The simplest example is a "loadfile" command: 241 The simplest example is a "loadfile" command:
242 242
243 $mpv->cmd_recv (loadfile => $mpv->escape_binary ($path)); 243 $mpv->cmd_recv (loadfile => $mpv->escape_binary ($path));
244 244
245 $started = $mpv->start (argument...) 245 $started = $mpv->start (argument...)
246 Starts mpv, passing the given arguemnts as extra arguments to mpv. 246 Starts mpv, passing the given arguments as extra arguments to mpv.
247 If mpv is already running, it returns false, otherwise it returns a 247 If mpv is already running, it returns false, otherwise it returns a
248 true value, so you can easily start mpv on demand by calling "start" 248 true value, so you can easily start mpv on demand by calling "start"
249 just before using it, and if it is already running, it will not be 249 just before using it, and if it is already running, it will not be
250 started again. 250 started again.
251 251
252 The arguments passwd to mpv are a set of hardcoded built-in 252 The arguments passed to mpv are a set of hard-coded built-in
253 arguments, followed by the arguments specified in the constructor, 253 arguments, followed by the arguments specified in the constructor,
254 followed by the arguments passwd to this method. The built-in 254 followed by the arguments passed to this method. The built-in
255 arguments currently are --no-input-terminal, --really-quiet (or 255 arguments currently are --no-input-terminal, --really-quiet (or
256 --quiet in "trace" mode), and "--input-ipc-client" (or equivalent). 256 --quiet in "trace" mode), and "--input-ipc-client" (or equivalent).
257 257
258 Some commonly used and/or even useful arguments you might want to 258 Some commonly used and/or even useful arguments you might want to
259 pass are: 259 pass are:
361 $position = $mpv->cmd_recv ("get_property", "playback-time"); 361 $position = $mpv->cmd_recv ("get_property", "playback-time");
362 362
363 $mpv->bind_key ($INPUT => $string) 363 $mpv->bind_key ($INPUT => $string)
364 This is an extension implement by this module to make it easy to get 364 This is an extension implement by this module to make it easy to get
365 key events. The way this is implemented is to bind a 365 key events. The way this is implemented is to bind a
366 "client-message" witha first argument of "AnyEvent::MPV" and the 366 "client-message" with a first argument of "AnyEvent::MPV" and the
367 $string you passed. This $string is then passed to the "on_key" 367 $string you passed. This $string is then passed to the "on_key"
368 handle when the key is proessed, e.g.: 368 handle when the key is processed, e.g.:
369 369
370 my $mpv = AnyEvent::MPV->new ( 370 my $mpv = AnyEvent::MPV->new (
371 on_key => sub { 371 on_key => sub {
372 my ($mpv, $key) = @_; 372 my ($mpv, $key) = @_;
373 373
377 }, 377 },
378 ); 378 );
379 379
380 $mpv_>bind_key (ESC => "letmeout"); 380 $mpv_>bind_key (ESC => "letmeout");
381 381
382 You cna find a list of key names in the mpv documentation 382 You can find a list of key names in the mpv documentation
383 <https://mpv.io/manual/stable/#key-names>. 383 <https://mpv.io/manual/stable/#key-names>.
384 384
385 The key configuration is lost when mpv is stopped and must be 385 The key configuration is lost when mpv is stopped and must be
386 (re-)done after every "start". 386 (re-)done after every "start".
387 387
390 This method registers a callback to be invoked for a specific event. 390 This method registers a callback to be invoked for a specific event.
391 Whenever the event occurs, it calls the coderef with the $mpv 391 Whenever the event occurs, it calls the coderef with the $mpv
392 object, the $event name and the event object, just like the 392 object, the $event name and the event object, just like the
393 "on_event" method. 393 "on_event" method.
394 394
395 For a lst of events, see the mpv documentation 395 For a list of events, see the mpv documentation
396 <https://mpv.io/manual/stable/#list-of-events>. Any underscore in 396 <https://mpv.io/manual/stable/#list-of-events>. Any underscore in
397 the event name is replaced by a minus sign, so you can specify event 397 the event name is replaced by a minus sign, so you can specify event
398 names using underscores for easier quoting in Perl. 398 names using underscores for easier quoting in Perl.
399 399
400 In void context, the handler stays registered until "stop" is 400 In void context, the handler stays registered until "stop" is
424 424
425 For a list of properties that you can observe, see the mpv 425 For a list of properties that you can observe, see the mpv
426 documentation <https://mpv.io/manual/stable/#property-list>. 426 documentation <https://mpv.io/manual/stable/#property-list>.
427 427
428 Due to the (sane :) way mpv handles these requests, you will always 428 Due to the (sane :) way mpv handles these requests, you will always
429 get a property cxhange event right after registering an observer 429 get a property change event right after registering an observer
430 (meaning you don't have to query the current value), and it is also 430 (meaning you don't have to query the current value), and it is also
431 possible to register multiple observers for the same property - they 431 possible to register multiple observers for the same property - they
432 will all be handled properly. 432 will all be handled properly.
433 433
434 When called in void context, the observer stays in place until mpv 434 When called in void context, the observer stays in place until mpv
435 is stopped. In any otrher context, these methods return a guard 435 is stopped. In any other context, these methods return a guard
436 object that, when it goes out of scope, unregisters the observe 436 object that, when it goes out of scope, unregisters the observe
437 using "unobserve_property". 437 using "unobserve_property".
438 438
439 Internally, this method uses observer ids of 2**52 439 Internally, this method uses observer ids of 2**52
440 (0x10000000000000) or higher - it will not interfere with lower 440 (0x10000000000000) or higher - it will not interfere with lower
441 ovserver ids, so it is possible to completely ignore this system and 441 observer ids, so it is possible to completely ignore this system and
442 execute "observe_property" commands yourself, whilst listening to 442 execute "observe_property" commands yourself, whilst listening to
443 "property-change" events - as long as your ids stay below 2**52. 443 "property-change" events - as long as your ids stay below 2**52.
444 444
445 Example: register observers for changtes in "aid" and "sid". Note 445 Example: register observers for changes in "aid" and "sid". Note
446 that a dummy statement is added to make sure the method is called in 446 that a dummy statement is added to make sure the method is called in
447 void context. 447 void context.
448 448
449 sub register_observers { 449 sub register_observers {
450 my ($mpv) = @_; 450 my ($mpv) = @_;
465 SUBCLASSING 465 SUBCLASSING
466 Like most perl objects, "AnyEvent::MPV" objects are implemented as 466 Like most perl objects, "AnyEvent::MPV" objects are implemented as
467 hashes, with the constructor simply storing all passed key-value pairs 467 hashes, with the constructor simply storing all passed key-value pairs
468 in the object. If you want to subclass to provide your own "on_*" 468 in the object. If you want to subclass to provide your own "on_*"
469 methods, be my guest and rummage around in the internals as much as you 469 methods, be my guest and rummage around in the internals as much as you
470 wish - the only guarantee that this module dcoes is that it will not use 470 wish - the only guarantee that this module does is that it will not use
471 keys with double colons in the name, so youc an use those, or chose to 471 keys with double colons in the name, so you can use those, or chose to
472 simply not care and deal with the breakage. 472 simply not care and deal with the breakage.
473 473
474 If you don't want to go to the effort of subclassing this module, you 474 If you don't want to go to the effort of subclassing this module, you
475 can also specify all event handlers as constructor keys. 475 can also specify all event handlers as constructor keys.
476 476
478 Here are some real-world code snippets, thrown in here mainly to give 478 Here are some real-world code snippets, thrown in here mainly to give
479 you some example code to copy. 479 you some example code to copy.
480 480
481 doomfrontend 481 doomfrontend
482 At one point I replaced mythtv-frontend by my own terminal-based video 482 At one point I replaced mythtv-frontend by my own terminal-based video
483 player (based on rxvt-unicode). I toyed with the diea of using mpv's 483 player (based on rxvt-unicode). I toyed with the idea of using mpv's
484 subtitle engine to create the user interface, but that is hard to use 484 subtitle engine to create the user interface, but that is hard to use
485 since you don't know how big your letters are. It is also where most of 485 since you don't know how big your letters are. It is also where most of
486 this modules code has originally been developed in. 486 this modules code has originally been developed in.
487 487
488 It uses a unified input queue to handle various remote controls, so its 488 It uses a unified input queue to handle various remote controls, so its
513 513
514 --audio-client-name=doomfrontend 514 --audio-client-name=doomfrontend
515 --osd-on-seek=msg-bar --osd-bar-align-y=-0.85 --osd-bar-w=95 515 --osd-on-seek=msg-bar --osd-bar-align-y=-0.85 --osd-bar-w=95
516 --sub-auto=exact --audio-file-auto=exact 516 --sub-auto=exact --audio-file-auto=exact
517 517
518 Since it runs on a TV without a desktop environemnt, it tries to keep 518 Since it runs on a TV without a desktop environment, it tries to keep
519 complications such as dbus away and the screensaver happy: 519 complications such as dbus away and the screensaver happy:
520 520
521 # prevent xscreensaver from doing something stupid, such as starting dbus 521 # prevent xscreensaver from doing something stupid, such as starting dbus
522 $ENV{DBUS_SESSION_BUS_ADDRESS} = "/"; # prevent dbus autostart for sure 522 $ENV{DBUS_SESSION_BUS_ADDRESS} = "/"; # prevent dbus autostart for sure
523 $ENV{XDG_CURRENT_DESKTOP} = "generic"; 523 $ENV{XDG_CURRENT_DESKTOP} = "generic";
547 KP_INS => 0, # KP0, but different 547 KP_INS => 0, # KP0, but different
548 ) { 548 ) {
549 $mpv->bind_key ($_->[0] => $_->[1]); 549 $mpv->bind_key ($_->[0] => $_->[1]);
550 } 550 }
551 551
552 It also reacts to sponsorblock chapters, so it needs to know when vidoe 552 It also reacts to sponsorblock chapters, so it needs to know when video
553 chapters change. Preadting "AnyEvent::MPV", it handles observers 553 chapters change. Predating "AnyEvent::MPV", it handles observers
554 manually: 554 manually instead of using "observe_property":
555 555
556 $mpv->cmd (observe_property => 1, "chapter-metadata"); 556 $mpv->cmd (observe_property => 1, "chapter-metadata");
557 557
558 It also tries to apply an mpv profile, if it exists: 558 It also tries to apply an mpv profile, if it exists:
559 559
563 }; 563 };
564 564
565 Most of the complicated parts deal with saving and restoring per-video 565 Most of the complicated parts deal with saving and restoring per-video
566 data, such as bookmarks, playing position, selected audio and subtitle 566 data, such as bookmarks, playing position, selected audio and subtitle
567 tracks and so on. However, since it uses Coro, it can conveniently block 567 tracks and so on. However, since it uses Coro, it can conveniently block
568 and wait for replies, which is n ot possible in purely event based 568 and wait for replies, which is not possible in purely event based
569 programs, as you are not allowed to block inside event callbacks in most 569 programs, as you are not allowed to block inside event callbacks in most
570 event loops. This simplifies the code quite a bit. 570 event loops. This simplifies the code quite a bit.
571 571
572 When the file to be played is a Tv recording done by mythtv, it uses the 572 When the file to be played is a TV recording done by mythtv, it uses the
573 "appending" protocol and deinterlacing: 573 "appending" protocol and deinterlacing:
574 574
575 if (is_myth $mpv_path) { 575 if (is_myth $mpv_path) {
576 $mpv_path = "appending://$mpv_path"; 576 $mpv_path = "appending://$mpv_path";
577 $initial_deinterlace = 1; 577 $initial_deinterlace = 1;
638 638
639 $mpv->cmd ("set_property", "deinterlace", "yes") 639 $mpv->cmd ("set_property", "deinterlace", "yes")
640 if $initial_deinterlace; 640 if $initial_deinterlace;
641 641
642 There is a lot going on here. First it seeks to the actual playback 642 There is a lot going on here. First it seeks to the actual playback
643 position, if it is not at the start of the file (it would probaby be 643 position, if it is not at the start of the file (it would probably be
644 more efficient to set the starting position before loading the file, 644 more efficient to set the starting position before loading the file,
645 though, but this is good enough). 645 though, but this is good enough).
646 646
647 Then it plays with the display fps, to set it to something harmonious 647 Then it plays with the display fps, to set it to something harmonious
648 w.r.t. the video framerate. 648 w.r.t. the video framerate.
650 If the file does not have a video part, it assumes it is an audio file 650 If the file does not have a video part, it assumes it is an audio file
651 and sets a visualizer. 651 and sets a visualizer.
652 652
653 Also, a number of properties are not global, but per-file. At the 653 Also, a number of properties are not global, but per-file. At the
654 moment, this is "audio-delay", and the current audio/subtitle track, 654 moment, this is "audio-delay", and the current audio/subtitle track,
655 which it sets, and also creates an observer. Again, this doesn'T use the 655 which it sets, and also creates an observer. Again, this doesn't use the
656 observe functionality of this module, but handles it itself, assigning 656 observe functionality of this module, but handles it itself, assigning
657 obsevrer ids 100+ to temporary/per-file observers. 657 observer ids 100+ to temporary/per-file observers.
658 658
659 Lastly, it sets some global (or per-youtube-uploader) parameters, such 659 Lastly, it sets some global (or per-youtube-uploader) parameters, such
660 as speed, and unpauses. Property changes are handled like other input 660 as speed, and unpauses. Property changes are handled like other input
661 events: 661 events:
662 662
735 $mpv->cmd ("unobserve_property", $oid--); 735 $mpv->cmd ("unobserve_property", $oid--);
736 } 736 }
737 737
738 $PLAYING_STATE->{curpos} = $mpv->cmd_recv ("get_property", "playback-time"); 738 $PLAYING_STATE->{curpos} = $mpv->cmd_recv ("get_property", "playback-time");
739 739
740 And thats most of the mpv-related code. 740 And that's most of the mpv-related code.
741 741
742 Gtk2::CV 742 Gtk2::CV
743 Gtk2::CV is low-feature image viewer that I use many times daily because 743 Gtk2::CV is low-feature image viewer that I use many times daily because
744 it can handle directories with millions of files without falling over. 744 it can handle directories with millions of files without falling over.
745 It also had the ability to play videos for ages, but it used an older, 745 It also had the ability to play videos for ages, but it used an older,
746 crappier protocol to talk to mpv and used ffprobe before playing each 746 crappier protocol to talk to mpv and used ffprobe before playing each
747 file instead of letting mpv handle format/size detection. 747 file instead of letting mpv handle format/size detection.
748 748
749 After writing this module, I decided to upgprade Gtk2::CV by making use 749 After writing this module, I decided to upgrade Gtk2::CV by making use
750 of it, with the goal of getting rid of ffprobe and being ablew to reuse 750 of it, with the goal of getting rid of ffprobe and being able to reuse
751 mpv processes, which would have a multitude of speed benefits (for 751 mpv processes, which would have a multitude of speed benefits (for
752 example, fork+exec of mpv caused the kernel to close all file 752 example, fork+exec of mpv caused the kernel to close all file
753 descriptors, which could take minutes if a large file was being copied 753 descriptors, which could take minutes if a large file was being copied
754 via NFS, as the kernel waited for thr buffers to be flushed on close - 754 via NFS, as the kernel waited for the buffers to be flushed on close -
755 not having to start mpv gets rid of this issue). 755 not having to start mpv gets rid of this issue).
756 756
757 Setting up is only complicated by the fact that mpv needs to be embedded 757 Setting up is only complicated by the fact that mpv needs to be embedded
758 into an existing window. To keep control of all inputs, Gtk2::CV puts an 758 into an existing window. To keep control of all inputs, Gtk2::CV puts an
759 eventbox in front of mpv, so mpv receives no input events: 759 eventbox in front of mpv, so mpv receives no input events:
805 ); 805 );
806 806
807 $self->{mpv}->cmd ("script-message" => "osc-visibility" => "never", "dummy"); 807 $self->{mpv}->cmd ("script-message" => "osc-visibility" => "never", "dummy");
808 $self->{mpv}->cmd ("osc-idlescreen" => "no"); 808 $self->{mpv}->cmd ("osc-idlescreen" => "no");
809 809
810 It also prepares a hack to force a ConfigureNotify event on every vidoe 810 It also prepares a hack to force a ConfigureNotify event on every video
811 reconfig: 811 reconfig event:
812 812
813 # force a configurenotify on every video-reconfig 813 # force a configurenotify on every video-reconfig
814 $self->{mpv_reconfig} = $self->{mpv}->register_event (video_reconfig => sub { 814 $self->{mpv_reconfig} = $self->{mpv}->register_event (video_reconfig => sub {
815 my ($mpv, $event, $data) = @_; 815 my ($mpv, $event, $data) = @_;
816 816
832 $self->{mpv}->cmd (set_property => "pause" => "yes"); 832 $self->{mpv}->cmd (set_property => "pause" => "yes");
833 $self->{mpv}->cmd ("playlist_remove", "current"); 833 $self->{mpv}->cmd ("playlist_remove", "current");
834 $self->{mpv}->cmd (set_property => "video-rotate" => 0); 834 $self->{mpv}->cmd (set_property => "video-rotate" => 0);
835 $self->{mpv}->cmd (set_property => "lavfi-complex" => ""); 835 $self->{mpv}->cmd (set_property => "lavfi-complex" => "");
836 836
837 Loading a file is a bit more complicated, as bluray and DVD rips are 837 Loading a file is a bit more complicated, as blu-ray and DVD rips are
838 supported: 838 supported:
839 839
840 if ($moviedir) { 840 if ($moviedir) {
841 if ($moviedir eq "br") { 841 if ($moviedir eq "br") {
842 $mpv->cmd (set => "bluray-device" => $path); 842 $mpv->cmd (set => "bluray-device" => $path);
854 854
855 After this, "Gtk2::CV" waits for the file to be loaded, video to be 855 After this, "Gtk2::CV" waits for the file to be loaded, video to be
856 configured, and then queries the video size (to resize its own window) 856 configured, and then queries the video size (to resize its own window)
857 and video format (to decide whether an audio visualizer is needed for 857 and video format (to decide whether an audio visualizer is needed for
858 audio playback). The problematic word here is "wait", as this needs to 858 audio playback). The problematic word here is "wait", as this needs to
859 be imploemented using callbacks. 859 be implemented using callbacks.
860 860
861 This made the code much harder to write, as the whole setup is very 861 This made the code much harder to write, as the whole setup is very
862 asynchronous ("Gtk2::CV" talks to the command interface in mpv, which 862 asynchronous ("Gtk2::CV" talks to the command interface in mpv, which
863 talks to the decode and playback parts, all of which run asynchronously 863 talks to the decode and playback parts, all of which run asynchronously
864 w.r.t. each other. In practise, this can mean that "Gtk2::CV" waits for 864 w.r.t. each other. In practise, this can mean that "Gtk2::CV" waits for
880 880
881 $guards->{file_loaded} = $mpv->register_event (file_loaded => sub { 881 $guards->{file_loaded} = $mpv->register_event (file_loaded => sub {
882 delete $guards->{file_loaded}; 882 delete $guards->{file_loaded};
883 return if $guards != $self->{mpv_guards}; 883 return if $guards != $self->{mpv_guards};
884 884
885 Commands do not have guards since they cnanot be cancelled, so we don't 885 Commands do not have guards since they cannot be cancelled, so we don't
886 have to do this for commands. But what prevents us form misinterpreting 886 have to do this for commands. But what prevents us form misinterpreting
887 an old event? Since mpv (by default) handles commands synchronously, we 887 an old event? Since mpv (by default) handles commands synchronously, we
888 can queue a dummy command, whose only purpose is to tell us when all 888 can queue a dummy command, whose only purpose is to tell us when all
889 previous commands are done. We use "get_version" for this. 889 previous commands are done. We use "get_version" for this.
890 890

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines