The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.

NAME

MPV::Simple::Pipe

SYNOPSIS

    use strict;
    use warnings;
    use utf8;
    use MPV::Simple::Pipe;
    use Tcl::Tk;
    use Time::HiRes qw(usleep);
    
    # 1) It is recommended to to create the MPV::Simple::Pipe object before TCL
    # interpreter because this forks and copies the perl environment
    # 2) If you want to handle events you have to pass a true value to the 
    # option event_handling 
    my $mpv = MPV::Simple::Pipe->new(event_handling => 1);
    
    my $int = Tcl::Tk->new();
    my $mw = $int->mainwindow();
    $mw->title("MPV::Simple example");  
    
    # Create the video frame
    my $f = $mw->Frame(-width => 640, -height => 480)->pack(-expand =>1,-fill => "both");
    
    # Until the video frame is mapped, we set up the MPV Player in this video frame
    $f->bind('<Map>' => sub {
        $f->bind('<Map>' => sub {});
        
        $mpv->initialize();
        
        # The video shall start paused here
        $mpv->set_property_string("pause","yes");
        
        # With the MPV property "wid" you can embed MPV in a foreign window
        # (therefore it was important, that $f is already mapped!)
        $mpv->set_property_string("wid",$f->id());
        
        # Load a video file
        $mpv->command("loadfile", "path_to_video.ogg");
    });
    
    my $b1 = $mw->Button(
        -text   =>  "Play",
        -command => sub {$mpv->set_property_string('pause','no')}
    )->pack(-side => 'left');
    my $b2 = $mw->Button(
        -text   =>  "Pause",
        -command => sub {$mpv->set_property_string('pause','yes')}
    )->pack(-side => 'left');
    my $b3 = $mw->Button(
        -text   =>  "Backward",
        -command => sub {$mpv->command('seek',-5)}
    )->pack(-side => 'left');
    my $b4 = $mw->Button(
        -text   =>  "Forward",
        -command => sub {$mpv->command('seek',5)}
    )->pack(-side => 'left');
    my $b5 = $mw->Button(
        -text   =>  "Close",
        # I recommend to destroy first the Tcl::Tk main window, and
        # then the mpv instance
        -command => sub {$mw->destroy();$mpv->terminate_destroy();}
    )->pack(-side => 'left');
    
    # In this example the Tcl loop coexists with the MPV loop
    # see L<https://docstore.mik.ua/orelly/perl3/tk/ch15_09.htm>
    # Another approach (especially if coexisting loops are not possible) 
    # would be using a timer, see MPV::Simple:JSON for an example
    loop($int);
    
    sub loop {
        my $int = shift;
        while ($int->Eval("info commands .")) { 
            while (my $stat = $int->DoOneEvent(Tcl::DONT_WAIT) ) {}
            while (my $event = $mpv->get_events() ){handle_event($event);}
            
            # Important: We add a little sleep to save CPU!
            usleep(100);
        }
        print "Shuting down..\n";
        $mpv->terminate_destroy();
    }
    
    # Event handler
    # If you set $opt{event_handling} to a true value in the constructor
    # the events are sent through a non-blocking pipe ($mpv->{evreader}) you can access 
    # events by the method $mpv->get_events(); which returns a hashref of the event
    # The event_ids can be translated to the event names with the global array 
    # $MPV::Simple::event_names[$id]
    sub handle_event {
        my $event = shift;
        if ($event->{event} eq "property-change") {
            print "prop ".$event->{name}." changed to ".$event->{data}." %\n";
        }
        else {
            print $event->{event}."\n";
        }
    }
    

DESCRIPTION

Using MPV::Simple as a seperate process to integrate it in a foreign event loop, especially to interact with GUI toolkits. The module give access to the same methods as MPV::Simple. Furthermore, if the option $opt{event_handling} is passed to a true value, events are passed trough a pipe ($mpv->{evreader}) which can be accessed by $mpv->get_events(). In this case you can and must handle the events by a repeatly call of a subroutine. See the example above.

Methods

The following methods exist. See MPV::Simple for a detailled description.

  • my $mpv = MPV::Simple->new()

  • $mpv->initialize()

  • $mpv->set_property_string('name','value');

  • $mpv->get_property_string('name');

  • $mpv->observe_property_string('name', id);

  • $mpv->unobserve_property(registered_id);

  • $mpv->command($command, @args);

  • $mpv->terminate_destroy() Note: After terminating you cannot use the MPV object anymore. Instead you have to create a new MPV object.

Error handling

You can use MPV::Simple::error_names(), MPV::Simple::check_error() and MPV::Simple::warn_error() to handle errors. See MPV::Simple for details.

SEE ALSO

See the doxygen documentation at https://github.com/mpv-player/mpv/blob/master/libmpv/client.h and the manual of the mpv media player in http://mpv.io.

2 POD Errors

The following errors were encountered while parsing the POD:

Around line 337:

'=item' outside of any '=over'

Around line 354:

You forgot a '=back' before '=head2'