Index: plugins/artdisplay/artdisplay/CoverArtDatabase.py
===================================================================
--- plugins/artdisplay/artdisplay/CoverArtDatabase.py	(revision 5445)
+++ plugins/artdisplay/artdisplay/CoverArtDatabase.py	(working copy)
@@ -26,10 +26,11 @@
 from PodcastCoverArtSearch import PodcastCoverArtSearch
 from AmazonCoverArtSearch import AmazonCoverArtSearch
 from LocalCoverArtSearch import LocalCoverArtSearch
+from EmbeddedArtSearch import EmbeddedArtSearch
 
 from urllib import unquote
 
-ART_SEARCHES_LOCAL = [LocalCoverArtSearch]
+ART_SEARCHES_LOCAL = [EmbeddedArtSearch, LocalCoverArtSearch]
 ART_SEARCHES_REMOTE = [PodcastCoverArtSearch, AmazonCoverArtSearch]
 ART_FOLDER = '~/.gnome2/rhythmbox/covers'
 ART_CACHE_EXTENSION = 'jpg'
Index: plugins/artdisplay/artdisplay/EmbeddedArtSearch.py
===================================================================
--- plugins/artdisplay/artdisplay/EmbeddedArtSearch.py	(revision 0)
+++ plugins/artdisplay/artdisplay/EmbeddedArtSearch.py	(revision 0)
@@ -0,0 +1,103 @@
+# -*- Mode: python; coding: utf-8; tab-width: 8; indent-tabs-mode: t; -*- 
+#
+# Copyright (C) 2007 - John Millikin <jmillikin@gmail.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+# 
+# This program 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA.
+
+import os
+import gnomevfs
+
+import codecs
+import pygst
+pygst.require ("0.10")
+import gst
+
+def extended_comment_to_dict (comments):
+	def split (comment):
+		key, value = comment.split ('=', 1)
+		return key.upper (), value
+		
+	return dict (split (comment) for comment in comments)
+	
+def on_message(bus, message, pipeline, on_found_data):
+	t = message.type
+	if t == gst.MESSAGE_EOS:
+		pipeline.set_state(gst.STATE_NULL)
+		on_found_data (None)
+		
+	elif t == gst.MESSAGE_ERROR:
+		pipeline.set_state(gst.STATE_NULL)
+		err, debug = message.parse_error()
+		print "Error: %s" % err, debug
+		on_found_data (None)
+		
+	elif t == gst.MESSAGE_TAG:
+		pipeline.set_state(gst.STATE_NULL)
+		tags = message.structure
+		if tags.has_field ('image'):
+			on_found_data (tags['image'])
+		elif tags.has_field ('extended-comment'):
+			extended = extended_comment_to_dict (tags['extended-comment'])
+			if 'COVERART' in extended:
+				decoder = codecs.getdecoder ('base64')
+				on_found_data (decoder (extended['COVERART'])[0])
+				
+def build_pipeline (uri, on_found_data):
+	pipeline = gst.Pipeline ("pipeline")
+	source = gst.element_factory_make ("gnomevfssrc", None)
+	decoder = gst.element_factory_make ("decodebin", None)
+	audiosink = gst.element_factory_make ("fakesink", None)
+	
+	source.set_property ('location', uri)
+	decoder.connect ('new-decoded-pad',
+	                 lambda dbin, pad, islast: pad.link (audiosink.get_pad ('sink')))
+	
+	pipeline.add (source)
+	pipeline.add (decoder)
+	pipeline.add (audiosink)
+	
+	gst.element_link_many (source, decoder)
+	bus = pipeline.get_bus ()
+	bus.add_signal_watch ()
+	bus.connect ('message', on_message, pipeline, on_found_data)
+	pipeline.set_state (gst.STATE_PLAYING)
+	status, state, pending = pipeline.get_state ()
+	
+	if state != gst.STATE_PLAYING:
+		print 'Error reading embedded art for %r' % (filename)
+		on_found_data (None)
+		
+class EmbeddedArtSearch (object):
+	def __init__ (self, loader):
+		self.loader = loader
+		
+	def search (self, db, entry, on_search_completed_cb, *args):
+		def on_found_data (image_data):
+			on_search_completed_cb (self, entry, [image_data], *args)
+			
+		try:
+			uri = gnomevfs.URI (entry.get_playback_uri())
+			print 'searching for embedded art for %r' % (uri)
+			build_pipeline (uri, on_found_data)
+		except StandardError:
+			on_found_data (None)
+			
+	def search_next (self):
+		return False
+		
+	def get_best_match_urls (self, search_results):
+		for image_data in search_results:
+			yield image_data, None
+			
