Re: Are there Perl bindings for gstreamer-1.0?
- From: Steve Cookson <it sca-uk com>
- To: Terence Ferraro <terencejferraro gmail com>
- Cc: GTK-Perl List <gtk-perl-list gnome org>
- Subject: Re: Are there Perl bindings for gstreamer-1.0?
- Date: Tue, 29 Apr 2014 15:46:03 +0100
Hi Guys,
On 28/04/14 19:57, Terence Ferraro wrote:
# Create Gtk3 windows, widgets, drawable, etc..
Here is a piece of code with a combination of bits of code:
- Terence's/Torsten's original wrapping ;
- The testsource code from vividsnow
- A small player in wxWidgets.
The buttons are not yet active.
The player and the video occupy different positions on the screen (not
normally considered and ideal situation);
However, there is a commented out piece of code in c which occupies a
subroutine called SetVideoOverlay.
There are actually several different callouts for overlays,
corresponding to resizing the windows, end of stream, change state, etc,
like this:
// Connect the glib events/callbacks we want to our playbin
g_signal_connect(m_playbin, "eos",
G_CALLBACK(gst_finish_callback), this);
g_signal_connect(m_playbin, "error",
G_CALLBACK(gst_error_callback), this);
g_signal_connect(m_playbin, "state-change",
G_CALLBACK(gst_state_change_callback), this);
but if we can get the start play going, then I guess the others will be
easier.
Code follows,
Regards
Steve.
#!/usr/bin/perl -w --
package i_Mage;
use Wx qw[:everything];
use Wx::Event qw( EVT_MENU );
use v5.18;
use base qw(Wx::Frame);
use strict;
use warnings;
use Glib::Object::Introspection;
our $gl_pipeline =();
our $m_xoverlay;
sub new {
my( $i_main_menu, $parent, $id, $title, $pos, $size, $style, $name
) = @_;
$parent = undef unless defined $parent;
$id = wxID_ANY unless defined $id;
$title = "" unless defined $title;
$pos = wxDefaultPosition unless defined $pos;
$size = wxDefaultSize unless defined $size;
$name = "" unless defined $name;
# Create top level window.
$style = wxNO_BORDER unless defined $style;
$i_main_menu = $i_main_menu->SUPER::new( undef, wxID_ANY, "Video
Player", wxDefaultPosition, [800,630], $style, $name );
my $Main_Szr = Wx::BoxSizer->new( wxVERTICAL);
my $video_panel=Wx::Panel->new($i_main_menu, wxID_ANY,
wxDefaultPosition, [800,600],);
$Main_Szr->Add($video_panel, 0, 0, 0);
#
# Create pipeline
#
MakePipeline();
#
# Draw player buttons
#
my $button_szr = Wx::BoxSizer->new(wxHORIZONTAL);
$Main_Szr->Add($button_szr, 0, 0, 0);
my $media_play_btn = Wx::Button->new($i_main_menu, wxID_ANY, "&>");
$media_play_btn->SetSize([20,20]);
my $Loc_Tooltip_String_Txt = "Play/resume media clip. Accelerator
key = alt->";
$media_play_btn->SetToolTipString($Loc_Tooltip_String_Txt);
Wx::Event::EVT_BUTTON( $i_main_menu, $media_play_btn, sub {});
$button_szr->Add($media_play_btn, 0, 0, 2);
$media_play_btn->SetFocus();
my $media_pause_btn = Wx::Button->new($i_main_menu, wxID_ANY, "&||");
$media_pause_btn->SetSize([20,20]);
$button_szr->Add($media_pause_btn, 0, 0, 2);
$Loc_Tooltip_String_Txt = "Pause media clip. Accelerator key = alt-|";
$media_pause_btn->SetToolTipString($Loc_Tooltip_String_Txt);
Wx::Event::EVT_BUTTON( $i_main_menu, $media_pause_btn, sub {} );
my $media_rewind_btn = Wx::Button->new($i_main_menu, wxID_ANY, "&<<");
$media_rewind_btn->SetSize([20,20]);
$button_szr->Add($media_rewind_btn, 0, 0, 2);
$media_rewind_btn->SetToolTipString("Rewinds 30 seconds.
Accelerator key = alt-<");
Wx::Event::EVT_BUTTON( $i_main_menu, $media_rewind_btn, sub {});
my $media_ffwd_btn = Wx::Button-> new($i_main_menu, wxID_ANY, ">&>");
$media_ffwd_btn->SetSize([20,20]);
$Loc_Tooltip_String_Txt = "Forwards 30 seconds. Accelerator key =
alt->";
$media_ffwd_btn->SetToolTipString($Loc_Tooltip_String_Txt);
$button_szr->Add($media_ffwd_btn, 0, 0, 2);
Wx::Event::EVT_BUTTON( $i_main_menu, $media_ffwd_btn, sub {} );
# Set video overlay and play video.
SetVideoOverlay();
my $bus = $gl_pipeline->get_bus;
$bus->add_signal_watch;
$bus->signal_connect(message => \&my_callback);
$gl_pipeline->set_state('playing');
$style = wxNO_BORDER unless defined $style;
$i_main_menu->Show(1);
$i_main_menu->SetSizer($Main_Szr);
$i_main_menu->Layout();
return $i_main_menu;
}
sub MakePipeline {
map { Glib::Object::Introspection->setup(basename => $_, version =>
'1.0', package => 'GStreamer') } qw'Gst GstBase';
my @version=();
@version = GStreamer::version();
print 'This program is linked against GStreamer ', join '.',
GStreamer::version(), "\n";
my $i = GStreamer::init ([$0, @ARGV]);
if (0) {
$gl_pipeline = GStreamer::ElementFactory->new("playbin","play");
my $fn = "http://www.csoft.co.uk/video/original/earth.avi";
$gl_pipeline->set_uri($fn);
} else {
$gl_pipeline = GStreamer::Pipeline->new('video-example');
my ($source, $flt, $sink) = map
GStreamer::ElementFactory::make(@$_),
[qw'videotestsrc source'],
[qw'capsfilter flt'],
[qw'ximagesink sink'];
sub gval ($$) {
Glib::Object::Introspection::GValueWrapper->new('Glib::'.ucfirst($_[0])
=> $_[1])
} # GValue wrapper shortcut
$flt->set(
caps => map {
$_->set_value(width => gval int => 800);
$_->set_value(height => gval int => 600);
$_;
}
GStreamer::Caps->new_empty_simple('video/x-raw')
);
map $gl_pipeline->add($_), $source, $flt, $sink;
map { state $p; $p->link($_) if $p; $p = $_ } $source, $flt, $sink;
}
}
sub SetVideoOverlay{
#
#//-----------------------------------------------------------------------------
#// wxGStreamerMediaBackend::SetupXOverlay
#//
#// Attempts to set the XWindow id of our GstVideoOverlay to tell it which
#// window to play video in.
#//-----------------------------------------------------------------------------
#void wxGStreamerMediaBackend::SetupXOverlay()
#{
# // Use the xoverlay extension to tell gstreamer to play in our window
##ifdef __WXGTK__
# if (!gtk_widget_get_realized(m_ctrl->m_wxwindow))
# {
# // Not realized yet - set to connect at realization time
# g_signal_connect (m_ctrl->m_wxwindow,
# "realize",
# G_CALLBACK (gtk_window_realize_callback),
# this);
# }
# else
# {
# gdk_flush();
#
# GdkWindow* window = gtk_widget_get_window(m_ctrl->m_wxwindow);
# wxASSERT(window);
##endif
# gst_video_overlay_set_window_handle(GST_VIDEO_OVERLAY(m_xoverlay),
##ifdef __WXGTK__
# GDK_WINDOW_XID(window)
##else
# ctrl->GetHandle()
##endif
# );
##ifdef __WXGTK__
# g_signal_connect(m_ctrl->m_wxwindow,
##ifdef __WXGTK3__
# "draw", G_CALLBACK(draw),
##else
# "expose_event", G_CALLBACK(expose_event),
##endif
# this);
# } // end if GtkPizza realized
##endif
#}
#
return 1;
}
sub my_callback
{
my ($bus, $message) = @_;
say "message ".$message->type;
if ($message->type =~ /error/)
{
warn "error\n";
$gl_pipeline->set_state ('null');
}
elsif ($message->type =~ /eos/)
{
warn "end\n";
$gl_pipeline->set_state ('null');
} else {
say "playing.";
}
return 1;
}
1;
package GStreamer;
sub GStreamer::ElementFactory::new
{
my ($self,$factory_name,$name) = @_;
my $e = GStreamer::ElementFactory::make($factory_name,$name);
print ref($e);
my $package = 'GStreamer::Element';
return bless $e, $package;
}
sub GStreamer::Element::set_uri
{
my ($self,$uri) = @_;
$self->set('uri' => $uri);
}
package i_Mage_Main_App;
use base qw(Wx::App);
use strict;
sub OnInit {
my( $self ) = shift;
my $i_Mage = i_Mage->new();
$self->SetTopWindow($i_Mage);
$i_Mage->Show(1);
return 1;
}
package main;
unless(caller){
my $gl_i_Mage_app = i_Mage_Main_App->new();
$gl_i_Mage_app->MainLoop();
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]