Skip to content
Snippets Groups Projects
Select Git revision
  • b56f4ceca7038f615e27060808cdff1831fac821
  • master default
  • nonce
  • encrypt-ticket
  • apache24
  • libsodium
  • mod-sso-cache
7 results

ai-sso-server.service

Blame
  • player.js 10.51 KiB
    // player.js
    
    
    // Player
    
    djr.Player = function(backend, selector) {
      this.backend = backend;
      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, {}, {
        supplied: 'mp3',
        solution: 'html, flash',
        swfPath: '/static/js',
        cssSelectorAncestor: '#cp_container',
        error: djr.playerError
      });
      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();
    };
    
    // Callback for removechunk click.
    djr.Player.prototype.removeChunk = function(chunk_id) {
      this.playlist.removeChunk(chunk_id);
      $('#chunk_' + chunk_id).remove();
      this.savePlaylist();
      // If the playlist is now empty, switch to a new uuid.
      if (this.playlist.isEmpty()) {
        this.clearPlaylist();
      }
    };
    
    // Remove a single song.
    djr.Player.prototype.removeSong = function(song) {
      $('#song_' + song).remove();
      var chunk_to_remove = this.playlist.removeSong(song);
      this.savePlaylist();
      if (chunk_to_remove > 0) {
        $('#chunk_' + chunk_to_remove).remove();
      }
    };
    
    // Save the current playlist.
    djr.Player.prototype.savePlaylist = function() {
      this.backend.savePlaylist(this.playlist.uuid, '', this.playlist.allSongs());
    };
    
    // Save the current playlist.
    djr.Player.prototype.savePlaylistWithTitle = function(title) {
      this.backend.savePlaylist(djr.generateRandomId(), title, this.playlist.allSongs());
      // Merge all existing chunks into one, named as the playlist.
      this.mergePlaylistChunks('playlist: ' + title);
    };
    
    // Completely clear out the current playlist, and replace it with 
    // a new empty one.
    djr.Player.prototype.clearPlaylist = function() {
      this.playlist = new djr.Playlist();
      $('#playlistDiv').empty();
      djr.debug('new playlist: ' + this.playlist.uuid);
    };
    
    // Merge all chunks into a single one.
    djr.Player.prototype.mergePlaylistChunks = function(title) {
      // Reduce the playlist to a single chunk.
      this.playlist = this.playlist.merge(title);
    
      // Shuffle the HTML data around (so we don't have to necessarily
      // fetch it again from the server). This is done in a few steps:
      // 1) Copy all .chunk_inner data in a temp
      var plhtml = [];
      $('.chunk .chunk_inner').each(function(idx) {
        plhtml.push($(this).html());
      });
    
      // 2) Remove all the .chunk divs.
      $('#playlistDiv').empty();
      // also: $('.chunk').remove();
    
      // 3) Create a new chunk div.
      var chunk_id = this.playlist.chunks[0];
      var chunk = this.playlist.chunk_map[chunk_id];
      this.setChunkHtml(chunk, chunk_id, plhtml.join(''));
    };
    
    // Search!
    djr.Player.prototype.search = function(query) {
      var player = this;
    
      this.backend.search(query, function(results) {
        var songs = [];
        $.each(results, function(idx, item) {
          songs.push(item.sha1);
        });
        if (songs.length == 0) {
          djr.showSearchWarning('No results found.');
          djr.debug('No results found.');
          return;
        }
    
        // Create a chunk of unique new songs.
        player.createChunk(songs, query);
      });
    };
    
    // Request N last uploaded songs 
    
    djr.Player.prototype.lastPlaylist = function(num) {
      var player = this;
      var title = "Last " + num + " Songs Uploaded";
      this.backend.lastPlaylist(num, function(results) {
        var songs = results;
        if (songs.length == 0) {
          djr.debug('No results found.');
          return;
        }
        // Create a chunk of unique new songs.
        player.createChunk(songs, title);
      });
    };
    
    djr.Player.prototype.randomPlaylist = function(num) {
      var player = this;
      var title = "" + num + " Random Songs ";
      this.backend.randomPlaylist(num, function(results) {
        var songs = results;
        if (songs.length == 0) {
          djr.debug('No results found.');
          return;
        }
        // Create a chunk of unique new songs.
        player.createChunk(songs, title);
      });
    
    };
    
    djr.Player.prototype.neverPlayedPlaylist = function(num) {
      var player = this;
      var title = "" + num + " Never Played Songs";
      this.backend.neverPlayedPlaylist(num, function(results) {
        var songs = results;
        if (songs.length == 0) {
          djr.debug('No results found.');
          return;
        }
        // Create a chunk of unique new songs.
        player.createChunk(songs, title);
      });
    
    };
    
    djr.Player.prototype.mostPlayedPlaylist = function(num) {
      var player = this;
      var title = "" + num + " Most Played Songs";
      this.backend.mostPlayedPlaylist(num, function(results) {
        var songs = [];
        $.each(results, function(idx, item) {
          songs.push(item.sha1);
        });
        if (songs.length == 0) {
          djr.debug('No results found.');
          return;
        }
        // Create a chunk of unique new songs.
        player.createChunk(songs, title);
      });
    
    };
    
    djr.Player.prototype.loadPlaylist = function(uuid) {
      var player = this;
      djr.debug('loading playlist: ' + uuid);
      this.backend.getPlaylist(uuid, function(plist) {
        var chunk_title;
        if (!plist.title) {
          chunk_title = 'playlist: ' + plist.uuid;
        } else {
          chunk_title = 'playlist: ' + plist.title;
        }
        player.clearPlaylist();
        player.createChunk(plist.songs, chunk_title);
      });
    };
    
    // Extend the current playlist with suggestions.
    djr.Player.prototype.extendCurrentPlaylist = function() {
      var player = this;
      var cur_songs = this.playlist.allSongs();
    
      this.backend.moreLikeThese(5, cur_songs, function(results) {
        player.createChunk(results, 'suggestions');
      });
    };
    
    // 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();
      });
    };
    
    // Extend the current playlist with the results of a MoreLikeThis
    // search based on a single selected song.
    djr.Player.prototype.moreLikeThis = function(sha1) {
      var player = this;
      var songs = [sha1];
    
      this.backend.moreLikeThese(10, songs, function(results) {
        player.createChunk(results, 'like that');
      });
    };
    
    djr.Player.prototype.createChunk = function(songs, chunk_title) {
      // Clear any pending error message.
      djr.clearSearchWarning();
    
      // Create the new chunk, with unique songs.
      var chunk = this.playlist.createUniqueChunk(songs, chunk_title);
      if (!chunk) {
        djr.showSearchWarning('All results already in playlist.');
        djr.debug('All the results are already in the playlist');
        return;
      }
    
      // If there's more than one chunk in the playlist, merge (that is,
      // replace the current playlist with a new, merged one).
      if (this.playlist.chunks.length > 1) {
        this.mergePlaylistChunks();
      }
    
      // Add the new chunk.
      var chunk_id = this.playlist.addChunk(chunk);
    
      // Save the current playlist.
      this.savePlaylist();
    
      // Set the URL hash fragment to point to the current playlist.
      djr.history.save(this.playlist.uuid);
    
      // Load the HTML fragment for the chunk and display it.  Also,
      // minimize all the other chunks.
      var player = this;
      this.backend.getHtmlForSongs(songs, function(songs_html) {
        var chunk_div = 'chunk_' + chunk_id;
        player.hideAllChunks();
        player.setChunkHtml(chunk, chunk_id, songs_html);
      });
    };
    
    // Set the HTML contents of a chunk object, and the related event hooks.
    djr.Player.prototype.setChunkHtml = function(chunk, chunk_id, songs_html) {
      var inner_html = chunk.wrapHtml(chunk_id, songs_html);
      $('#playlistDiv').append(inner_html);
    
      var player = this;
      var chunk_div = $('#chunk_' + chunk_id);
    
      // Add onclick handlers to chunk title, song title, song album.
      chunk_div.find('.song_a').click(function() {
        player.play($(this).attr('id').substr(5));
      });
      chunk_div.find('.album_a').click(function() {
        player.search('(album:\"' + $(this).text() + '\")');
      });
      chunk_div.find('.chunk_title').click(function() {
        chunk_div.find('.chunk_inner').toggle();
      });
    
      // Add onclick and hover handlers to the chunk control box.
      chunk_div.hover(function() {
        $(this).find('.chunk_ctl_wrap .ctlbox').show();
      }, function() {
        $(this).find('.chunk_ctl_wrap .ctlbox').hide();
      });
      chunk_div.find('.chunk_ctl_wrap .ctlbox .ctl_remove').click(function() {
        djr.debug('removing chunk ' + chunk_id);
        player.removeChunk(chunk_id);
      });
    
      // Add onclick handlers to the song control boxes.
      chunk_div.find('.chunk_inner .song').hover(function() {
        $(this).find('.ctlbox').show();
      }, function() {
        $(this).find('.ctlbox').hide();
      });
      chunk_div.find('.chunk_inner .ctlbox .ctl_remove').click(function() {
        // What a horrible way of finding the song SHA1...
        var sha1 = $(this).parent().parent().attr('id').substr(5);
        player.removeSong(sha1);
      });
      chunk_div.find('.chunk_inner .ctlbox .ctl_love').click(function() {
        var sha1 = $(this).parent().parent().attr('id').substr(5);
        player.moreLikeThis(sha1);
      });
    };
    
    // Start playing a specific song.
    djr.Player.prototype.play = function(song) {
      djr.debug('play ' + song);
    
      if (this.cur_song) {
        this.old_songs.push(this.cur_song);
        if (this.old_songs.length > 5) {
          this.old_songs.shift();
        }
      }
      this.cur_song = song;
    
      $('.song').removeClass('playing');
      $('#song_' + song).addClass('playing');
    
      var url = '/dl/' + song;
      this.player.jPlayer('setMedia',
                          {mp3: url}).jPlayer('play');
    
      // Load song info in the player UI. We cheat by stealing the data
      // from the existing <div> instead than from the server.
      var artist = $('#song_' + song + ' .artist').text();
      var album = $('#song_' + song + ' .album').text();
      $('#songInfoDiv').html(
        $('#song_' + song + ' .title').text() + '<br>'
          + artist + '<br>'
          + '<small>' + album + '</small>'
      );
    
      // Load album art full-screen.
      var album_art_url = '/album_image/' + escape(artist) + '/' + escape(album);
      $('#albumart_fs').attr('src', album_art_url);
      $('#albumart_fs').fullBg();
      $('#albumart_fs').show();
    
      // Report the new song being played.
      this.backend.nowPlaying(song, this.old_songs);
    };
    
    // Start playing the next song.
    djr.Player.prototype.nextSong = function() {
      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.
    djr.Player.prototype.streamCurrentPlaylist = function(enable) {
      // Nothing for now.
    };
    
    
    // Fine