Development Team/Almanac/GStreamer: Difference between revisions

No edit summary
Line 143: Line 143:
self.gplayWin.resize( 300, 400 )
self.gplayWin.resize( 300, 400 )
self.gplayWin.show_all( )
self.gplayWin.show_all( )
</pre>
=== How can I add play/pause buttons and a scrubber to my audio or video? ===
<pre>
import gtk
import pygtk
pygtk.require('2.0')
import pygst
pygst.require('0.10')
import gst
import gst.interfaces
import gobject
import sugar.graphics.style
class GScrub(gtk.Window):
def __init__(self, gplay, playImg, pauseImg):
gtk.Window.__init__(self)
self._gplay = gplay
self._playImg = playImg
self._pauseImg = pauseImg
self.UPDATE_INTERVAL = 500
self.UPDATE_SCALE_ID = 0
self.CHANGED_ID = 0
self.was_playing = False
self.p_position = gst.CLOCK_TIME_NONE
self.p_duration = gst.CLOCK_TIME_NONE
self.hbox = gtk.HBox()
self.hbox.modify_bg( gtk.STATE_NORMAL, sugar.graphics.style.COLOR_BLACK.get_gdk_color() )
self.hbox.modify_bg( gtk.STATE_INSENSITIVE, sugar.graphics.style.COLOR_BLACK.get_gdk_color() )
self.add( self.hbox )
self.button = gtk.Button()
buttBox = gtk.EventBox()
buttBox.add(self.button)
buttBox.modify_bg( gtk.STATE_NORMAL, sugar.graphics.style.COLOR_BLACK.get_gdk_color() )
self.button.set_image( self._playImg )
self.button.set_property('can-default', True)
self.button.set_relief(gtk.RELIEF_NONE)
self.button.set_size_request( 55, 55 )
buttBox.set_size_request( 55, 55 )
self.button.show()
buttBox.modify_bg( gtk.STATE_NORMAL, sugar.graphics.style.COLOR_BLACK.get_gdk_color() )
self.button.modify_bg( gtk.STATE_ACTIVE, sugar.graphics.style.COLOR_BLACK.get_gdk_color() )
self.button.connect('clicked', self._buttonClickedCb)
self.hbox.pack_start(buttBox, expand=False)
self.adjustment = gtk.Adjustment(0.0, 0.00, 100.0, 0.1, 1.0, 1.0)
self.hscale = gtk.HScale(self.adjustment)
self.hscale.set_draw_value(False)
self.hscale.set_update_policy(gtk.UPDATE_CONTINUOUS)
hscaleBox = gtk.EventBox()
hscaleBox.modify_bg( gtk.STATE_NORMAL, sugar.graphics.style.COLOR_BLACK.get_gdk_color() )
hscaleBox.add( self.hscale )
self.hscale.connect('button-press-event', self._scaleButtonPressCb)
self.hscale.connect('button-release-event', self._scaleButtonReleaseCb)
self.hbox.pack_start(hscaleBox, expand=True)
def removeCallbacks( self ):
if (self.UPDATE_SCALE_ID != 0):
gobject.source_remove(self.UPDATE_SCALE_ID)
self.UPDATE_SCALE_ID = 0
if (self.CHANGED_ID != 0):
gobject.source_remove(self.CHANGED_ID)
self.CHANGED_ID = 0
def reset(self):
self.adjustment.set_value(0)
def _buttonClickedCb(self, widget):
self.play_toggled()
def set_button_play(self):
self.button.set_image(self._playImg)
def set_button_pause(self):
self.button.set_image(self._pauseImg)
def play_toggled(self):
self.p_position, self.p_duration = self._gplay.queryPosition()
if (self.p_position == self.p_duration):
self._gplay.seek(0)
self._gplay.pause()
if self._gplay.is_playing():
self._gplay.pause()
self.set_button_play()
else:
#if self._gplay.error:
# #todo: check if we have "error", and also to disable everything
# self.button.set_disabled()
#else:
self.doPlay()
def doPlay(self):
self._gplay.play()
if self.UPDATE_SCALE_ID == 0:
self.UPDATE_SCALE_ID = gobject.timeout_add(self.UPDATE_INTERVAL, self._updateScaleCb)
self.set_button_pause()
def _scaleButtonPressCb(self, widget, event):
#self.button.set_sensitive(False)
self.was_playing = self._gplay.is_playing()
if self.was_playing:
self._gplay.pause()
# don't timeout-update position during seek
if self.UPDATE_SCALE_ID != 0:
gobject.source_remove(self.UPDATE_SCALE_ID)
self.UPDATE_SCALE_ID = 0
# make sure we get changed notifies
if self.CHANGED_ID == 0:
self.CHANGED_ID = self.hscale.connect('value-changed', self._scaleValueChangedCb)
def _scaleButtonReleaseCb(self, widget, event):
# see seek.cstop_seek
widget.disconnect(self.CHANGED_ID)
self.CHANGED_ID = 0
#self.button.set_sensitive(True)
if self.was_playing:
self._gplay.play()
if self.UPDATE_SCALE_ID != 0:
pass
#print('Had a previous update timeout id')
else:
self.UPDATE_SCALE_ID = gobject.timeout_add(self.UPDATE_INTERVAL, self._updateScaleCb)
def _scaleValueChangedCb(self, scale):
real = long(scale.get_value() * self.p_duration / 100) # in ns
self._gplay.seek(real)
# allow for a preroll
self._gplay.get_state(timeout=50*gst.MSECOND) # 50 ms
def _updateScaleCb(self):
self.p_position, self.p_duration = self._gplay.queryPosition()
if self.p_position != gst.CLOCK_TIME_NONE:
value = self.p_position * 100.0 / self.p_duration
if (value > 99):
value = 99
elif (value < 0):
value = 0
self.adjustment.set_value(value)
if self._gplay.is_playing() and (self.p_position == self.p_duration):
self._gplay.pause()
self.set_button_play()
return True
</pre>
</pre>