import gst, gtk, urllib, sys, os, gobject FIELDS = [ "album", "artist", "track-number", "title" ] class TagFetcher(object): def __init__(self, path, verify_scan_cb=None, save_data_cb=None, debug=False): self.path = path self.debug = debug if not self.path.endswith("/"): self.path += "/" self.data = {} self.verify_scan_cb = verify_scan_cb self.save_data_cb = save_data_cb def tagmsg(self, bus, msg): taglist = msg.parse_tag() for k in taglist.keys(): if k in FIELDS: self.taglist[k] = taglist[k] def asyncdone(self, bus, msg): self.pipeline.set_state(gst.STATE_NULL) for f in FIELDS: if not self.taglist.has_key(f): if f == "title": fne = os.path.split(self.next_base)[1] fn = os.path.splitext(fne)[0] self.taglist[f] = fn else: self.taglist[f] = "Unknown" self.data[self.next_relative] = self.taglist self.parse_one() def pipeline_error(self, bus, msg): # some sort of error in the playback # merrily skip on to the next one self.pipeline.set_state(gst.STATE_NULL) self.parse_one() def parse(self, uri): self.pipeline = gst.parse_launch("playbin uri=%s" % uri) fakesink = gst.element_factory_make("fakesink", "fakesink") fakesink2 = gst.element_factory_make("fakesink", "fakesink2") self.pipeline.set_property("video-sink", fakesink) self.pipeline.set_property("audio-sink", fakesink2) bus = self.pipeline.get_bus() bus.add_signal_watch() bus.connect('message::tag', self.tagmsg) bus.connect('message::error', self.pipeline_error) bus.connect('message::async-done', self.asyncdone) self.taglist = {} self.pipeline.set_state(gst.STATE_PAUSED) def run(self): self.files = [os.path.join(path, f) for path, dirs, files in os.walk(self.path) for f in files] self.parse_one() def parse_one(self): try: self.next_base = self.files.pop(0) except IndexError: if self.save_data_cb: self.save_data_cb(self.data) return False self.next_relative = self.next_base[len(self.path):] self.next = os.path.realpath(self.next_base) self.next = "file://%s" % urllib.quote(self.next) if self.verify_scan_cb: do_scan = self.verify_scan_cb(self.next_relative) if not do_scan: gobject.idle_add(self.parse_one) return False # we might have been idle_added if self.debug: print "Scanning", self.next_relative self.parse(self.next) return False # we might have been idle_added if __name__ == "__main__": def dump(data): print data gtk.main_quit() def verify(f): return "iv" in f fetcher = TagFetcher(sys.argv[1], verify_scan_cb=verify, save_data_cb=dump) fetcher.run() gtk.main()