diff --git a/plugins/generic-player/rb-generic-player-source.c b/plugins/generic-player/rb-generic-player-source.c
index dd4ab99..cef9b4d 100644
--- a/plugins/generic-player/rb-generic-player-source.c
+++ b/plugins/generic-player/rb-generic-player-source.c
@@ -177,20 +231,74 @@ rb_generic_player_source_constructor (GType type,
 	return G_OBJECT (source);
 }
 
+static char *
+get_is_audio_player_path (GnomeVFSVolume *volume)
+{
+	char *path = gnome_vfs_volume_get_activation_uri (volume);
+	char *file = g_build_filename (path, ".is_audio_player", NULL);
+	g_free (path);
+
+	if (rb_uri_is_local (file) && rb_uri_exists (file)) {
+		return file;
+	}
+
+	g_free (file);
+	return NULL;
+}
+
+static void
+set_playlist_formats (RBGenericPlayerSource *source, char **formats)
+{
+	RBGenericPlayerSourcePrivate *priv = GENERIC_PLAYER_SOURCE_GET_PRIVATE (source);
+	int fmt;
+
+	priv->playlist_format_unknown = TRUE;
+	priv->playlist_format_m3u = FALSE;
+	priv->playlist_format_pls = FALSE;
+	for (fmt = 0; formats[fmt] != NULL; fmt++) {
+		char *format;
+		char *stripped;
+
+		format = g_strdup (formats[fmt]);
+		stripped = g_strstrip (format);
+
+		if (strcmp (stripped, "audio/x-mpegurl") == 0) {
+			rb_debug ("device supports M3U playlists");
+			priv->playlist_format_unknown = FALSE;
+			priv->playlist_format_m3u = TRUE;
+		} else if (strcmp (stripped, "audio/x-scpls") == 0) {
+			rb_debug ("device supports PLS playlists");
+			priv->playlist_format_unknown = FALSE;
+			priv->playlist_format_pls = TRUE;
+		} else {
+			rb_debug ("unrecognized playlist format: %s", stripped);
+		}
+
+		g_free (format);
+	}
+
+	if (priv->playlist_format_unknown) {
+		rb_debug ("didn't find a playlist format");
+	}
+}
+
 static void
 rb_generic_player_source_get_device_info (RBGenericPlayerSource *source)
 {
-#if HAVE_HAL
-	GnomeVFSVolume *volume;
-	LibHalContext *ctx = get_hal_context ();
 	RBGenericPlayerSourcePrivate *priv = GENERIC_PLAYER_SOURCE_GET_PRIVATE (source);
+	GnomeVFSVolume *volume;
+	char *is_audio_player;
+#ifdef HAVE_HAL
+	LibHalContext *ctx;
+#endif
+	g_object_get (source, "volume", &volume, NULL);
 
+#ifdef HAVE_HAL
+	ctx = get_hal_context ();
 	if (ctx != NULL) {
 		gchar *udi;
 
-		g_object_get (G_OBJECT (source), "volume", &volume, NULL);
 		udi = get_hal_udi_for_player (ctx, volume);
-		g_object_unref (G_OBJECT (volume));
 
 		if (udi != NULL) {
 			DBusError error;
@@ -237,24 +345,7 @@ rb_generic_player_source_get_device_info (RBGenericPlayerSource *source)
 			proplist = libhal_device_get_property_strlist (ctx, udi, "portable_audio_player.playlist_format", &error);
 			if (proplist) {
 				if (!dbus_error_is_set (&error)) {
-					int fmt;
-					for (fmt = 0; proplist[fmt] != NULL; fmt++) {
-						if (strcmp (proplist[fmt], "audio/x-mpegurl") == 0) {
-							rb_debug ("device supports M3U playlists");
-							priv->playlist_format_unknown = FALSE;
-							priv->playlist_format_m3u = TRUE;
-						} else if (strcmp (proplist[fmt], "audio/x-scpls") == 0) {
-							rb_debug ("device supports PLS playlists");
-							priv->playlist_format_unknown = FALSE;
-							priv->playlist_format_pls = TRUE;
-						} else {
-							rb_debug ("unrecognized playlist format: %s", proplist[fmt]);
-						}
-					}
-				}
-
-				if (priv->playlist_format_unknown) {
-					rb_debug ("didn't find a playlist format");
+					set_playlist_formats (source, proplist);
 				}
 
 				libhal_free_string_array (proplist);
@@ -286,9 +377,95 @@ rb_generic_player_source_get_device_info (RBGenericPlayerSource *source)
 		g_free (udi);
 	}
 	cleanup_hal_context (ctx);
-#else
-	rb_debug ("no player info available (no HAL)");
 #endif
+
+	/* allow HAL info to be overridden with .is_audio_player file */
+	is_audio_player = get_is_audio_player_path (volume);
+	if (is_audio_player) {
+		/* it would be nice if this had been a .desktop-style file.. */
+		char *data = NULL;
+		gsize data_size = 0;
+		GnomeVFSResult result;
+
+		rb_debug ("reading .is_audio_player file %s", is_audio_player);
+		result = gnome_vfs_read_entire_file (is_audio_player, &data_size, &data);
+		if (result != GNOME_VFS_OK) {
+			/* can we sensibly report this anywhere? */
+			rb_debug ("error reading .is_audio_player file: %s", gnome_vfs_result_to_string (result));
+		} else {
+			gchar **lines;
+			int l;
+
+			lines = g_strsplit (data, "\n", -1);
+			for (l = 0; lines[l] != NULL; l++) {
+				gchar **bits;
+
+				if (lines[l][0] == '#') {
+					continue;
+				}
+
+				bits = g_strsplit (lines[l], "=", 2);
+				if (bits[0] != NULL && bits[1] != NULL) {
+					char *key = g_strstrip (bits[0]);
+					char *value = g_strstrip (bits[1]);
+					int i;
+
+					if (strcmp (key, "audio_folders") == 0) {
+
+						rb_debug ("got audio folder list from .is_audio_player: %s", value);
+						g_strfreev (priv->audio_folders);
+						priv->audio_folders = g_strsplit (value, ",", -1);
+						for (i = 0; priv->audio_folders[i] != NULL; i++) {
+							priv->audio_folders[i] = g_strstrip (priv->audio_folders[i]);
+						}
+
+					} else if (strcmp (key, "output_formats") == 0) {
+
+						rb_debug ("got output format list from .is_audio_player: %s", value);
+						g_strfreev (priv->output_mime_types);
+						for (i = 0; priv->output_mime_types[i] != NULL; i++) {
+							priv->output_mime_types[i] = g_strstrip (priv->output_mime_types[i]);
+						}
+
+					} else if (strcmp (key, "folder_depth") == 0) {
+						unsigned long depth;
+						char *endptr;
+
+						rb_debug ("got folder depth from .is_audio_player: %s", value);
+						depth = strtoul (value, &endptr, 0);
+						if (endptr != value) {
+							priv->folder_depth = depth;
+						} else {
+							priv->folder_depth = -1;
+						}
+
+					} else if (strcmp (key, "playlist_format") == 0) {
+
+						char **formats;
+						formats = g_strsplit (value, ",", -1);
+						set_playlist_formats (source, formats);
+						g_strfreev (formats);
+
+					} else if (strcmp (key, "playlist_path") == 0) {
+
+						g_free (priv->playlist_path);
+						priv->playlist_path = g_strdup (value);
+						rb_debug ("got playlist path from .is_audio_player: %s", value);
+					} else {
+						rb_debug ("unsupported .is_audio_player setting: %s", lines[l]);
+					}
+				}
+				g_strfreev (bits);
+			}
+			g_strfreev (lines);
+		}
+
+		g_free (is_audio_player);
+	} else {
+		rb_debug ("no .is_audio_player file found on this device");
+	}
+
+	g_object_unref (volume);
 }
 
 static void
@@ -455,13 +653,10 @@ rb_generic_player_is_volume_player (GnomeVFSVolume *volume)
 
 	/* treat as audio player if ".is_audio_player" exists in the root of the volume  */
 	if (!result) {
-		char *path = gnome_vfs_volume_get_activation_uri (volume);
-		char *file = g_build_filename (path, ".is_audio_player", NULL);
-
-		if (rb_uri_is_local (file) && rb_uri_exists (file))
-			result = TRUE;
+		char *path;
+		path = get_is_audio_player_path (volume);
+		result = (path != NULL);
 
-		g_free (file);
 		g_free (path);
 	}
 
@@ -563,6 +758,7 @@ load_playlist_file (RBGenericPlayerSource *source,
 	TotemPlParser *parser;
 	HandlePlaylistEntryData *data;
 	RBShell *shell;
+	RBGenericPlayerSourcePrivate *priv = GENERIC_PLAYER_SOURCE_GET_PRIVATE (source);
 
 	g_object_get (G_OBJECT (source),
 		      "shell", &shell,
@@ -582,6 +778,14 @@ load_playlist_file (RBGenericPlayerSource *source,
 
 	parser = totem_pl_parser_new ();
 
+	/* ignore playlist formats we know the device doesn't support */
+	if (priv->playlist_format_unknown == FALSE) {
+		if (priv->playlist_format_m3u == FALSE)
+			totem_pl_parser_add_ignored_mimetype (parser, "audio/x-mpegurl");
+		if (priv->playlist_format_pls == FALSE)
+			totem_pl_parser_add_ignored_mimetype (parser, "audio/x-scpls");
+	}
+
 #if TOTEM_PL_PARSER_CHECK_VERSION(2,19,0)
 	g_signal_connect (parser,
 			  "entry-parsed", G_CALLBACK (handle_playlist_entry_cb),
@@ -624,11 +828,7 @@ visit_playlist_dirs (const gchar *rel_path,
 	playlist_path = rb_uri_append_path (main_path, rel_path);
 	g_free (main_path);
 
-	/* don't add playlists in formats we know the player can't handle  */
-	if ((g_str_has_suffix (playlist_path, ".m3u") && (priv->playlist_format_unknown || priv->playlist_format_m3u)) ||
-	   (g_str_has_suffix (playlist_path, ".pls") && (priv->playlist_format_unknown || priv->playlist_format_pls))) {
-		load_playlist_file (source, playlist_path, rel_path);
-	}
+	load_playlist_file (source, playlist_path, rel_path);
 	g_free (playlist_path);
 
 	return TRUE;
