#!/usr/bin/perl -w -- use Wx 0.15 qw[:allclasses]; use strict; package MyFrame; use Wx qw[:everything]; use base qw(Wx::Frame); use strict; sub new { my( $self, $parent, $id, $title, $pos, $size, $style, $name ) = @_; $style = wxDEFAULT_FRAME_STYLE unless defined $style; $self = $self->SUPER::new( undef, wxID_ANY, "Draw/Video Controls", wxDefaultPosition, wxDefaultSize, $style, "" ); $self->SetTitle("Draw/Video Controls"); # # Wx::Timer # $self->{TIMER} = Wx::Timer->new( $self, 1 ); $self->{TIMER}->Start( 200 ); Wx::Event::EVT_TIMER( $self, 1, \&on_timer ); # Events # Wx::Event::EVT_SCROLL_THUMBTRACK( $self, \&on_slider ); # Define parents of split $self->{Ctl_Post_Exam_Videos_Sizer_2} = Wx::BoxSizer->new(wxVERTICAL); # Top-level left-hand sizer (contains media) # # Video panel. # # wxMEDIABACKEND_DIRECTSHOW Use ActiveMovie/DirectShow. Requires wxUSE_DIRECTSHOW to be enabled, requires linkage with the static library strmiids.lib, and is available on Windows Only. # wxMEDIABACKEND_QUICKTIME Use QuickTime. Windows and Mac Only. NOTE: On Mac Systems lower than OSX 10.2 this defaults to emulating window positioning and suffers from several bugs, including not working correctly embedded in a wxNotebook. # wxMEDIABACKEND_MCI Use Media Command Interface. Windows Only. # wxMEDIABACKEND_GSTREAMER Use GStreamer. Unix Only. # wxMEDIABACKEND_WMP10 Windows Media Player 9 or 10 # wxMEDIABACKEND_REALPLAYER Realplayer # Blank Allow to choose own player $self->{Ctl_Videos_Media}= Wx::MediaCtrl->new( $self, wxID_ANY, '', wxDefaultPosition, wxDefaultSize,0, ); $self->{Ctl_Videos_Media}->Show( 1 ); $self->{Ctl_Videos_Media}->ShowPlayerControls(wxMEDIACTRLPLAYERCONTROLS_NONE); # or wxMEDIACTRLPLAYERCONTROLS_NONE # wxMEDIACTRLPLAYERCONTROLS_STEP # wxMEDIACTRLPLAYERCONTROLS_VOLUME # wxMEDIACTRLPLAYERCONTROLS_DEFAULT $self->{Ctl_Post_Exam_Videos_Sizer_2}->Add( $self->{Ctl_Videos_Media}, 1, wxEXPAND|wxALL, 5 ); # # Draw Slider and end labels # $self->{Ctl_Media_Slider_Szr} = Wx::BoxSizer->new(wxHORIZONTAL); # second-level left-hand sizer (contains slider) my $loc_post_exam_videos_panel=$self; $self->{Ctl_Media_Slider_Start_Lbl} = Wx::StaticText-> new($loc_post_exam_videos_panel, wxID_ANY, "0", wxDefaultPosition, wxDefaultSize, ); $self->{Ctl_Media_Slider_Szr}->Add($self->{Ctl_Media_Slider_Start_Lbl}, 0, 0, 0); $self->{Ctl_Media_Slider_Sld} = Wx::Slider-> new($loc_post_exam_videos_panel, wxID_ANY, 0, 0, 10, wxDefaultPosition, wxDefaultSize, wxSL_HORIZONTAL); # |wxSL_AUTOTICKS|wxSL_LABELS $self->{Ctl_Media_Slider_Sld}->SetMinSize(Wx::Size->new(300, -1)); $self->{Ctl_Media_Slider_Sld}->SetToolTipString(("Drag slider to re-position video.")); $self->{Ctl_Media_Slider_Szr}->Add($self->{Ctl_Media_Slider_Sld}, 0, 0, 0); $self->{Ctl_Media_Slider_End_Lbl} = Wx::StaticText-> new($loc_post_exam_videos_panel, wxID_ANY, "100", wxDefaultPosition, wxDefaultSize, ); $self->{Ctl_Media_Slider_Szr}->Add($self->{Ctl_Media_Slider_End_Lbl}, 0, 0, 0); # # Draw buttons # $self->{Ctl_Media_Button_Szr} = Wx::BoxSizer->new(wxHORIZONTAL); # third-level left-hand sizer (contains buttons) $self->{Ctl_Media_Rewind_Btn} = Wx::Button-> new($loc_post_exam_videos_panel, wxID_ANY, "<<", wxDefaultPosition, [40,-1] ); $self->{Ctl_Media_Rewind_Btn}->SetSize($self->{Ctl_Media_Rewind_Btn}->GetBestSize()); $self->{Ctl_Media_Button_Szr}->Add($self->{Ctl_Media_Rewind_Btn}, 0, 0, 2); $self->{Ctl_Media_Rewind_Btn}->Enable(1); $self->{Ctl_Media_Rewind_Btn}->SetToolTipString(("Rewinds 30 seconds.")); Wx::Event::EVT_BUTTON( $self, $self->{Ctl_Media_Rewind_Btn}, \&on_media_rw ); $self->{Ctl_Media_Play_Btn} = Wx::Button-> new($loc_post_exam_videos_panel, wxID_ANY, ">", wxDefaultPosition, [40,-1] ); $self->{Ctl_Media_Play_Btn}->SetSize($self->{Ctl_Media_Play_Btn}->GetBestSize()); $self->{Ctl_Media_Play_Btn}->Enable(1); $self->{Ctl_Media_Play_Btn}->SetToolTipString(("Play/resume media clip.")); Wx::Event::EVT_BUTTON( $self, $self->{Ctl_Media_Play_Btn}, \&on_media_play ); $self->{Ctl_Media_Button_Szr}->Add($self->{Ctl_Media_Play_Btn}, 0, 0, 2); $self->{Ctl_Media_Pause_Btn} = Wx::Button-> new($loc_post_exam_videos_panel, wxID_ANY, "||", wxDefaultPosition, [40,-1] ); $self->{Ctl_Media_Pause_Btn}->SetSize($self->{Ctl_Media_Pause_Btn}->GetBestSize()); $self->{Ctl_Media_Button_Szr}->Add($self->{Ctl_Media_Pause_Btn}, 0, 0, 2); $self->{Ctl_Media_Pause_Btn}->Enable(1); $self->{Ctl_Media_Pause_Btn}->SetToolTipString(("Pause media clip.")); Wx::Event::EVT_BUTTON( $self, $self->{Ctl_Media_Pause_Btn}, \&on_media_pause ); $self->{Ctl_Media_Record_Btn} = Wx::Button-> new($loc_post_exam_videos_panel, wxID_ANY, "Record", wxDefaultPosition, [40,-1] ); $self->{Ctl_Media_Record_Btn}->SetSize($self->{Ctl_Media_Record_Btn}->GetBestSize()); $self->{Ctl_Media_Button_Szr}->Add($self->{Ctl_Media_Record_Btn}, 0, 0, 2); $self->{Ctl_Media_Record_Btn}->Show(0); # Set to 1 or zero depending on whether you are debugging or not. $self->{Ctl_Media_Record_Btn}->Enable(1); $self->{Ctl_Media_Record_Btn}->SetToolTipString(("Press red button to start record of media clip. Press black button to complete.")); $self->{Ctl_Media_Ffwd_Btn} = Wx::Button-> new($loc_post_exam_videos_panel, wxID_ANY, ">>", wxDefaultPosition, [40,-1] ); $self->{Ctl_Media_Ffwd_Btn}->SetSize($self->{Ctl_Media_Ffwd_Btn}->GetBestSize()); $self->{Ctl_Media_Ffwd_Btn}->Enable(1); $self->{Ctl_Media_Ffwd_Btn}->SetToolTipString(("Forwards 30 seconds.")); $self->{Ctl_Media_Button_Szr}->Add($self->{Ctl_Media_Ffwd_Btn}, 0, 0, 2); Wx::Event::EVT_BUTTON( $self, $self->{Ctl_Media_Ffwd_Btn}, \&on_media_ff ); $self->{Ctl_Media_Open_Btn} = Wx::Button-> new($loc_post_exam_videos_panel, wxID_ANY, "Open", wxDefaultPosition, wxDefaultSize ); $self->{Ctl_Media_Open_Btn}->Show(1); # Set to 1 or zero depending on whether you are debugging or not. $self->{Ctl_Media_Open_Btn}->SetToolTipString(("Press to open previous clip. Clip is saved in media folder.")); $self->{Ctl_Media_Open_Btn}->SetSize($self->{Ctl_Media_Open_Btn}->GetBestSize()); $self->{Ctl_Media_Button_Szr}->Add($self->{Ctl_Media_Open_Btn}, 0, 0, 2); Wx::Event::EVT_BUTTON( $self, $self->{Ctl_Media_Open_Btn}, \&on_media_load ); $self->{Ctl_Media_OpenURI_Btn} = Wx::Button-> new($loc_post_exam_videos_panel, wxID_ANY, "Camera"); $self->{Ctl_Media_OpenURI_Btn}->Show(1); # Set to 1 or zero depending on whether you are debugging or not. $self->{Ctl_Media_OpenURI_Btn}->SetToolTipString(("Press to open previous clip. Clip is saved in media folder.")); $self->{Ctl_Media_OpenURI_Btn}->SetSize($self->{Ctl_Media_OpenURI_Btn}->GetBestSize()); $self->{Ctl_Media_Button_Szr}->Add($self->{Ctl_Media_OpenURI_Btn}, 0, 0, 2); Wx::Event::EVT_BUTTON( $self, $self->{Ctl_Media_OpenURI_Btn}, \&on_media_loadURI ); $self->{Ctl_Post_Exam_Videos_Sizer_2}->Add($self->{Ctl_Media_Slider_Szr}, 0, wxALL|wxEXPAND, 5); $self->{Ctl_Post_Exam_Videos_Sizer_2}->Add($self->{Ctl_Media_Button_Szr}, 0, wxALL|wxEXPAND, 5); $self->{Ctl_Videos_Log}= Wx::LogWindow->new( $self, 'Log', 1,1 ); $self->SetSizer($self->{Ctl_Post_Exam_Videos_Sizer_2}); $self->Layout(); Wx::Event::EVT_MEDIA_LOADED( $self, $self->{Ctl_Videos_Media}, \&on_media_loaded ); return $self; } sub on_media_loaded { my( $self, $event ) = @_; $self->{Ctl_Videos_Media}->Play; on_media_play(@_); } sub on_media_ff { # # subroutine to update slider control # my( $i_frame, $event ) = @_; my $loc_bcur = Wx::BusyCursor->new; # Create hourglass within current scope. Hourglass is deleted on exit. my $loc_new_value = $i_frame->{Ctl_Videos_Media}->Tell()+30000; $i_frame->{Ctl_Media_Slider_Sld}->SetValue($loc_new_value/1000); # Set slider Move forwards 30 seconds. $i_frame->{Ctl_Videos_Media}->Seek($loc_new_value, wxFromStart); my $time_in_secs = Wx::Slider::GetValue($i_frame->{Ctl_Media_Slider_Sld}); my $length_in_secs=($i_frame->{Ctl_Videos_Media}->Length())/1000; # Only works after a 'play' command. my $ss = $length_in_secs % 60; if (length($ss) == 1) {$ss = "0" . $ss} # zerp pad seconds my $loc_length_hhhss = int($length_in_secs / 60) . ":" . $ss ; $ss = $time_in_secs % 60; if (length($ss) == 1) {$ss = "0" . $ss} # zerp pad seconds my $loc_time_hhhss = int($time_in_secs / 60) . ":" . $ss ; $i_frame->{Ctl_Media_Slider_End_Lbl}->SetLabel(" ".$loc_time_hhhss."/".$loc_length_hhhss); # Set max video length in mm:ss. } sub on_media_rw { # # subroutine to update slider control # my( $i_frame, $event ) = @_; my $loc_bcur = Wx::BusyCursor->new; # Create hourglass within current scope. Hourglass is deleted on exit. my $loc_new_value = $i_frame->{Ctl_Videos_Media}->Tell()-30000; if (defined $i_frame->{mediafile_clip_start}){ if ($i_frame->{mediafile_clip_start} ne ''){ if($loc_new_value < ($i_frame->{mediafile_clip_start}) * 1000){ # Rewind can't precede record start during clip record. $loc_new_value =$i_frame->{mediafile_clip_start} * 1000; } } } if ($loc_new_value<0) {$loc_new_value=0} # If negative, set to beginning of video $i_frame->{Ctl_Media_Slider_Sld}->SetValue($loc_new_value/1000); # Set slider to move backwards 30 seconds. $i_frame->{Ctl_Videos_Media}->Seek($loc_new_value, wxFromStart); # Set media to move backwards 30 seconds. my $time_in_secs = Wx::Slider::GetValue($i_frame->{Ctl_Media_Slider_Sld}); my $length_in_secs=($i_frame->{Ctl_Videos_Media}->Length())/1000; # Only works after a 'play' command. my $ss = $length_in_secs % 60; if (length($ss) == 1) {$ss = "0" . $ss} # zerp pad seconds my $loc_length_hhhss = int($length_in_secs / 60) . ":" . $ss ; $ss = $time_in_secs % 60; if (length($ss) == 1) {$ss = "0" . $ss} # zerp pad seconds my $loc_time_hhhss = int($time_in_secs / 60) . ":" . $ss ; $i_frame->{Ctl_Media_Slider_End_Lbl}->SetLabel(" ".$loc_time_hhhss."/".$loc_length_hhhss); # Set max video length in mm:ss. } sub on_slider { # # subroutine to update slider control # my( $i_frame, $event ) = @_; my $time_in_secs = Wx::Slider::GetValue($i_frame->{Ctl_Media_Slider_Sld}); if (defined $i_frame->{mediafile_clip_start}){ if ($i_frame->{mediafile_clip_start} ne ''){ if($time_in_secs < $i_frame->{mediafile_clip_start}){ # Slider can't precede record start during clip record. $time_in_secs =$i_frame->{mediafile_clip_start}; } } } $i_frame->{Ctl_Videos_Media}->Seek($time_in_secs*1000, wxFromStart); # Set video to slider position in msecs. my $length_in_secs=($i_frame->{Ctl_Videos_Media}->Length())/1000; # Only works after a 'play' command. my $ss = $length_in_secs % 60; if (length($ss) == 1) {$ss = "0" . $ss} # zero pad seconds my $loc_length_hhhss = int($length_in_secs / 60) . ":" . $ss ; $ss = $time_in_secs % 60; if (length($ss) == 1) {$ss = "0" . $ss} # zero pad seconds my $loc_time_hhhss = int($time_in_secs / 60) . ":" . $ss ; $i_frame->{Ctl_Media_Slider_End_Lbl}->SetLabel(" ".$loc_time_hhhss."/".$loc_length_hhhss); # Set max video length in mm:ss. } sub on_media_play { my( $i_frame, $event ) = @_; $i_frame->{Ctl_Videos_Media}->Play; my $length_in_secs=($i_frame->{Ctl_Videos_Media}->Length())/1000; # Only works after a 'play' command. $i_frame->{mediafile_length}= $length_in_secs ; # Store length of video in '$i_frame' in secs $length_in_secs = int($length_in_secs); # Round length to display correctly $i_frame->{Ctl_Media_Slider_Sld}->SetRange(0,$length_in_secs); # Set max video length in secs. my $ss = $length_in_secs % 60; if (length($ss) == 1) {$ss = "0" . $ss} # zerp pad seconds my $hhss = int($length_in_secs / 60) . ":" . $ss ; $i_frame->{Ctl_Media_Slider_End_Lbl}->SetLabel("0/".$hhss); # Set max video length in mm:ss. if (not defined $i_frame->{mediafile_clip_start}){ $i_frame->{mediafile_clip_start}=""; # Set clip start. } if (not defined $i_frame->{mediafile_clip_end}){ $i_frame->{mediafile_clip_end}=""; # Set clip end. } $i_frame->{Ctl_Media_Button_Szr}->Layout(); } sub on_media_load { # # Load file button selected # my( $i_frame, $event ) = @_; #my $file = '/usr/bin/gst-launch-0.10 v4l2src ! tee name=videoout ! queue ! videorate ! video/x-raw-yuv,fps=15 ! queue ! theoraenc quality=60 ! queue ! muxout. oggmux name=muxout ! filesink location=lulz.ogg videoout. ! queue ! ffmpegcolorspace ! ximagesink'; my $file = Wx::FileSelector('Choose a media file'); # Select video file if( length( $file ) ) { my $false = $i_frame->{Ctl_Videos_Media}->LoadFile ($file); # Load video file print $false,"\n"; #print $i_frame->{Ctl_Videos_Media}->LoadURI ('file:///dev/video0'); # Load video file $i_frame->{mediafile}= $file; # Store location of video file in '$i_frame } $i_frame->{mediafile_clip_start}=""; # Set clip start. $i_frame->{mediafile_clip_end}=""; # Set clip end. } sub on_media_loadURI { # # Load file button selected # my( $i_frame, $event ) = @_; my $file = 'file:///dev/video0'; # Select video source my $false = $i_frame->{Ctl_Videos_Media}->LoadURI ($file); # Load video source print $false,"\n"; $i_frame->{mediafile}= $file; # Store location of video source in '$i_frame $i_frame->{mediafile_clip_start}=""; # Set clip start. $i_frame->{mediafile_clip_end}=""; # Set clip end. } sub on_media_pause { my( $i_frame, $event ) = @_; my $time_in_msecs; my $time_in_secs; $i_frame->{Ctl_Videos_Media}->Pause(); $time_in_msecs=$i_frame->{Ctl_Videos_Media}->Tell(); $time_in_secs=$time_in_msecs/1000; $i_frame->{Ctl_Media_Button_Szr}->Layout(); } sub on_media_stop { my( $i_frame, $event ) = @_; $i_frame->{Ctl_Videos_Media}->Stop; } sub on_timer { # # subroutine to perform periodic processing # my( $i_frame, $event ) = @_; my $time_in_msecs; my $time_in_secs; if (defined $i_frame->{Ctl_Media_Snap_Time} ){ # and $gl_media_control_available == 1){ if ($i_frame->{Ctl_Media_Snap_Time} ne ""){ $time_in_msecs=$i_frame->{Ctl_Videos_Media}->Play(); # Restarts playback. $i_frame->{Ctl_Media_Snap_Time}=""; # Clears snap time of photo } } ######## update slider control position ################################################# $time_in_msecs=$i_frame->{Ctl_Videos_Media}->Tell(); # Obtains the current position in time within the movie in milliseconds. $time_in_secs=$time_in_msecs/1000; #print $time_in_secs; $i_frame->{Ctl_Media_Slider_Sld}->SetValue($time_in_secs); # Set slider to video position in secs. my $length_in_secs=($i_frame->{Ctl_Videos_Media}->Length())/1000; # Only works after a 'play' command. my $ss = $length_in_secs % 60; if (length($ss) == 1) {$ss = "0" . $ss} # zero-pad seconds my $loc_length_hhhss = int($length_in_secs / 60) . ":" . $ss ; $ss = $time_in_secs % 60; if (length($ss) == 1) {$ss = "0" . $ss} # zerp pad seconds my $loc_time_hhhss = int($time_in_secs / 60) . ":" . $ss ; $i_frame->{Ctl_Media_Slider_End_Lbl}->SetLabel(" ".$loc_time_hhhss."/".$loc_length_hhhss); # Set max video length in mm:ss. } package main; unless(caller){ local *Wx::App::OnInit = sub{1}; my $app = Wx::App->new(); Wx::InitAllImageHandlers(); my $frame_1 = MyFrame->new(); $app->SetTopWindow($frame_1); $frame_1->Show(1); $app->MainLoop(); }