allow to specify frame offset for videos in the GUI
authorgc <gc>
Fri, 15 Apr 2005 22:16:34 +0000 (22:16 +0000)
committergc <gc>
Fri, 15 Apr 2005 22:16:34 +0000 (22:16 +0000)
bin/booh-gui
data/booh/images/stock-video-16.png [new file with mode: 0644]
lib/booh/booh-lib.rb

index a0c6acd2055dcb2d4a2ae9f93dfa9831b301d9dc..bdd2ad6c34cfdb38adbe013f734bd17122a8fe8d 100755 (executable)
@@ -313,6 +313,53 @@ def enhance(xmldir, attributes_prefix)
     end
 end
 
+def change_frame_offset(xmldir, attributes_prefix, value)
+    xmldir.add_attribute("#{attributes_prefix}frame-offset", value)
+end
+
+def ask_new_frame_offset(xmldir, attributes_prefix)
+    value = xmldir.attributes["#{attributes_prefix}frame-offset"]
+
+    dialog = Gtk::Dialog.new(utf8(_("Change frame offset")),
+                             $main_window,
+                             Gtk::Dialog::MODAL | Gtk::Dialog::DESTROY_WITH_PARENT,
+                             [Gtk::Stock::OK, Gtk::Dialog::RESPONSE_OK],
+                             [Gtk::Stock::CANCEL, Gtk::Dialog::RESPONSE_CANCEL])
+
+    lbl = Gtk::Label.new
+    lbl.markup = utf8(
+_("Please specify the <b>frame offset</b> of the video, to take the thumbnail
+from. There are approximately 25 frames per second in a video.
+"))
+    dialog.vbox.add(lbl)
+    dialog.vbox.add(entry = Gtk::Entry.new.set_text(value))
+    entry.signal_connect('key-press-event') { |w, event|
+        if event.keyval == Gdk::Keyval::GDK_Return
+            dialog.response(Gtk::Dialog::RESPONSE_OK)
+            true
+        elsif event.keyval == Gdk::Keyval::GDK_Escape
+            dialog.response(Gtk::Dialog::RESPONSE_CANCEL)
+            true
+        else
+            false  #- propagate if needed
+        end
+    }
+    
+    dialog.window_position = Gtk::Window::POS_MOUSE
+    dialog.show_all
+
+    dialog.run { |response|
+        newval = entry.text
+        dialog.destroy
+        if response == Gtk::Dialog::RESPONSE_OK
+            msg 3, "changing frame offset top #{newval}"
+            return { :old => value, :new => newval }
+        else
+            return nil
+        end
+    }
+end
+
 def gen_real_thumbnail(type, origfile, destfile, xmldir, size, img)
     Thread.new {
         push_mousecursor_wait
@@ -348,13 +395,16 @@ def popup_thumbnail_menu(event, optionals, type, xmldir, attributes_prefix, clos
     r270.image = Gtk::Image.new("#{$FPATH}/images/stock-rotate-270-16.png")
     r270.signal_connect('activate') { closures[:rotate].call(-90) }
     if type == 'video'
-        menu.append(             Gtk::SeparatorMenuItem.new)
-        menu.append(color_swap = Gtk::ImageMenuItem.new(utf8(_("Red/blue color swap"))))
+        menu.append(               Gtk::SeparatorMenuItem.new)
+        menu.append(  color_swap = Gtk::ImageMenuItem.new(utf8(_("Red/blue color swap"))))
         color_swap.image = Gtk::Image.new("#{$FPATH}/images/stock-color-triangle-16.png")
         color_swap.signal_connect('activate') { closures[:color_swap].call }
-        menu.append(      flip = Gtk::ImageMenuItem.new(utf8(_("Flip upside-down"))))
+        menu.append(        flip = Gtk::ImageMenuItem.new(utf8(_("Flip upside-down"))))
         flip.image = Gtk::Image.new("#{$FPATH}/images/stock-rotate-180-16.png")
         flip.signal_connect('activate') { closures[:rotate].call(180) }
+        menu.append(frame_offset = Gtk::ImageMenuItem.new(utf8(_("Specify frame offset"))))
+        frame_offset.image = Gtk::Image.new("#{$FPATH}/images/stock-video-16.png")
+        frame_offset.signal_connect('activate') { closures[:frame_offset].call }
     end
     menu.append(               Gtk::SeparatorMenuItem.new)
     menu.append(enhance      = Gtk::ImageMenuItem.new(utf8(xmldir.attributes["#{attributes_prefix}enhance"] ? _("Original contrast") :
@@ -435,12 +485,32 @@ def add_thumbnail(autotable, filename, type, thumbnail_img, caption)
                       perform_color_swap_and_cleanup.call
                       $notebook.set_page(1)
                       Proc.new {
-                          perform_color_swap_and_cleanup
+                          perform_color_swap_and_cleanup.call
                           $notebook.set_page(1)
                       }
                   })
     }
 
+    change_frame_offset_and_cleanup = Proc.new {
+        if values = ask_new_frame_offset($xmldir.elements["[@filename='#{filename}']"], '')
+            perform_change_frame_offset_and_cleanup = Proc.new { |val|
+                change_frame_offset($xmldir.elements["[@filename='#{filename}']"], '', val)
+                my_gen_real_thumbnail.call
+            }
+            perform_change_frame_offset_and_cleanup.call(values[:new])
+
+            save_undo(_("specify frame offset"),
+                      Proc.new {
+                          perform_change_frame_offset_and_cleanup.call(values[:old])
+                          $notebook.set_page(1)
+                          Proc.new {
+                              perform_change_frame_offset_and_cleanup.call(values[:new])
+                              $notebook.set_page(1)
+                          }
+                      })
+        end
+    }
+
     enhance_and_cleanup = Proc.new {
         perform_enhance_and_cleanup = Proc.new {
             enhance($xmldir.elements["[@filename='#{filename}']"], '')
@@ -455,7 +525,7 @@ def add_thumbnail(autotable, filename, type, thumbnail_img, caption)
                       perform_enhance_and_cleanup.call
                       $notebook.set_page(1)
                       Proc.new {
-                          perform_enhance_and_cleanup
+                          perform_enhance_and_cleanup.call
                           $notebook.set_page(1)
                       }
                   })
@@ -572,7 +642,8 @@ def add_thumbnail(autotable, filename, type, thumbnail_img, caption)
         end
         if event.event_type == Gdk::Event::BUTTON_PRESS && event.button == 3
             popup_thumbnail_menu(event, ['delete'], type, $xmldir.elements["[@filename='#{filename}']"], '',
-                                 { :rotate => rotate_and_cleanup, :color_swap => color_swap_and_cleanup, :enhance => enhance_and_cleanup, :delete => delete })
+                                 { :rotate => rotate_and_cleanup, :color_swap => color_swap_and_cleanup, :enhance => enhance_and_cleanup,
+                                   :frame_offset => change_frame_offset_and_cleanup, :delete => delete })
         end
         if event.event_type == Gdk::Event::BUTTON2_PRESS && event.button == 1
             view_element(filename)
@@ -821,12 +892,32 @@ def change_dir
                           perform_color_swap_and_cleanup.call
                           $notebook.set_page(0)
                           Proc.new {
-                              perform_color_swap_and_cleanup
+                              perform_color_swap_and_cleanup.call
                               $notebook.set_page(0)
                           }
                       })
         }
 
+        change_frame_offset_and_cleanup = Proc.new {
+            if values = ask_new_frame_offset(xmldir, "#{infotype}-")
+                perform_change_frame_offset_and_cleanup = Proc.new { |val|
+                    change_frame_offset(xmldir, "#{infotype}-", val)
+                    my_gen_real_thumbnail.call
+                }
+                perform_change_frame_offset_and_cleanup.call(values[:new])
+
+                save_undo(_("specify frame offset"),
+                          Proc.new {
+                              perform_change_frame_offset_and_cleanup.call(values[:old])
+                              $notebook.set_page(0)
+                              Proc.new {
+                                  perform_change_frame_offset_and_cleanup.call(values[:new])
+                                  $notebook.set_page(0)
+                              }
+                          })
+            end
+        }
+
         enhance_and_cleanup = Proc.new {
             perform_enhance_and_cleanup = Proc.new {
                 enhance(xmldir, "#{infotype}-")
@@ -838,10 +929,10 @@ def change_dir
             save_undo(_("enhance"),
                       Proc.new {
                           perform_enhance_and_cleanup.call
-                          $notebook.set_page(1)
+                          $notebook.set_page(0)
                           Proc.new {
-                              perform_enhance_and_cleanup
-                              $notebook.set_page(1)
+                              perform_enhance_and_cleanup.call
+                              $notebook.set_page(0)
                           }
                       })
         }
@@ -858,7 +949,8 @@ def change_dir
             end
             if event.event_type == Gdk::Event::BUTTON_PRESS && event.button == 3
                 popup_thumbnail_menu(event, ['change_image'], entry2type(captionfile), xmldir, "#{infotype}-",
-                                     { :change => change_image, :rotate => rotate_and_cleanup, :enhance => enhance_and_cleanup, :color_swap => color_swap_and_cleanup })
+                                     { :change => change_image, :rotate => rotate_and_cleanup, :enhance => enhance_and_cleanup,
+                                       :color_swap => color_swap_and_cleanup, :frame_offset => change_frame_offset_and_cleanup })
             end
             if event.event_type == Gdk::Event::BUTTON2_PRESS && event.button == 1
                 change_image.call
diff --git a/data/booh/images/stock-video-16.png b/data/booh/images/stock-video-16.png
new file mode 100644 (file)
index 0000000..758cfbf
Binary files /dev/null and b/data/booh/images/stock-video-16.png differ
index ab58ef34cde247a1e7ac02d800bb950172512e2a..bdb3302c5a3b87ffeee0ffaa74d44537d8dfd8f7 100644 (file)
@@ -223,6 +223,10 @@ module Booh
             if felem
                 #- frame-offset is an attribute that allows to specify which frame to use for the thumbnail
                 frame_offset = felem.attributes["#{attributes_prefix}frame-offset"]
+                if !frame_offset
+                    felem.add_attribute("#{attributes_prefix}frame-offset", frame_offset = "5")
+                end
+                frame_offset = frame_offset.to_i
                 if rotate = felem.attributes["#{attributes_prefix}rotate"]
                     convert_options += "-rotate #{rotate} "
                 end
@@ -230,7 +234,6 @@ module Booh
                     convert_options += "-contrast -enhance -normalize "
                 end
             end
-            frame_offset = (frame_offset || 5).to_i
             for dest in dests
                 if !File.exists?("#{dest_dir}/screenshot.jpg000004.jpg")
                     transcode_options = ''
@@ -241,7 +244,11 @@ module Booh
                     end
                     cmd = "transcode -a 0 -c #{frame_offset-5}-#{frame_offset} -i '#{orig}' -y jpg -o '#{dest_dir}/screenshot.jpg' #{transcode_options} 2>&1"
                     msg 2, cmd
-                    if subproc_runaway_aware(cmd) =~ /V: import format.*unknown/ || !File.exists?("#{dest_dir}/screenshot.jpg000004.jpg")
+                    results = subproc_runaway_aware(cmd)
+                    if results =~ /skipping frames/ && results !~ /encoding frame/
+                        msg 0, _("specified frame-offset probably too large. max frame was: %s.") % results.scan(/skipping frames \[000000-(\d+)\]/)[-1]
+                        return false
+                    elsif results =~ /V: import format.*unknown/ || !File.exists?("#{dest_dir}/screenshot.jpg000004.jpg")
                         msg 2, _("* could not extract first image of video %s with transcode, will try first converting with mencoder") % orig
                         cmd = "mencoder '#{orig}' -nosound -ovc lavc -lavcopts vcodec=mjpeg -o '#{dest_dir}/foo.avi' -frames #{frame_offset} -fps 25 >/dev/null 2>/dev/null"
                         msg 2, cmd