bulk commit
[talkcutter.git] / src / mediaplayer.py
index 4b4df99..352aa84 100644 (file)
@@ -4,6 +4,7 @@ import sys
 import pygtk
 import gtk
 import gtk.glade
+import time
 
 class mediaplayer(object):
     PLAY_IMAGE = gtk.image_new_from_stock(gtk.STOCK_MEDIA_PLAY, gtk.ICON_SIZE_BUTTON)
@@ -19,6 +20,7 @@ class mediaplayer(object):
         self.spinner.set_range(0, 100)
         self.spinner.set_increments(1, 10)
         self.spinner.connect('value-changed', self.on_spinner_change)
+        self.spinner.connect('output', self.on_spinner_output)
 
         self.seeker.set_range(0, 100)
         self.seeker.set_increments(1, 10)
@@ -26,18 +28,46 @@ class mediaplayer(object):
         self.seeker.connect('button-press-event', self.on_button_press)
         self.seeker.connect('button-release-event', self.on_button_release)
 
+        label = gtk.Label()
+        label.set_text('Begin:')
+        self.markers.pack_start(label, True)
+
+        self.begin = gtk.SpinButton()
+        self.begin.connect('output', self.on_spinner_output)
+        self.markers.pack_start(self.begin, True)
+
+        label = gtk.Label()
+        label.set_text('End:')
+        self.markers.pack_start(label, True)
+
+        self.end = gtk.SpinButton()
+        self.end.connect('output', self.on_spinner_output)
+        self.markers.pack_start(self.end, True)
+
+        label = gtk.Label()
+        label.set_text('Length:')
+        self.markers.pack_start(label, True)
+
+        self.length = gtk.SpinButton()
+        self.length.connect('output', self.on_spinner_output)
+        self.markers.pack_start(self.length, True)
+
+        self.markers.show_all()
+
         self.play_button = gtk.Button()
+        self.image_play = gtk.image_new_from_stock(gtk.STOCK_MEDIA_PLAY, gtk.ICON_SIZE_BUTTON)
+        self.image_pause = gtk.image_new_from_stock(gtk.STOCK_MEDIA_PAUSE, gtk.ICON_SIZE_BUTTON)
         self.play_button.set_image(self.PLAY_IMAGE)
         self.play_button.connect('clicked', self.on_play_clicked)
         self.bbox.pack_start(self.play_button, False)
 
         self.begin_button = gtk.Button()
-        self.begin_button.set_image(self.PLAY_IMAGE)
+        self.begin_button.set_image(gtk.image_new_from_stock(gtk.STOCK_GOTO_FIRST, gtk.ICON_SIZE_BUTTON))
         self.begin_button.connect('clicked', self.on_begin_clicked)
         self.bbox.pack_start(self.begin_button, False)
 
         self.end_button = gtk.Button()
-        self.end_button.set_image(self.PLAY_IMAGE)
+        self.end_button.set_image(gtk.image_new_from_stock(gtk.STOCK_GOTO_LAST, gtk.ICON_SIZE_BUTTON))
         self.end_button.connect('clicked', self.on_end_clicked)
         self.bbox.pack_start(self.end_button, False)
 
@@ -46,12 +76,13 @@ class mediaplayer(object):
         self.is_loaded = False
         self.is_playing = False
         self.known_range = False
+        self.lock_slider = 0
 
     def play(self, uri):
         self.playbin.set_property('uri', uri)
         self.playbin.set_state(gst.STATE_PLAYING)
         self.label.label = 'f';
-        gobject.timeout_add(500, self.update_slider)
+        gobject.timeout_add(50, self.update_slider)
         self.is_playing = True
         self.is_loaded = True
         self.known_range = False
@@ -65,9 +96,15 @@ class mediaplayer(object):
     def on_video_realized(self, sender):
         self.sink.set_xwindow_id(self.drawingarea.window.xid)
 
+    def get_pos(self):
+        nanosecs, format = self.playbin.query_position(gst.FORMAT_TIME)
+        return float(nanosecs) / gst.SECOND;
+
     def update_slider(self):
         if not self.is_playing:
             return True
+        if self.lock_slider > time.time():
+            return True
 
         try:
             if not self.known_range:
@@ -77,48 +114,68 @@ class mediaplayer(object):
                   print duration_secs
                   self.seeker.set_range(0, duration_secs)
                   self.spinner.set_range(0, duration_secs)
+                  self.begin.set_range(0, duration_secs)
+                  self.end.set_range(0, duration_secs)
+                  self.length.set_range(0, duration_secs)
                   self.known_range = True
                   print "Duration: %f" % (duration_secs) 
 
-            nanosecs, format = self.playbin.query_position(gst.FORMAT_TIME)
+            value = self.get_pos()
+            self.set_value(value)
 
-            # block seek handler so we don't seek when we set_value()
-            self.seeker.handler_block_by_func(self.on_seeker_change)
-            self.spinner.handler_block_by_func(self.on_spinner_change)
+        except gst.QueryError:
+            # pipeline must not be ready and does not know position
+            pass
 
-            value = float(nanosecs) / gst.SECOND;
+        return True # continue calling every 30 milliseconds
 
-            #print "Trigger: %f" % (value) 
+    def set_value(self, value):
+        # block seek handler so we don't seek when we set_value()
+        self.seeker.handler_block_by_func(self.on_seeker_change)
+        self.spinner.handler_block_by_func(self.on_spinner_change)
 
-            self.seeker.set_value(value)
-            self.spinner.set_text("%f" %(value))
+        #print "Trigger: %f" % (value) 
 
-            self.seeker.handler_unblock_by_func(self.on_seeker_change)
-            self.spinner.handler_unblock_by_func(self.on_spinner_change)
+        self.seeker.set_value(value)
+        self.spinner.set_value(value)
 
-        except gst.QueryError:
-            # pipeline must not be ready and does not know position
-            pass
+        self.seeker.handler_unblock_by_func(self.on_seeker_change)
+        self.spinner.handler_unblock_by_func(self.on_spinner_change)
 
-        return True # continue calling every 30 milliseconds
+    def formatSecondsToMencoder(self, s):
+        ds = s % 1
+        ws = s - ds
+        ds *= 1000
+        s = ws % 60
+        ws -= s
+        m = ws % 3600 / 60
+        ws -= ws % 3600
+        h = ws / 3600
+        return "%02d:%02d:%02d.%03d" % (h, m, s, ds)
 
+    def on_spinner_change(self, element):
+        seek_time_secs = element.get_value()
+        self.mseek(seek_time_secs)
 
     def on_seeker_change(self, element, a, b):
         seek_time_secs = element.get_value()
         self.mseek(seek_time_secs)
 
-    def on_spinner_change(self, element):
-        seek_time_secs = float(element.get_value())
-        self.mseek(seek_time_secs)
+    def on_spinner_output(self, element):
+        element.set_text(self.formatSecondsToMencoder(element.get_value()))
+        return True
 
     def mplay(self):
         self.playbin.set_state(gst.STATE_PLAYING)
+        self.mseek(self.get_pos())
 
     def mpause(self):
         self.playbin.set_state(gst.STATE_PAUSED)
 
     def mseek(self, seek_time_secs):
-        print 'seek: %f' % (seek_time_secs)
+        #print 'seek: %f' % (seek_time_secs)
+        self.set_value(seek_time_secs)
+        self.lock_slider = time.time() + 0.1;
         self.playbin.seek_simple(gst.FORMAT_TIME, gst.SEEK_FLAG_FLUSH | gst.SEEK_FLAG_KEY_UNIT, seek_time_secs * gst.SECOND)
 
     def on_button_press(self, element, a):
@@ -140,6 +197,17 @@ class mediaplayer(object):
           self.is_playing = True;
           
     def on_begin_clicked(self, element):
+        pos = self.get_pos()
+        print 'Begin clicked: %f' % (pos)
+        self.begin.set_value(pos)
+        self.update_length()
         
     def on_end_clicked(self, element):
+        pos = self.get_pos()
+        print 'End clicked: %f' % (pos)
+        self.end.set_value(pos)
+        self.update_length()
+    
+    def update_length(self):
+        self.length.set_value(self.end.get_value() - self.begin.get_value())