Re: Are there Perl bindings for gstreamer-1.0?



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]