Warum Videos bearbeiten?
Wie Videos bearbeiten?
Code
Hübsche Bilder
Generative Videoinstallationen
Videoschleifen
Immer wiederholend
Aber nicht immer gleich
Offline mit ffmpeg
Die Videos können nicht verfremdet werden
Keine Live-Bilder von der Webcam
Keine Filme von YouTube etc.
Fester endlicher Automat
Darstellung von 3D Grafik
3D Grafik ist etwas mehr als 2D Grafik
(wie Videos)
Video
Video
Webcam
Video
Webcam
Logo
Video
Webcam
Logo
OpenGL als Rechenmaschine
Video
Webcam
Logo
OpenGL als Rechenmaschine
Video
Webcam
Logo
OpenGL als Rechenmaschine
Hardwareunterstützung statt Perl
Blumen mit Logo-Überlagerung, TV-Effekt
Pipeline ursprünglich fest
Objekt rastern
Pipeline ursprünglich fest
Objekt rastern
Objekt texturieren
Pipeline ursprünglich fest
Objekt rastern
Objekt texturieren
Objekt darstellen
Es gab nur wenige, vorgegebene Funktionen zum Kombinieren von Pixeln bei der Texturierung:
Addition, Multiplikation, Subtraktion, OR, XOR, AND
Maskierung
Pipeline komplett programmierbar (seit OpenGL 2.0)
Programme heissen "Shader"
Parallele Verarbeitung
Verfremdungs- und Effektfilter
Schwarzweissfilter
Schwarzweissfilter
Kantenerkennung
Schwarzweissfilter
Kantenerkennung
Chromakey / Bluescreen / Greenscreen
Statischen Hintergrund vom Bild abziehen
Crossfades zwischen Filmen
Zwei Filme anhand einer Maske/eines dritten Films ineinander übergehen lassen
(Ring)Puffer
Speichert Einzelbilder zwischen
Aus ffmpeg
(schnell)
Von der Grafikkarte (langsam)
Delay (1 s)
Vielleicht für Webcam
Filter "Nervös"
Filter "Nervös"
Filter "Nervös"
Feedback
OpenGL
- OpenGL Anbindung
OpenGL::Shader
- OpenGL Shader/Filter
Source::FFmpeg
- der Decoder für die Videostreams
Filter::Buffer
- Ringpuffer für Feedback/Delay
Filme öffnen (Source::FFmpeg)
Mainloop
1: my $curr_texture; 2: for my $movie (@movies) { 3: # Bild in Grafikkarte laden 4: $curr_texture = $movie->tick(); 5: # Bild in Ringpuffer laden 6: ... 7: 8: # Textur-Ping-Pong 9: for my $filter (@active_filters) { 10: $curr_texture = $filter->render($curr_texture); 11: }; 12: };
Startet ffmpeg
mit ein paar Kommandozeilenparametern
ffmpeg
gibt den Film nach STDOUT aus
Liefert ein Filehandle zurück, aus dem die einzelnen Bilder gelesen werden
1: sub stream_info { 2: my ($self,$filename) = @_; 3: my ($child_in, $stream, $info); 4: my $cmd = sprintf 5: qq{bin\\ffmpeg-old.exe -t 0 -i "%s-}, 6: $filename; 7: my $pid = open3 $child_in, $stream, $stream, $cmd 8: or die "Couldn't spawn '$cmd': $!/$?";
1: while (my $line = <$stream>) { 2: #print ">>$line"; 3: if ($line =~ /Video: .*/) { 4: chomp $line; 5: print ">$line<\n"; 6: my ($width,$height) = $line =~ /(\d+)x(\d+)/; 7: return ($width,$height); 8: }; 9: }; 10: };
Parameterüberprüfung
1: sub new { 2: my ($class,%args) = @_; 3: my $file = delete $args{filename}; 4: die "No file: '$file'" 5: unless -f $file; 6: warn "$file seems valid.";
Die Informationen über den Film werden gleich beim Start eingelesen
1: my ($width,$height) = $class->stream_info($file); 2: 3: my $cmd = sprintf 4: qq{bin\\ffmpeg-old.exe -i "%s} 5: . qq{-f rawvideo -pix_fmt rgb24 - |}, 6: $file; 7: my $pid = open my $stream, "$cmd" 8: or die "Couldn't spawn '$cmd': $!/$?"; 9: binmode $stream;
...
tick()
wird aufgerufen, wenn ein neues Bild eingelesen werden soll
1: sub tick { 2: my ($self) = @_;
1: # Textur anlegen 2: my $texture_id = $self->texture_id; 3: if (! $texture_id) { 4: ($texture_id) = glGenTextures_p(1); 5: $self->texture_id($texture_id); 6: };
1: # Daten lesen 2: my $frame; 3: read $self->stream, $frame, $self->width * $self->height * $self->depth 4: or die "Read failure"; 5: 6: # Übergeben an OpenGL 7: OpenGL::Tools::set_texture_pixels( 8: texture => $texture_id, 9: pixels => $frame, 10: ... 11: );
ffmpeg
stoppen, wenn das Objekt
weggeworfen wird
1: sub DESTROY { 2: if (my $pid = $_[0]->pid) { 3: kill 9 => $pid 4: }; 5: };
Kein Sound
Keine Pause/Vorwärts/Zurückspulen
Nicht Server-fähig wegen OpenGL
Einfache Installation
Funktioniert
Fragen?