diff --git a/server/djrandom/frontend/static/js/djr.min.js b/server/djrandom/frontend/static/js/djr.min.js
index 89884027fff3303fac9539fc2102336bc02b9687..3353fb35fa092fc9cf97d67b8632ebced2c871d8 100644
--- a/server/djrandom/frontend/static/js/djr.min.js
+++ b/server/djrandom/frontend/static/js/djr.min.js
@@ -8,17 +8,18 @@ djr.PlaylistChunk.prototype.wrapHtml=function(a,b){return'<div id="chunk_'+a+'"
 djr.Playlist.prototype.allSongs=function(){var a=[],b,c;for(b=0;b<this.chunks.length;b++)for(c=0;c<this.chunk_map[this.chunks[b]].songs.length;c++)a.push(this.chunk_map[this.chunks[b]].songs[c]);return a};djr.Playlist.prototype.createUniqueChunk=function(a,b){var c=[],d;for(d=0;d<a.length;d++)this.song_map[a[d]]==null&&c.push(a[d]);return c.length>0?new djr.PlaylistChunk(c,b):null};
 djr.Playlist.prototype.addChunk=function(a){djr.debug("adding chunk to playlist "+this.uuid);var b,c=this.next_chunk_id++;for(b=0;b<a.songs.length;b++)this.song_map[a.songs[b]]=c;this.chunk_map[c]=a;this.chunks.push(c);return c};djr.Playlist.prototype.getChunkSongs=function(a){return this.chunk_map[a].songs};
 djr.Playlist.prototype.removeChunk=function(a){djr.debug("removing chunk "+a);var b=this.chunk_map[a].songs,c;for(c=0;c<b.length;c++)delete this.song_map[b[c]];delete this.chunk_map[a];this.chunks=$.grep(this.chunks,function(b){return b!=a})};djr.Playlist.prototype.removeSong=function(a){djr.debug("removing song "+a);var b=this.song_map[a];this.chunk_map[b].removeSong(a);delete this.song_map[a];return this.chunk_map[b].songs.length==0?(this.removeChunk(b),b):-1};
-djr.Playlist.prototype.merge=function(){var a=[],b;for(b=0;b<this.chunks.length;b++)a.push(this.chunk_map[this.chunks[b]].title);a=a.join(" + ");b=new djr.Playlist;b.uuid=this.uuid;b.addChunk(new djr.PlaylistChunk(this.allSongs(),a));return b};djr.Playlist.prototype.getNextSong=function(a){var b=this.song_map[a],c=this.chunk_map[b].songs,b=this.chunks.indexOf(b),a=c.indexOf(a)+1;a>=c.length&&(a=0,b++,b>=this.chunks.length&&(b=0));return this.chunk_map[this.chunks[b]].songs[a]};djr.Player=function(a,b){this.backend=a;this.playlist=new djr.Playlist;this.old_songs=[];this.cur_song=null;this.circleplayer=new CirclePlayer(b,{},{supplied:"mp3",swfPath:"/static/js",cssSelectorAncestor:"#cp_container",error:function(a){djr.state.player.reportError(a)}});this.player=this.circleplayer.player;this.player.bind($.jPlayer.event.ended+".djr",function(){djr.state.player.nextSong()})};djr.Player.prototype.hideAllChunks=function(){$(".chunk .chunk_inner").hide()};
+djr.Playlist.prototype.merge=function(){var a=[],b;for(b=0;b<this.chunks.length;b++)a.push(this.chunk_map[this.chunks[b]].title);a=a.join(" + ");b=new djr.Playlist;b.uuid=this.uuid;b.addChunk(new djr.PlaylistChunk(this.allSongs(),a));return b};djr.Playlist.prototype.getNextSong=function(a){var b=this.song_map[a],c=this.chunk_map[b].songs,b=this.chunks.indexOf(b),a=c.indexOf(a)+1;a>=c.length&&(a=0,b++,b>=this.chunks.length&&(b=0));return this.chunk_map[this.chunks[b]].songs[a]};
+djr.Playlist.prototype.isLastSong=function(a){var b=this.song_map[a],c=this.chunk_map[b].songs,b=this.chunks.indexOf(b),a=c.indexOf(a),c=c.length-1;return b==this.chunks.length-1&&a==c?!0:!1};djr.Player=function(a,b){this.backend=a;this.playlist=new djr.Playlist;this.old_songs=[];this.cur_song=null;this.auto_extend=!0;this.circleplayer=new CirclePlayer(b,{},{supplied:"mp3",swfPath:"/static/js",cssSelectorAncestor:"#cp_container",error:function(a){djr.state.player.reportError(a)}});this.player=this.circleplayer.player;this.player.bind($.jPlayer.event.ended+".djr",function(){djr.state.player.nextSong()})};djr.Player.prototype.hideAllChunks=function(){$(".chunk .chunk_inner").hide()};
 djr.Player.prototype.removeChunk=function(a){this.playlist.removeChunk(a);this.savePlaylist();$("#chunk_"+a).remove()};djr.Player.prototype.removeSong=function(a){$("#song_"+a).remove();a=this.playlist.removeSong(a);this.savePlaylist();a>0&&$("#chunk_"+a).remove()};djr.Player.prototype.savePlaylist=function(){this.backend.savePlaylist(this.playlist.uuid,"",this.playlist.allSongs())};djr.Player.prototype.saveNewPlaylist=function(a){this.backend.savePlaylist(djr.generateRandomId(),a,this.playlist.allSongs())};
 djr.Player.prototype.clearPlaylist=function(){this.playlist=new djr.Playlist;$("#playlistDiv").empty()};djr.Player.prototype.mergePlaylistChunks=function(){this.playlist=this.playlist.merge();var a=[];$(".chunk .chunk_inner").each(function(){a.push($(this).html())});$("#playlistDiv").empty();var b=this.playlist.chunks[0];this.setChunkHtml(this.playlist.chunk_map[b],b,a.join(""))};
 djr.Player.prototype.search=function(a){var b=this;this.backend.search(a,function(c){var d=[];$.each(c,function(a,b){d.push(b.sha1)});d.length==0?djr.debug("No results found."):b.createChunk(d,a)})};djr.Player.prototype.lastPlaylist=function(a){var b=this,c="Last "+a+" Songs Uploaded";this.backend.lastPlaylist(a,function(a){a.length==0?djr.debug("No results found."):b.createChunk(a,c)})};
 djr.Player.prototype.randomPlaylist=function(a){var b=this,c=""+a+" Random Songs ";this.backend.randomPlaylist(a,function(a){a.length==0?djr.debug("No results found."):b.createChunk(a,c)})};djr.Player.prototype.neverPlayedPlaylist=function(a){var b=this,c=""+a+" Never Played Songs";this.backend.neverPlayedPlaylist(a,function(a){a.length==0?djr.debug("No results found."):b.createChunk(a,c)})};
 djr.Player.prototype.mostPlayedPlaylist=function(a){var b=this,c=""+a+" Most Played Songs";this.backend.mostPlayedPlaylist(a,function(a){var e=[];$.each(a,function(a,b){e.push(b.sha1)});e.length==0?djr.debug("No results found."):b.createChunk(e,c)})};djr.Player.prototype.extendCurrentPlaylist=function(){var a=this;this.backend.moreLikeThese(this.playlist.allSongs(),function(b){a.createChunk(b,"suggestions")})};
-djr.Player.prototype.createChunk=function(a,b){var c=this.playlist.createUniqueChunk(a,b);if(c){this.playlist.chunks.length>1&&this.mergePlaylistChunks();var d=this.playlist.addChunk(c);this.savePlaylist();var e=this;this.backend.getHtmlForSongs(a,function(a){e.hideAllChunks();e.setChunkHtml(c,d,a)})}else djr.debug("All the results are already in the playlist")};
+djr.Player.prototype.autoExtendCurrentPlaylist=function(a){var b=this;this.backend.markovPlaylist(10,this.playlist.allSongs(),function(c){b.createChunk(c,"more...");a()})};djr.Player.prototype.createChunk=function(a,b){var c=this.playlist.createUniqueChunk(a,b);if(c){this.playlist.chunks.length>1&&this.mergePlaylistChunks();var d=this.playlist.addChunk(c);this.savePlaylist();var e=this;this.backend.getHtmlForSongs(a,function(a){e.hideAllChunks();e.setChunkHtml(c,d,a)})}else djr.debug("All the results are already in the playlist")};
 djr.Player.prototype.setChunkHtml=function(a,b,c){a=a.wrapHtml(b,c);$("#playlistDiv").append(a);var d=this,e=$("#chunk_"+b);e.find(".song_a").click(function(){d.play($(this).attr("id").substr(5))});e.find(".album_a").click(function(){d.search('(album:"'+$(this).text()+'")')});e.find(".chunk_title").click(function(){e.find(".chunk_inner").toggle()});e.hover(function(){$(this).find(".chunk_ctl_wrap .ctlbox").show()},function(){$(this).find(".chunk_ctl_wrap .ctlbox").hide()});e.find(".chunk_ctl_wrap .ctlbox .ctl_remove").click(function(){djr.debug("removing chunk "+
 b);d.removeChunk(b)});e.find(".chunk_inner .song").hover(function(){$(this).find(".ctlbox").show()},function(){$(this).find(".ctlbox").hide()});e.find(".chunk_inner .ctlbox .ctl_remove").click(function(){var a=$(this).parent().parent().attr("id").substr(5);d.removeSong(a)})};
 djr.Player.prototype.play=function(a){djr.debug("play "+a);this.cur_song&&(this.old_songs.push(this.cur_song),this.old_songs.length>5&&this.old_songs.shift());this.cur_song=a;$(".song").removeClass("playing");$("#song_"+a).addClass("playing");this.player.jPlayer("setMedia",{mp3:"/dl/"+a}).jPlayer("play");var b=$("#song_"+a+" .artist").text(),c=$("#song_"+a+" .album").text();$("#songInfoDiv").html($("#song_"+a+" .title").text()+"<br>"+b+"<br><small>"+c+"</small>");b="/album_image/"+escape(b)+"/"+escape(c);
-$("#albumart_fs").attr("src",b);$("#albumart_fs").fullBg();$("#albumart_fs").show();this.backend.nowPlaying(a,this.old_songs)};djr.Player.prototype.nextSong=function(){this.play(this.playlist.getNextSong(this.cur_song))};djr.Player.prototype.streamCurrentPlaylist=function(){};djr.state={backend:null,player:null};
+$("#albumart_fs").attr("src",b);$("#albumart_fs").fullBg();$("#albumart_fs").show();this.backend.nowPlaying(a,this.old_songs)};djr.Player.prototype.nextSong=function(){if(this.auto_extend&&this.playlist.isLastSong(this.cur_song)){var a=this;this.autoExtendCurrentPlaylist(function(){a.nextSong()})}else this.play(this.playlist.getNextSong(this.cur_song))};djr.Player.prototype.streamCurrentPlaylist=function(){};djr.state={backend:null,player:null};
 djr.init=function(){djr.state.backend=new djr.Backend;djr.state.player=new djr.Player(djr.state.backend,"#djr_player");$("#playlistClearBtn").click(function(){djr.state.player.clearPlaylist()});$("#playlistStreamBtn").click(function(){djr.state.player.streamCurrentPlaylist()});$("#playlistExtendBtn").click(function(){djr.state.player.extendCurrentPlaylist()});$("#playlistLast5").click(function(){djr.state.player.lastPlaylist(5)});$("#playlistLast25").click(function(){djr.state.player.lastPlaylist(25)});
 $("#playlistRandom5").click(function(){djr.state.player.randomPlaylist(5)});$("#playlistRandom25").click(function(){djr.state.player.randomPlaylist(25)});$("#playlistMost5").click(function(){djr.state.player.mostPlayedPlaylist(5)});$("#playlistMost25").click(function(){djr.state.player.mostPlayedPlaylist(25)});$("#playlistNever5").click(function(){djr.state.player.neverPlayedPlaylist(5)});$("#playlistNever25").click(function(){djr.state.player.neverPlayedPlaylist(25)});$("#playlistSave").click(function(){$("#saveForm").is(":visible")==
 !1?($("#savetext").val(djr.playlist.title),$("#saveForm").show("slow")):($("#savetext").val(""),$("#saveForm").hide("slow"))});$("#playlistSaveBtn").click(function(){$("#savetext").val()!=""&&djr.player.saveNewPlaylist($("#savetext").val())});$("#wikibtn").click(function(){var a=$("#song_"+djr.state.player.cur_song+" .artist").text();$("#wikipedia").is(":visible")==!1?a!=""&&(a=a.split(" ").join("+"),$("#wikipedia").show("slow"),$("#wikipedia").attr("src","http://en.m.wikipedia.org/w/index.php?search="+
diff --git a/server/djrandom/frontend/static/js/djr/player.js b/server/djrandom/frontend/static/js/djr/player.js
index 398083f080d6ff25c252cd9dfa04eb357978233c..be7e5b34c9cf1a3d40559863c44c60c8ce551f5a 100644
--- a/server/djrandom/frontend/static/js/djr/player.js
+++ b/server/djrandom/frontend/static/js/djr/player.js
@@ -8,6 +8,7 @@ djr.Player = function(backend, selector) {
   this.playlist = new djr.Playlist();
   this.old_songs = [];
   this.cur_song = null;
+  this.auto_extend = true;
 
   // Setup the jPlayer interface.
   this.circleplayer = new CirclePlayer(selector, {}, {
@@ -179,6 +180,18 @@ djr.Player.prototype.extendCurrentPlaylist = function() {
   });
 };
 
+// Automatically extend the current playlist using Markov-based
+// suggestions. Invokes callback when done.
+djr.Player.prototype.autoExtendCurrentPlaylist = function(callback) {
+  var player = this;
+  var cur_songs = this.playlist.allSongs();
+
+  this.backend.markovPlaylist(10, cur_songs, function(results) {
+    player.createChunk(results, 'more...');
+    callback();
+  });
+};
+
 djr.Player.prototype.createChunk = function(songs, chunk_title) {
   // Create the new chunk, with unique songs.
   var chunk = this.playlist.createUniqueChunk(songs, chunk_title);
@@ -293,7 +306,15 @@ djr.Player.prototype.play = function(song) {
 
 // Start playing the next song.
 djr.Player.prototype.nextSong = function() {
-  this.play(this.playlist.getNextSong(this.cur_song));
+  if (this.auto_extend && this.playlist.isLastSong(this.cur_song)) {
+    var player = this;
+    // auto-extend!
+    this.autoExtendCurrentPlaylist(function() {
+      player.nextSong();
+    });
+  } else {
+    this.play(this.playlist.getNextSong(this.cur_song));
+  }
 };
 
 // Activate streaming of the current playlist.
diff --git a/server/djrandom/frontend/static/js/djr/playlist.js b/server/djrandom/frontend/static/js/djr/playlist.js
index f00eea595ff2703489a0687ceaa5b506b9d93098..317cd6277a30e20b8499fc3431b3a5a877212c2c 100644
--- a/server/djrandom/frontend/static/js/djr/playlist.js
+++ b/server/djrandom/frontend/static/js/djr/playlist.js
@@ -235,3 +235,18 @@ djr.Playlist.prototype.getNextSong = function(song) {
 
   return this.chunk_map[this.chunks[chunk_idx]].songs[idx];
 };
+
+djr.Playlist.prototype.isLastSong = function(song) {
+  var cur_chunk = this.song_map[song];
+  var chunk_songs = this.chunk_map[cur_chunk].songs;
+  var chunk_idx = this.chunks.indexOf(cur_chunk);
+  var song_idx = chunk_songs.indexOf(song);
+  var last_chunk = this.chunks.length - 1;
+  var last_song = chunk_songs.length - 1;
+  if (chunk_idx == last_chunk && song_idx == last_song) {
+    return true;
+  } else {
+    return false;
+  }
+};
+