From: <wi...@fr...> - 2005-07-12 13:27:48
|
CVS Root: /cvs/gstreamer Module: gst-python Changes by: wingo Date: Tue Jul 12 2005 06:27:44 PDT Log message: 2005-07-12 Andy Wingo <wi...@po...> * configure.ac (AC_CONFIG_FILES): * examples/: Moved all examples up from examples/gst/ into examples/. Modified files: . : ChangeLog configure.ac examples : Makefile.am Added files: examples : audioconcat.py bps.py cp.py f2f.py filesrc.py gst123 gstfile.py play.py vorbisplay.py Removed files: examples/gst : .cvsignore Makefile.am audioconcat.py bps.py cp.py f2f.py filesrc.py gst123 gstfile.py play.py vorbisplay.py Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-python/ChangeLog.diff?r1=1.174&r2=1.175 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-python/configure.ac.diff?r1=1.65&r2=1.66 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-python/examples/Makefile.am.diff?r1=1.8&r2=1.9 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-python/examples/audioconcat.py?rev=1.1&content-type=text/vnd.viewcvs-markup http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-python/examples/bps.py?rev=1.1&content-type=text/vnd.viewcvs-markup http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-python/examples/cp.py?rev=1.1&content-type=text/vnd.viewcvs-markup http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-python/examples/f2f.py?rev=1.1&content-type=text/vnd.viewcvs-markup http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-python/examples/filesrc.py?rev=1.1&content-type=text/vnd.viewcvs-markup http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-python/examples/gst123?rev=1.1&content-type=text/vnd.viewcvs-markup http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-python/examples/gstfile.py?rev=1.1&content-type=text/vnd.viewcvs-markup http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-python/examples/play.py?rev=1.1&content-type=text/vnd.viewcvs-markup http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-python/examples/vorbisplay.py?rev=1.1&content-type=text/vnd.viewcvs-markup http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-python/examples/gst/.cvsignore http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-python/examples/gst/Makefile.am http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-python/examples/gst/audioconcat.py http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-python/examples/gst/bps.py http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-python/examples/gst/cp.py http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-python/examples/gst/f2f.py http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-python/examples/gst/filesrc.py http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-python/examples/gst/gst123 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-python/examples/gst/gstfile.py http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-python/examples/gst/play.py http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-python/examples/gst/vorbisplay.py ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-python/ChangeLog,v retrieving revision 1.174 retrieving revision 1.175 diff -u -d -r1.174 -r1.175 --- ChangeLog 12 Jul 2005 13:15:26 -0000 1.174 +++ ChangeLog 12 Jul 2005 13:27:31 -0000 1.175 @@ -1,5 +1,9 @@ 2005-07-12 Andy Wingo <wi...@po...> + * configure.ac (AC_CONFIG_FILES): + * examples/: Moved all examples up from examples/gst/ into + examples/. + * examples/gstplay: Removed examples for old gstplay. 2005-07-12 Edward Hervey <ed...@fl...> Index: configure.ac RCS file: /cvs/gstreamer/gst-python/configure.ac,v retrieving revision 1.65 retrieving revision 1.66 diff -u -d -r1.65 -r1.66 --- configure.ac 5 Jul 2005 13:50:21 -0000 1.65 +++ configure.ac 12 Jul 2005 13:27:31 -0000 1.66 @@ -165,7 +165,6 @@ AC_OUTPUT([ Makefile examples/Makefile - examples/gst/Makefile gst/Makefile pkgconfig/Makefile pkgconfig/gst-python.pc Index: Makefile.am RCS file: /cvs/gstreamer/gst-python/examples/Makefile.am,v retrieving revision 1.8 retrieving revision 1.9 diff -u -d -r1.8 -r1.9 --- Makefile.am 5 Jul 2005 13:52:17 -0000 1.8 +++ Makefile.am 12 Jul 2005 13:27:31 -0000 1.9 @@ -1 +1,13 @@ -SUBDIRS = gst +examplesdir = $(pkgdatadir)/examples +examples_DATA = \ + bps.py \ + cp.py \ + f2f.py \ + filesrc.py \ + gst123 \ + play.py \ + vorbisplay.py \ + gstfile.py \ + audioconcat.py +EXTRA_DIST = $(examples_DATA) --- NEW FILE: audioconcat.py --- #!/usr/bin/env python # audio concat tool # takes in one or more audio files and creates one audio file of the combination # Uses the gnonlin elements (http://gnonlin.sf.net/) import os import sys import gobject import gst from gstfile import Discoverer, time_to_string class AudioSource(gst.Bin): """A bin for audio sources with proper audio converters""" def __init__(self, filename, caps): gst.Bin.__init__(self) self.filename = filename self.outcaps = caps self.filesrc = gst.element_factory_make("filesrc") self.filesrc.set_property("location", self.filename) self.dbin = gst.element_factory_make("decodebin") self.ident = gst.element_factory_make("identity") self.audioconvert = gst.element_factory_make("audioconvert") self.audioscale = gst.element_factory_make("audioscale") self.add_many(self.filesrc, self.dbin, self.ident, self.audioconvert, self.audioscale) self.filesrc.link(self.dbin) self.audioconvert.link(self.audioscale) self.audioscale.link(self.ident, caps) self.add_ghost_pad(self.ident.get_pad("src"), "src") self.dbin.connect("new-decoded-pad", self._new_decoded_pad_cb) def _new_decoded_pad_cb(self, dbin, pad, is_last): if not "audio" in pad.get_caps().to_string(): return pad.link(self.audioconvert.get_pad("sink")) gobject.type_register(AudioSource) class AudioConcat(gst.Thread): """A Gstreamer thread that concatenates a series of audio files to another audio file""" def __init__(self, infiles, outfile, audioenc="rawvorbisenc", muxer="oggmux"): gst.Thread.__init__(self) self.infiles = infiles self.outfile = outfile self.audioenc = gst.element_factory_make(audioenc) if not self.audioenc: raise NameError, str(audioenc + " audio encoder is not available") self.muxer = gst.element_factory_make(muxer) if not self.muxer: raise NameError, str(muxer + " muxer is not available") self.filesink = gst.element_factory_make("filesink") self.filesink.set_property("location", self.outfile) self.timeline = gst.element_factory_make("gnltimeline") self.audiocomp = gst.element_factory_make("gnlcomposition", "audiocomp") self.add_many(self.timeline, self.audioconvert, self.audioenc, self.muxer, self.filesink) ## identity perfect stream check ! identity = gst.element_factory_make("identity") identity.set_property("check-perfect", True) self.add(identity) #self.audioconvert.link(self.audioenc) if not self.audioconvert.link(identity): print "couldn't link audioconv -> ident" if not identity.link(self.audioenc): print "couldn't link ident -> audioenc" self.audioenc.link(self.muxer) self.muxer.link(self.filesink) self.timeline.add(self.audiocomp) caps = gst.caps_from_string("audio/x-raw-int,channels=2,rate=44100,depth=16") pos = 0L for infile in self.infiles: d = Discoverer(infile) if not d.audiolength: continue print "file", infile, "has length", time_to_string(d.audiolength) asource = AudioSource(infile, caps) gnlsource = gst.element_factory_make("gnlsource") gnlsource.set_property("element", asource) gnlsource.set_property("media-start", 0L) gnlsource.set_property("media-stop", d.audiolength) gnlsource.set_property("start", pos) gnlsource.set_property("stop", pos + d.audiolength) self.audiocomp.add(gnlsource) pos += d.audiolength self.timeline.get_pad("src_audiocomp").link(self.audioconvert.get_pad("sink")) timelineprobe = gst.Probe(False, self.timelineprobe) self.timeline.get_pad("src_audiocomp").add_probe(timelineprobe) def timelineprobe(self, probe, data): if isinstance(data, gst.Buffer): print "timeline outputs buffer", data.timestamp, data.duration else: print "timeline ouputs event", data.type return True gobject.type_register(AudioConcat) def eos_cb(pipeline): sys.exit() if __name__ == "__main__": if len(sys.argv) < 3: print "Usage : %s <input file(s)> <output file>" % sys.argv[0] print "\tCreates an ogg file from all the audio input files" sys.exit() if not gst.element_factory_make("gnltimeline"): print "You need the gnonlin elements installed (http://gnonlin.sf.net/)" concat = AudioConcat(sys.argv[1:-1], sys.argv[-1]) concat.connect("eos", eos_cb) concat.set_state(gst.STATE_PLAYING) gst.main() --- NEW FILE: bps.py --- # # gst-python # Copyright (C) 2003 David I. Lehn # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Library General Public # License as published by the Free Software Foundation; either # version 2 of the License, or (at your option) any later version. # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Library General Public License for more details. # You should have received a copy of the GNU Library General Public # License along with this library; if not, write to the # Free Software Foundation, Inc., 59 Temple Place - Suite 330, # Boston, MA 02111-1307, USA. # # Author: David I. Lehn <dl...@us...> import pygtk pygtk.require('2.0') import time import gtk class BPS(object): def __init__(self): self.buffers = 0 self.start = 0 def done(self): end = time.time() dt = end - self.start bps = self.buffers/dt spb = dt/self.buffers print '\t%d buffers / %fs\t= %f bps\t= %f spb' % (self.buffers, dt, bps, spb) def eos(self, sink): self.done() if self.method in ('gtk', 'c'): gst.main_quit() def fakesrc(self, buffers): src = gst.element_factory_make('fakesrc','src') src.set_property('silent', 1) src.set_property('num_buffers', buffers) return src def fakesink(self): sink = gst.element_factory_make('fakesink','sink') sink.set_property('silent', 1) return sink def build_pipeline(self, buffers): pipeline = gst.Pipeline('pipeline') src = self.fakesrc(buffers) pipeline.add(src) sink = self.fakesink() pipeline.add(sink) sink.connect('eos', self.eos) src.link(sink) return pipeline def notify(self, sender, obj, arg): prop = obj.get_property(arg.name) print 'notify', sender, arg.name, prop print prop def idle(self, pipeline): return pipeline.iterate() def test(self, method): print '%s:' % (method,), self.method = method print self.pipeline.get_state() self.pipeline.set_state(gst.STATE_PLAYING) if method == 'py': self.start = time.time() while self.pipeline.iterate(): pass elif method == 'c': gobject.idle_add(self.pipeline.iterate) gst.main() #elif method == 'gst': # self.start = time.time() # gtk.idle_add(self.idle, self.pipeline) # gtk.main() self.pipeline.set_state(gst.STATE_NULL) def run(self, buffers, methods): self.buffers = buffers print '# Testing buffer processing rate for "fakesrc ! fakesink"' #print '# gst = gtk idle loop function in python' print '# c = gtk idle loop function in C' print '# py = full iterate loop in python' print '# all = full iterate loop in C' print '# bps = buffers per second' print '# spb = seconds per buffer' self.pipeline = self.build_pipeline(buffers) assert self.pipeline #self.pipeline.connect('deep-notify', self.notify) map(self.test, methods) def main(args): "GStreamer Buffers-Per-Second tester" if len(args) < 2: print 'usage: %s buffers [method method ...]' % args[0] return 1 bps = BPS() buffers = int(args[1]) if buffers < 0: print 'buffers must be higher than 0' return methods = args[2:] if not methods: methods = ('gtk', 'c', 'py', 'all') bps.run(buffers, methods) if __name__ == '__main__': sys.exit(main(sys.argv)) --- NEW FILE: cp.py --- # Copyright (C) 2002 David I. Lehn <dl...@us...> # 2004 Johan Dahlin <jo...@gn...> def filter(input, output): "A GStreamer copy pipeline which can add arbitrary filters" # create a new bin to hold the elements bin = gst.parse_launch('filesrc name=source ! ' + 'statistics silent=false buffer-update-freq=1 ' + 'update_on_eos=true ! ' + 'filesink name=sink') filesrc = bin.get_by_name('source') filesrc.set_property('location', input) filesink = bin.get_by_name('sink') filesink.set_property('location', output) # start playing bin.set_state(gst.STATE_PLAYING); try: while bin.iterate(): pass except KeyboardInterrupt: pass # stop the bin bin.set_state(gst.STATE_NULL) "A GStreamer based cp(1) with stats" if len(args) != 3: print 'usage: %s source dest' % (sys.argv[0]) return -1 return filter(args[1], args[2]) sys.exit(main(sys.argv)) --- NEW FILE: f2f.py --- # Copyright (C) 2002 David I. Lehn def handoff_cb(sender, *args): print sender.get_name(), args #gst_debug_set_categories(-1) bin = gst.parse_launch('fakesrc name=source silent=1 num-buffers=10 ! ' + 'fakesink name=sink silent=1') source = bin.get_by_name('source') source.connect('handoff', handoff_cb) sink = bin.get_by_name('source') sink.connect('handoff', handoff_cb) res = bin.set_state(gst.STATE_PLAYING); assert res while bin.iterate(): res = bin.set_state(gst.STATE_NULL) --- NEW FILE: filesrc.py --- # GStreamer python bindings # filesrc.py: implements a file source element completely in python class FileSource(gst.Element): blocksize = 4096 fd = None def __init__(self, name): self.__gobject_init__() self.set_name(name) self.srcpad = gst.Pad('src', gst.PAD_SRC) self.srcpad.set_get_function(self.srcpad_get) self.add_pad(self.srcpad) def set_property(self, name, value): if name == 'location': self.fd = open(value, 'r') def srcpad_get(self, pad): data = self.fd.read(self.blocksize) if data: return gst.Buffer(data) self.set_eos() return gst.Event(gst.EVENT_EOS) gobject.type_register(FileSource) print 'This example is not finished yet.' return if len(args) != 3: print 'Usage: %s input output' % (args[0]) return -1 bin = gst.Pipeline('pipeline') filesrc = FileSource('filesource') #filesrc = gst.Element('filesrc', 'src') assert filesrc filesrc.set_property('location', args[1]) filesink = gst.element_factory_make('filesink', 'sink') filesink.set_property('location', args[2]) bin.add_many(filesrc, filesink) gst.element_link_many(filesrc, filesink) bin.set_state(gst.STATE_PLAYING); while bin.iterate(): pass bin.set_state(gst.STATE_NULL) --- NEW FILE: gst123 --- # -*- Mode: python -*- import getopt """Usage: gst123 [<options>] <input file> ... -h, --help this help -V, --version display gst123 version -d, --device=d uses 'd' as an output device Possible devices are ('*'=live, '@'=file): null* wav@ raw@ au@ arts* esd* oss* -f, --file=filename Set the output filename for a previously specified file device (with -d). -k n, --skip n Skip the first 'n' seconds -b n, --buffer n use an input buffer of 'n' kilobytes -v, --verbose display progress and other status information -q, --quiet don't display anything (no title) -z, --shuffle shuffle play""" def found_tags_cb(element, source, tags): for tag in tags.keys(): if tag in ['title', 'artist', 'genre', 'album']: ntag = tag[0].upper() + tag[1:] + ':' print '%-8s %s' % (ntag, tags[tag]) def error_cb(bin, element, error, debug): print error raise SystemExit def pad_notify_caps_cb(pad, arg): caps = pad.get_negotiated_caps() if not caps: return for structure in caps: print 'Bitstream is %(channels)d channel(s), %(rate)dHz' % structure def playfile(filename): bin = gst.Thread('player') bin.connect('eos', lambda bin: gst.main_quit()) bin.connect('error', error_cb) source = gst.element_factory_make('filesrc', 'src') source.set_property('location', filename) spider = gst.element_factory_make('spider', 'spider') spider.connect('found-tag', found_tags_cb) sink = gst.element_factory_make('osssink', 'sink') #sink.set_property('release-device', 1) pad = sink.get_pad('sink') pad.connect('notify::caps', pad_notify_caps_cb) bin.add_many(source, spider, sink) if not gst.element_link_many(source, spider, sink): print "ERROR: could not link" sys.exit(1) print 'Playing:', filename if not bin.set_state(gst.STATE_PLAYING): print "ERROR: could not set bin to playing" while 1: try: if not gst.main(): break except KeyboardInterrupt: if not bin.set_state(gst.STATE_PAUSED): print "ERROR: could not set bin to paused" sys.exit(1) sys.stdout.write("Paused. Press Enter to go back to playing.") sys.stdout.flush() try: sys.stdin.readline() if not bin.set_state(gst.STATE_PLAYING): print "ERROR: could not set bin to playing" sys.exit(1) print "Playing." except KeyboardInterrupt: print if len(args) > 2: print 'usage: gst123 files...' return 2 args2, opt = getopt.getopt(args[1:], 'b:d:f:hk:vVqz', ['help', 'version', 'device=', 'file=', 'skip=', 'buffer=', 'verbose', 'quiet', 'shuffle']) for arg in args[1:]: playfile(arg) raise SystemExit for i in range(10, 20, 1): pass --- NEW FILE: gstfile.py --- # gstfile.py # (c) 2005 Edward Hervey <edward at fluendo dot com> # Discovers and prints out multimedia information of files # This example shows how to use gst-python: # _ in an object-oriented way (Discoverer class) # _ subclassing a gst.Pipeline # _ and overidding existing methods (do_iterate()) def time_to_string(value): """ transform a value in nanoseconds into a human-readable string ms = value / gst.MSECOND sec = ms / 1000 ms = ms % 1000 min = sec / 60 sec = sec % 60 return "%2dm %2ds %3d" % (min, sec, ms) class Discoverer(gst.Pipeline): Discovers information about files mimetype = None audiocaps = {} videocaps = {} videowidth = 0 videoheight = 0 videorate = 0 audiofloat = False audiorate = 0 audiodepth = 0 audiowidth = 0 audiochannels = 0 audiolength = 0L videolength = 0L is_video = False is_audio = False otherstreams = [] finished = False tags = {} def __init__(self, filename): gobject.GObject.__init__(self) self.mimetype = None self.audiocaps = {} self.videocaps = {} self.videowidth = 0 self.videoheight = 0 self.videorate = 0 self.audiofloat = False self.audiorate = 0 self.audiodepth = 0 self.audiowidth = 0 self.audiochannels = 0 self.audiolength = 0L self.videolength = 0L self.is_video = False self.is_audio = False self.otherstreams = [] self.finished = False self.tags = {} if not os.path.isfile(filename): self.finished = True # the initial elements of the pipeline self.src = gst.element_factory_make("filesrc") self.src.set_property("location", filename) self.src.set_property("blocksize", 1000000) self.add_many(self.src, self.dbin) self.src.link(self.dbin) self.typefind = self.dbin.get_by_name("typefind") # callbacks self.typefind.connect("have-type", self._have_type_cb) self.dbin.connect("unknown-type", self._unknown_type_cb) self.dbin.connect("found-tag", self._found_tag_cb) self.discover() def discover(self): """iterate on ourself to find the information on the given file""" if self.finished: self.set_state(gst.STATE_PLAYING) while 1: if not self.iterate(): self.set_state(gst.STATE_NULL) self.finished = True def print_info(self): """prints out the information on the given file""" if not self.finished: self.discover() if not self.mimetype: print "Unknown media type" print "Mime Type :\t", self.mimetype if not self.is_video and not self.is_audio: print "Length :\t", time_to_string(max(self.audiolength, self.videolength)) print "\tAudio:", time_to_string(self.audiolength), "\tVideo:", time_to_string(self.videolength) if self.is_video: print "Video :" print "\t%d x %d @ %.2f fps" % (self.videowidth, self.videoheight, self.videorate) if self.tags.has_key("video-codec"): print "\tCodec :", self.tags.pop("video-codec") if self.is_audio: print "Audio :" if self.audiofloat: print "\t%d channels(s) : %dHz @ %dbits (float)" % (self.audiochannels, self.audiorate, self.audiowidth) else: print "\t%d channels(s) : %dHz @ %dbits (int)" % (self.audiochannels, self.audiorate, self.audiodepth) if self.tags.has_key("audio-codec"): print "\tCodec :", self.tags.pop("audio-codec") for stream in self.otherstreams: if not stream == self.mimetype: print "Other unsuported Multimedia stream :", stream if self.tags: print "Additional information :" for tag in self.tags.keys(): print "%20s :\t" % tag, self.tags[tag] def _unknown_type_cb(self, dbin, pad, caps): self.otherstreams.append(caps.to_string()) def _have_type_cb(self, typefind, prob, caps): self.mimetype = caps.to_string() def _notify_caps_cb(self, pad, args): caps = pad.get_negotiated_caps() if not caps: # the caps are fixed # We now get the total length of that stream length = pad.get_peer().query(gst.QUERY_TOTAL, gst.FORMAT_TIME) # We store the caps and length in the proper location if "audio" in caps.to_string(): self.audiocaps = caps self.audiolength = length self.audiorate = caps[0]["rate"] self.audiowidth = caps[0]["width"] self.audiochannels = caps[0]["channels"] if "x-raw-float" in caps.to_string(): self.audiofloat = True self.audiodepth = caps[0]["depth"] if (not self.is_video) or self.videocaps: self.finished = True elif "video" in caps.to_string(): self.videocaps = caps self.videolength = length self.videowidth = caps[0]["width"] self.videoheight = caps[0]["height"] self.videorate = caps[0]["framerate"] if (not self.is_audio) or self.audiocaps: # Does the file contain got audio or video ? if "audio" in pad.get_caps().to_string(): self.is_audio = True elif "video" in pad.get_caps().to_string(): self.is_video = True if is_last and not self.is_video and not self.is_audio: # we connect a fakesink to the new pad... fakesink = gst.element_factory_make("fakesink") self.add(fakesink) sinkpad = fakesink.get_pad("sink") # ... and connect a callback for when the caps are fixed sinkpad.connect("notify::caps", self._notify_caps_cb) pad.link(sinkpad) fakesink.set_state(gst.STATE_PLAYING) def _found_tag_cb(self, dbin, source, tags): self.tags.update(tags) def do_iterate(self): # this overrides the GstBin 'iterate' method # if we have finished discovering we stop the iteration return False # else we call the parent class method return gst.Pipeline.do_iterate(self) gobject.type_register(Discoverer) print 'usage: %s files...' % args[0] if len(args[1:]) > 1: for filename in args[1:]: print "File :", filename Discoverer(filename).print_info() print "\n" else: Discoverer(args[1]).print_info() --- NEW FILE: play.py --- import gst.interfaces class GstPlayer: self.player = gst.element_factory_make("playbin", "player") def set_video_sink(self, sink): self.player.set_property('video-sink', sink) print self.player.get_property('video-sink') def set_location(self, location): self.player.set_property('uri', location) def get_length(self): return self.player.query(gst.QUERY_TOTAL, gst.FORMAT_TIME) def get_position(self): return self.player.query(gst.QUERY_POSITION, gst.FORMAT_TIME) def seek(self, location): print "seek to %ld on element %s" % (location, self.player.get_name()) event = gst.event_new_seek(gst.FORMAT_TIME | gst.SEEK_METHOD_SET | gst.SEEK_FLAG_FLUSH, location) self.player.send_event(event) self.player.set_state(gst.STATE_PLAYING) def pause(self): self.player.set_state(gst.STATE_PAUSED) def play(self): def stop(self): self.player.set_state(gst.STATE_READY) is_playing = lambda self: self.player.get_state() == gst.STATE_PLAYING is_paused = lambda self: self.player.get_state() == gst.STATE_PAUSED is_stopped = lambda self: self.player.get_state() == gst.STATE_READY class VideoWidget(gtk.DrawingArea): def __init__(self, player): gtk.DrawingArea.__init__(self) self.connect('destroy', self.destroy_cb) self.connect_after('realize', self.after_realize_cb) self.set_size_request(400, 400) self.player = player self.imagesink = gst.element_factory_make('xvimagesink') self.player.set_video_sink(self.imagesink) def destroy_cb(self, da): self.set_window_id(0L) # Sort of a hack, but it works for now. def after_realize_cb(self, window): gtk.idle_add(self.idler) def idler(self): self.set_window_id(self.window.xid) def set_window_id(self, xid): self.imagesink.set_xwindow_id(xid) class PlayerWindow(gtk.Window): UPDATE_INTERVAL = 500 gtk.Window.__init__(self) self.connect('delete-event', gtk.main_quit) self.set_default_size(96, 96) self.player = GstPlayer() self.create_ui() self.update_id = -1 def load_file(self, location): self.player.set_location(location) def create_ui(self): vbox = gtk.VBox() videowidget = VideoWidget(self.player) vbox.pack_start(videowidget) hbox = gtk.HBox() vbox.pack_start(hbox) button = gtk.Button('play') button.connect('clicked', self.play_clicked_cb) hbox.pack_start(button, False) button = gtk.Button("pause"); button.connect('clicked', self.pause_clicked_cb) button = gtk.Button("stop"); button.connect('clicked', self.stop_clicked_cb) self.adjustment = gtk.Adjustment(0.0, 0.00, 100.0, 0.1, 1.0, 1.0) hscale = gtk.HScale(self.adjustment) hscale.set_digits(2) hscale.set_update_policy(gtk.UPDATE_CONTINUOUS) hscale.connect('button-press-event', self.scale_button_press_cb) hscale.connect('button-release-event', self.scale_button_release_cb) hscale.connect('format-value', self.scale_format_value_cb) hbox.pack_start(hscale) self.add(vbox) def scale_format_value_cb(self, scale, value): duration = self.player.get_length() if duration == -1: real = 0 real = value * duration / 100 seconds = real / gst.SECOND return "%02d:%02d" % (seconds / 60, seconds % 60) def scale_button_press_cb(self, widget, event): self.player.pause() if self.update_id != -1: gtk.timeout_remove(self.update_id) self.update_id = -1 def scale_button_release_cb(self, widget, event): real = long(widget.get_value() * duration / 100) self.player.seek(real) self.update_id = gtk.timeout_add(self.UPDATE_INTERVAL, self.update_scale_cb) def update_scale_cb(self): length = self.player.get_length() if length: value = self.player.get_position() * 100.0 / length self.adjustment.set_value(value) def play_clicked_cb(self, button): if self.player.is_playing(): self.player.play() def pause_clicked_cb(self, button): if self.player.is_paused(): def stop_clicked_cb(self, button): if self.player.is_stopped(): self.player.stop() self.adjustment.set_value(0.0) w = PlayerWindow() w.load_file(args[1]) w.show_all() gtk.main() --- NEW FILE: vorbisplay.py --- def gst_props_debug_entry(entry, level=0): name = entry.get_name() type = entry.get_props_type() indent = ' '*level if type == PROPS_INT_TYPE: ret, val = entry.get_int() assert ret print '%s%s: int %d' % (indent, name, val) elif type == PROPS_FLOAT_TYPE: ret, val = entry.get_float() print '%s%s: float %f' % (indent, name, val) elif type == PROPS_FOURCC_TYPE: ret, val = entry.get_fourcc() print '%s%s: fourcc %c%c%c%c' % (indent, name, (val>>0)&0xff, (val>>8)&0xff, (val>>16)&0xff, (val>>24)&0xff) elif type == PROPS_BOOLEAN_TYPE: ret, val = entry.get_bool() print '%s%s: bool %d' % (indent, name, val) elif type == PROPS_STRING_TYPE: ret, val = entry.get_string() print '%s%s: string "%s"' % (indent, name, val) elif type == PROPS_INT_RANGE_TYPE: ret, min, max = entry.get_int_range() print '%s%s: int range %d-%d' % (indent, name, min, max) elif type == PROPS_FLOAT_RANGE_TYPE: ret, min, max = entry.get_float_range() print '%s%s: float range %f-%f' % (indent, name, min, max) elif type == PROPS_LIST_TYPE: ret, val = entry.get_list() print '[list] (' for e in val: gst_props_debug_entry(e, level+1) print ')' print '%sWARNING: %s: unknown property type %d' % (indent, name, type) def debug_caps(caps): props = caps.get_props() ret, plist = props.get_list() for e in plist: gst_props_debug_entry(e, level=1) def streaminfo(sender, pspec): assert pspec.name == 'streaminfo' caps = sender.get_property(pspec.name) print 'streaminfo:' debug_caps(caps) def metadata(sender, pspec): assert pspec.name == 'metadata' print 'metadata:' def decoder_notified(sender, pspec): if pspec.name == 'streaminfo': streaminfo(sender, pspec) elif pspec.name == 'metadata': metadata(sender, pspec) print 'notify:', sender, pspec "Basic example to play an Ogg Vorbis stream through OSS" if len(args) != 2: print 'usage: %s <Ogg Vorbis file>' % args bin = gst.parse_launch('filesrc name=source ! ' + 'oggdemux name=demuxer ! ' + 'vorbisdec name=decoder ! ' + 'audioconvert ! osssink') filesrc = bin.get_by_name('source') demuxer = bin.get_by_name('demuxer') demuxer.connect('notify', decoder_notified) decoder = bin.get_by_name('decoder') decoder.connect('notify', decoder_notified) # start playing try: while bin.iterate(): pass except KeyboardInterrupt: # stop the bin --- .cvsignore DELETED --- --- Makefile.am DELETED --- --- audioconcat.py DELETED --- --- bps.py DELETED --- --- cp.py DELETED --- --- f2f.py DELETED --- --- filesrc.py DELETED --- --- gst123 DELETED --- --- gstfile.py DELETED --- --- play.py DELETED --- --- vorbisplay.py DELETED --- |