#!/usr/bin/perl use strict; use warnings; use Glib qw(TRUE FALSE); use GStreamer -init; use Gtk2 -init; use Gtk2::GladeXML; $/ = undef; my $xml = Gtk2::GladeXML -> new_from_buffer(); $xml -> signal_autoconnect_from_package("main"); sub my_bus_callback { my ($bus, $message, $loop) = @_; my $done = FALSE; if ($message -> type & "tag") { my $tags = $message -> tag_list; foreach (qw(artist title album)) { if (exists $tags -> { $_ }) { $xml -> get_widget("entry_$_") -> set_text($tags -> { $_ } -> [0]); $done = TRUE; } } } elsif ($message -> type & "error") { warn $message -> error; $loop -> quit(); } elsif ($message -> type & "eos") { $loop -> quit(); } $loop -> quit() if $done; # remove message from the queue return TRUE; } sub on_delete_event { Gtk2 -> main_quit(); } sub on_selection_changed { my ($chooser) = @_; my $file = $chooser -> get_filename(); return unless $file; my $pipeline = GStreamer::Pipeline -> new("pipe"); my ($source, $decoder) = GStreamer::ElementFactory -> make(filesrc => "source", decodebin => "decoder"); $pipeline -> add($source, $decoder); $source -> link($decoder); my $loop = Glib::MainLoop -> new(undef, FALSE); $source -> set(location => Glib::filename_to_unicode $file); $pipeline -> get_bus() -> add_watch(\&my_bus_callback, $loop); $pipeline -> set_state("playing") or die "Could not start playing"; $loop -> run(); $pipeline -> set_state("null"); } sub on_save_clicked { my $chooser = $xml -> get_widget("chooser"); warn "Saving doesn't work yet"; return; my $file = $chooser -> get_filename(); my $pipeline = GStreamer::Pipeline -> new("pipeline"); my ($source, $tagger, $sink) = GStreamer::ElementFactory -> make(filesrc => "src", id3mux => "tagger", filesink => "sink"); my $backup = $file . ".bak"; rename $file, $backup; $source -> set(location => Glib::filename_to_unicode $backup); $sink -> set(location => Glib::filename_to_unicode $file); $tagger -> set_tag_merge_mode("keep"); foreach my $tag (qw(artist title album)) { my $value = $xml -> get_widget("entry_$tag") -> get_text(); $tagger -> add_tags("replace", $tag => $value); } $source -> link($tagger, $sink) or die "Could not link"; $pipeline -> add($source, $tagger, $sink); $pipeline -> set_state("playing") or die "Could not start playing"; while ($pipeline -> iterate()) { } $pipeline -> set_state("null"); } Gtk2 -> main(); __DATA__ True Tag Writer GTK_WINDOW_TOPLEVEL GTK_WIN_POS_NONE False True False True False False GDK_WINDOW_TYPE_HINT_NORMAL GDK_GRAVITY_NORTH_WEST True 5 True False 0 True Select a File GTK_FILE_CHOOSER_ACTION_OPEN True False -1 0 False True True 5 True True True 3 2 False 0 0 True Artist: False False GTK_JUSTIFY_LEFT False False 0 0.5 0 0 PANGO_ELLIPSIZE_NONE -1 False 0 0 1 0 1 fill True Title: False False GTK_JUSTIFY_LEFT False False 0 0.5 0 0 PANGO_ELLIPSIZE_NONE -1 False 0 0 1 1 2 fill True Album: False False GTK_JUSTIFY_LEFT False False 0 0.5 0 0 PANGO_ELLIPSIZE_NONE -1 False 0 0 1 2 3 fill True True True True 0 True * False 1 2 0 1 True True True True 0 True * False 1 2 1 2 True True True True 0 True * False 1 2 2 3 0 True True True 5 True True True True True GTK_RELIEF_NORMAL True True 0.5 0.5 0 0 0 0 0 0 True False 2 True gtk-save 4 0.5 0.5 0 0 0 False False True Save True False GTK_JUSTIFY_LEFT False False 0.5 0.5 0 0 PANGO_ELLIPSIZE_NONE -1 False 0 0 True True 0 False False