X-Git-Url: http://git.asbjorn.biz/?a=blobdiff_plain;f=src%2Fmediaplayer.py;h=352aa84b5713fc1afc5894cd9e71245ceae46797;hb=refs%2Fheads%2Fmaster;hp=b2741b046a02e7629161cde524517ef1f3cb14e9;hpb=6958c5bcc833e071bb8b0cae1483c02c00c7099b;p=talkcutter.git diff --git a/src/mediaplayer.py b/src/mediaplayer.py index b2741b0..352aa84 100644 --- a/src/mediaplayer.py +++ b/src/mediaplayer.py @@ -4,8 +4,12 @@ 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) + PAUSE_IMAGE = gtk.image_new_from_stock(gtk.STOCK_MEDIA_PAUSE, gtk.ICON_SIZE_BUTTON) + def __init__( self ): self.playbin = gst.element_factory_make('playbin2') @@ -15,7 +19,8 @@ class mediaplayer(object): self.spinner.set_range(0, 100) self.spinner.set_increments(1, 10) - self.spinner.connect('change-value', self.on_seeker_change) + 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) @@ -23,16 +28,65 @@ 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(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(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) + + self.bbox.show_all() + + 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(100, self.update_slider) + gobject.timeout_add(50, self.update_slider) self.is_playing = True + self.is_loaded = True self.known_range = False + self.label.set_text(uri) def on_finish(self, bus, message): self.playbin.set_state(gst.STATE_PAUSED); @@ -42,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 False # cancel timeout + return True + if self.lock_slider > time.time(): + return True try: if not self.known_range: @@ -54,41 +114,100 @@ 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_seeker_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_seeker_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): - print 'on_seeker_change' seek_time_secs = 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) + 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): - self.playbin.set_state(gst.STATE_PAUSED); + if self.is_playing: + self.mpause() def on_button_release(self, element, a): - self.playbin.set_state(gst.STATE_PLAYING) - + if self.is_playing: + self.mplay() + + def on_play_clicked(self, element): + if self.is_playing: + self.mpause() + self.play_button.set_image(self.PLAY_IMAGE) + self.is_playing = False; + else: + self.mplay() + self.play_button.set_image(self.PAUSE_IMAGE) + 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())