Thread FFmpeg::Stream::Video installieren (20 answers)
Opened by cbxk1xg at 2010-10-05 18:16

topeg
 2010-10-09 23:10
#141796 #141796
User since
2006-07-10
2611 Artikel
BenutzerIn

user image
kleines Script, das ein Bild von einem Video holt:
Code (perl): (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
#!/usr/bin/perl
use strict;
use warnings;
use utf8;
use Glib qw(TRUE FALSE);
use GStreamer -init;

# eingabe datei
my $file='test.avi';
# ausgabe datei
my $ofile='test.jpg';
# position im video
my $pos=3_000_000_000; # ns
# höhe /breite
my $scale_w=720;
my $scale_h=510;

my @scales;
push(@scales,"width=$scale_w") if($scale_w);
push(@scales,"height=$scale_h") if($scale_h);

#pipeline erzeugen
my $pipeline = GStreamer::parse_launch(sprintf(
        'filesrc location=%s ! avidemux name=data_demux '.
        'data_demux.audio_00 ! queue ! fakesink '.
        'data_demux.video_00 ! decodebin name=video_decode ! ffmpegcolorspace '.
        '! videoscale ! video/x-raw-yuv,%s ! jpegenc ! fakesink name=video_sink signal-handoffs=TRUE ',
      $file,join(',',@scales)));

# der pipeline einen Namen geben
$pipeline->set_name('my_pipeline');

# Puffer für die Ausgabe
my $buffer=undef;

# Listener für Frame einrichten
my $video_sink=$pipeline->get_by_name('video_sink');
$video_sink->signal_connect(handoff => sub{
    return TRUE if($buffer);

    my $query=GStreamer::Query::Position->new('time');
    $video_sink->query($query);
    my (undef, $pos_now)=$query->position;

    return TRUE if($pos_now<$pos);

    $buffer=$_[1];

    return TRUE;
  });

# video abspielen
$pipeline->set_state("playing");
my $seek=1;
my $bus=$pipeline->get_bus();
while (1)
{
  # alle nahrichten vom bus holen
  my $message = $bus -> poll("any", 0);

  # Schleife beenden wenn wir ein Bild haben
  last if($buffer);

  # wenn keine Nachrichten warten
  unless (defined $message)
  {
    select(undef,undef,undef,0.25);
    next;
  }


  # beenden wenn das Video am Ende ist,
  # oder ein Fehler auftrat
  last if (
            $message->type & "eos"     ||
            $message->type & "error"   ||
            $message->type & "warning"
          );


  # wenn sich det Zusand eines pileelemts geändert hat
  if($message->type & "state-changed")
  {
    # Name des Elementes ermitteln
    my $name=$message->src()->get_name() || 'UNDEF';
    #print "$name => ".$message->new_state()."\n";

    # es wurde noch nicht zu der stelle gespringen,
    # der Name stimmt und die pipeline ist "playing"
    if($seek && $name eq 'my_pipeline' && $message->new_state() eq 'playing')
    {
      # zur gewünschten Stelle springen
      $pipeline->seek(1,'time','flush','set',$pos,'none',0) || last;
      $seek--;
    }
  }
}
# pipeline stoppen
$pipeline->set_state("null");

# wenn ein bild da ist
if($buffer)
{
  # bild in Datei schreiben.
  open(my $fh, '>', $ofile) or die("Error open $ofile! ($!)");
  binmode($fh);
  print $fh $buffer->data();
  close($fh);
}


Ja die Doku ist nicht so toll, aber schau mal hier:
Perl Doku: http://gtk2-perl.sourceforge.net/doc/pod/GStreamer...
C++ Doku: http://maemoide.nokia.com/fremantle/index.jsp?topi...
GStreamer Plugins: http://gstreamer.freedesktop.org/documentation/plu...
Damit kommt man schon recht weit.

View full thread FFmpeg::Stream::Video installieren