Wx::MediaCtrl

From WxPerl Wiki
Jump to: navigation, search

This is a great MediaCtrl sample Mark created to showcase new events.


#!/usr/bin/perl
use strict;
use warnings;

#------------------------------------------

package MediaSample::MediaPanel;

#------------------------------------------
use Wx qw( :everything );
use Wx::Media;
use base qw( Wx::Panel );
use Wx::Event qw(
    EVT_MEDIA_LOADED EVT_MEDIA_STOP EVT_MEDIA_FINISHED
    EVT_MEDIA_STATECHANGED EVT_MEDIA_PLAY EVT_MEDIA_PAUSE
    EVT_BUTTON
);

sub new {
    my ($class, $parent) = @_;
    my $self = $class->SUPER::new($parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL|wxBORDER_NONE);
    
    my $mswbackend = wxMEDIABACKEND_WMP10;
    #my $mswbackend = wxMEDIABACKEND_DIRECTSHOW;
    
    my $mediabackend = ( Wx::wxMSW() )
        ? $mswbackend
        : (  Wx::wxMAC() )
            ? wxMEDIABACKEND_QUICKTIME
            : wxMEDIABACKEND_GSTREAMER ;
    
    #----------------------------------
    # Controls
    #----------------------------------
    #$self->{currentfile} = Wx::TextCtrl->new($self, wxID_ANY, '', wxDefaultPosition, wxDefaultSize, wxTE_READONLY);
    $self->{mediacontrol} = Wx::MediaCtrl->new($self, wxID_ANY,'', wxDefaultPosition, wxDefaultSize, 0, $mediabackend );
    $self->{buttonload} = Wx::Button->new($self, wxID_ANY, 'Load');
    $self->{buttonuri} = Wx::Button->new($self, wxID_ANY, 'Load URI');
    $self->{buttonplay} = Wx::Button->new($self, wxID_ANY, 'Play');
    $self->{buttonpause} = Wx::Button->new($self, wxID_ANY, 'Pause');
    $self->{buttonstop} = Wx::Button->new($self, wxID_ANY, 'Stop');
    
    #----------------------------------
    # Events
    #----------------------------------
    
    EVT_MEDIA_LOADED($self, $self->{mediacontrol}, sub { shift->OnEventMediaLoaded( @_ ); });
    EVT_MEDIA_STOP($self, $self->{mediacontrol}, sub { shift->OnEventMediaStop( @_ ); });
    EVT_MEDIA_FINISHED($self, $self->{mediacontrol}, sub { shift->OnEventMediaFinished( @_ ); });
    
    #EVT_MEDIA_STATECHANGED($self, $self->{mediacontrol}, sub { shift->OnEventMediaStateChanged( @_ ); });
    #EVT_MEDIA_PLAY($self, $self->{mediacontrol}, sub { shift->OnEventMediaPlay( @_ ); });
    #EVT_MEDIA_PAUSE($self, $self->{mediacontrol}, sub { shift->OnEventMediaPause( @_ ); });
    
    EVT_BUTTON($self, $self->{buttonload}, sub { shift->OnEventButtonLoad( @_ ); });
    EVT_BUTTON($self, $self->{buttonuri}, sub { shift->OnEventButtonLoadURI( @_ ); });
    EVT_BUTTON($self, $self->{buttonplay}, sub { shift->OnEventButtonPlay( @_ ); });
    EVT_BUTTON($self, $self->{buttonpause}, sub { shift->OnEventButtonPause( @_ ); });
    EVT_BUTTON($self, $self->{buttonstop}, sub { shift->OnEventButtonStop( @_ ); });
    
    #----------------------------------
    # Layout
    #----------------------------------
    my $mainsizer = Wx::BoxSizer->new(wxVERTICAL);
    #$mainsizer->Add($self->{currentfile}, 0, wxEXPAND|wxALL, 0);
    $mainsizer->Add($self->{mediacontrol}, 1, wxEXPAND|wxALL, 0);
    $mainsizer->Add(Wx::StaticLine->new($self, -1), 0, wxEXPAND|wxALL, 5);
    
    my $buttonsizer = Wx::BoxSizer->new(wxHORIZONTAL);
    $buttonsizer->Add($self->{buttonload}, 0, wxEXPAND|wxALL, 3);
    $buttonsizer->Add($self->{buttonuri}, 0, wxEXPAND|wxALL, 3);
    $buttonsizer->Add($self->{buttonplay}, 0, wxEXPAND|wxALL, 3);
    $buttonsizer->Add($self->{buttonpause}, 0, wxEXPAND|wxALL, 3);
    $buttonsizer->Add($self->{buttonstop}, 0, wxEXPAND|wxALL, 3);
    
    $mainsizer->Add($buttonsizer, 0, wxALIGN_RIGHT|wxALL, 3);
    
    $self->SetSizer($mainsizer);
    
    #----------------------------------
    # State Values
    #----------------------------------
    
    $self->{medialoaded} = 0;
    $self->reset_state;
    return $self;
}

sub reset_state {
    my $self = shift;
    
    if(!$self->{medialoaded}) {
        $self->{buttonload}->Enable(1);
        $self->{buttonuri}->Enable(1);
        $self->{buttonplay}->Enable(0);
        $self->{buttonpause}->Enable(0);
        $self->{buttonstop}->Enable(0);
        return;
    }
    
    my $state = $self->{mediacontrol}->GetState;
    
    if($state == wxMEDIASTATE_PLAYING ) {
        $self->{buttonload}->Enable(0);
        $self->{buttonuri}->Enable(0);
        $self->{buttonplay}->Enable(0);
        $self->{buttonpause}->Enable(1);
        $self->{buttonstop}->Enable(1);
    } elsif($state == wxMEDIASTATE_STOPPED  ) {
        $self->{buttonload}->Enable(1);
        $self->{buttonuri}->Enable(1);
        $self->{buttonplay}->Enable(1);
        $self->{buttonpause}->Enable(0);
        $self->{buttonstop}->Enable(0);
    } else {
        # Paused
        $self->{buttonload}->Enable(0);
        $self->{buttonuri}->Enable(0);
        $self->{buttonplay}->Enable(1);
        $self->{buttonpause}->Enable(0);
        $self->{buttonstop}->Enable(1);
    }
}


sub OnEventMediaLoaded {
    my($self, $event) = @_;
    #$event->Skip(1);
    $self->{medialoaded} = 1;
    print qq(EVT MEDIA LOADED \n);
    $self->reset_state;
}

sub OnEventMediaStop {
    my($self, $event) = @_;
    #$event->Skip(1);
    if( $self->{mediastopping} ) {
        print qq(EVT MEDIA STOP \n);
        $self->{mediastopping} = 0;
    } else {
        $event->Veto();
         print qq(EVT MEDIA STOP VETOED\n);
    }
    $self->reset_state;
}

sub OnEventMediaFinished {
    my($self, $event) = @_;
    #$event->Skip(1);
    print qq(EVT MEDIA FINISHED \n);
    $self->reset_state;
}

sub OnEventMediaStateChanged {
    my($self, $event) = @_;
    #$event->Skip(1);
    print qq(EVT MEDIA STATECHANGED \n);
    $self->reset_state;
}

sub OnEventMediaPlay {
    my($self, $event) = @_;
    #$event->Skip(1);
    print qq(EVT MEDIA PLAY \n);
    $self->reset_state;
}

sub OnEventMediaPause {
    my($self, $event) = @_;
    $event->Skip(1);
    print qq(EVT MEDIA PAUSE \n);
    $self->reset_state;
}

sub OnEventButtonLoad {
    my($self, $event) = @_;
    $self->{mediacontrol}->Stop;
    my $file = Wx::FileSelector( 'Select a media file' );
    if( length( $file )  && !$self->{mediacontrol}->LoadFile( $file ) ) {
        Wx::LogError('Application failed to load %s', $file);
    }
    $self->reset_state;
}

sub OnEventButtonLoadURI {
    my($self, $event) = @_;
    
    my $uri;
    
    my $dialog = Wx::TextEntryDialog->new
        ( $self,
          'Enter an address to download',
          'Select Media URI',
          '',
        );
        
    if( $dialog->ShowModal != wxID_CANCEL ) {
        $uri = $dialog->GetValue;
    }
    
    $dialog->Destroy;
    
    print qq(LOADING $uri\n);
    
    if( length( $uri )  && !$self->{mediacontrol}->LoadURI( $uri ) ) {
        Wx::LogError('Application failed to load %s', $uri);
    }
}

sub OnEventButtonPlay {
    my($self, $event) = @_;
    $self->{mediacontrol}->Play;
    $self->reset_state;
}

sub OnEventButtonPause {
    my($self, $event) = @_;
    $self->{mediacontrol}->Pause;
    #$self->reset_state;
}

sub OnEventButtonStop {
    my($self, $event) = @_;
    $self->{mediastopping} = 1;
    $self->{mediacontrol}->Stop;
    #$self->reset_state;
}


#------------------------------------------

package MediaSample::Frame;

#------------------------------------------
use Wx qw( :everything );
use base qw( Wx::Frame );

sub new {
    my $class = shift;
    my $self = $class->SUPER::new(undef, wxID_ANY, 'MediaSample::Frame', wxDefaultPosition, [600,600]);
    
    $self->{mainpanel} = MediaSample::MediaPanel->new($self);
    my $mainsizer = Wx::BoxSizer->new(wxVERTICAL);
    $mainsizer->Add($self->{mainpanel}, 1, wxEXPAND|wxALL, 0);
    $self->SetSizer( $mainsizer );
    
    return $self;
}


#------------------------------------------

package MediaSample::App;

#------------------------------------------
use Wx qw( :everything );
use base qw( Wx::App );


sub new {
    my $class = shift;
    my $self = $class->SUPER::new();
    # note, OnInit will run before SUPER::new returns
    $self->GetTopWindow->Show(1);
    return $self;
}

sub OnInit {
    my $self = shift;
    
    my $mainwin = MediaSample::Frame->new();
    $self->SetTopWindow( $mainwin );
    
    return 1;
}



#------------------------------------------

package main;

#------------------------------------------

my $app = MediaSample::App->new();
$app->MainLoop;


1;

__END__