class PartyGoerPlayer::Player

Public Class Methods

new(server) click to toggle source
# File lib/partygoer-player.rb, line 25
def initialize(server)
  @client = PartyGoerClient.new(server)
  @plaything = Plaything.new
  @playing = false

  $session_callbacks = {
    log_message: proc do |_session, message|
      @@logger.info { "Message from spotify: #{message}" }
    end,

    logged_in: proc do |_session, error|
      @@logger.info { "Logged in: #{error}" }
    end,

    logged_out: proc do |_session|
      @@logger.info { 'Logged out!' }
    end,

    streaming_error: proc do |_session, error|
      @@logger.error { "Streaming error #{error.message}" }
    end,

    connection_error: proc do |_session, error|
      @@logger.error { "Connection error: #{error}" }
    end,

    play_token_lost: proc do |_session|
      @@logger.error { 'Play token lost. Stopping playback.' }
      @plaything.stop
      @playing = false
    end,

    streaming_error: proc do |_session, error|
      @@logger.error { "Streaming error #{error}. Stopping playback" }
      @plaything.stop
      @playing = false
    end,

    start_playback: proc do |_session|
      @@logger.debug { 'Starting playback' }
      @plaything.play
    end,

    stop_playback: proc do |_session|
      @@logger.debug { 'Stopping playback' }
      Spotify.try(:session_player_play, session, false)
      @plaything.stop
    end,

    get_audio_buffer_stats: proc do |_session, stats|
      stats[:samples] = @plaything.queue_size
      stats[:stutter] = @plaything.drops
    end,

    music_delivery: proc do |_session, format, frames, num_frames|
      if num_frames == 0
        @@logger.error { 'Music delivery audio discontuity' }
        @plaything.stop
        0
      else
        @@logger.debug {
                        "#{num_frames} frames delivered. #{format.to_h.inspect}"
                       }
        frames = FrameReader.new(
                      format[:channels], format[:sample_type], num_frames, frames)
        consumed_frames = @plaything.stream(frames, format.to_h)
        consumed_frames
      end
    end,

    end_of_track: proc do |session|
      Spotify.try(:session_player_play, session, false)
      @@logger.info { 'End of track' }
      @plaything.stop
      if @client.up_next
        play_track(session, @client.up_next['spotify_uri'])
        @client.playing = @client.up_next
        @playing = true
      else
        @playing = false
      end
    end
  }

  config = YAML.load_file('config.yml')
  Support::DEFAULT_CONFIG[:callbacks] = Spotify::SessionCallbacks.new(
                                                             $session_callbacks)
  @session = Support.initialize_spotify!(config['username'], config['password'])
end

Public Instance Methods

pause() click to toggle source
# File lib/partygoer-player.rb, line 133
def pause
  Spotify.try(:session_player_play, @session, false)
end
play() click to toggle source
# File lib/partygoer-player.rb, line 141
def play
  resume
end
play_track(session, uri) click to toggle source
# File lib/partygoer-player.rb, line 118
def play_track(session, uri)
  track = Spotify.link_as_track(Spotify.link_create_from_string(uri))
  Spotify.session_process_events(session) until Spotify.track_is_loaded(track)

  # Pause before we load a new track. Fixes a quirk in libspotify.
  Spotify.try(:session_player_play, session, false)
  Spotify.try(:session_player_load, session, track)
  Spotify.try(:session_player_play, session, true)
  @playing = true
  @@logger.info {"Playing next track: #{uri}"}
rescue
  @@logger.error {"Failed to play track: #{uri}"}
  @playing = false
end
resume() click to toggle source
# File lib/partygoer-player.rb, line 137
def resume
  Spotify.try(:session_player_play, @session, true)
end
start() click to toggle source
# File lib/partygoer-player.rb, line 146
def start
  play_track(@session, @client.playing['spotify_uri']) if @client.playing
  t = Thread.new {
    loop do
      Spotify.session_process_events(@session)
      if @client.skip?
        @@logger.info { 'Skipping track' }
        if @client.up_next
          play_track(@session, @client.up_next['spotify_uri'])
          @client.playing = @client.up_next
        else
          @playing = false
        end
      end
      unless @playing
        @@logger.info { 'Nothing playing, attempting to play next track' }
        if @client.up_next
          play_track(@session, @client.up_next['spotify_uri'])
          @client.playing = @client.up_next
        else
          @playing = false
        end
      end
      sleep(0.05)
    end
  }
end