class Muzak::Player::MPV

Exposes MPV's IPC to muzak for playback control.

Constants

DEFAULT_MPV_ARGS

Public Class Methods

available?() click to toggle source

@return [Boolean] whether or not MPV is available for execution

# File lib/muzak/player/mpv.rb, line 22
def self.available?
  ::MPV::Server.available?
end

Public Instance Methods

activate!() click to toggle source

Activate mpv by executing it and preparing for event processing. @return [void]

# File lib/muzak/player/mpv.rb, line 33
def activate!
  return if running?

  debug "activating #{self.class}"

  args = DEFAULT_MPV_ARGS + configured_mpv_args

  @mpv = ::MPV::Session.new(user_args: args)
  @mpv.callbacks << method(:dispatch_event!)

  instance.event :player_activated
end
clear_queue() click to toggle source

Clears mpv's internal queue. @return [void]

# File lib/muzak/player/mpv.rb, line 160
def clear_queue
  return unless running?
  @mpv.command "stop"
end
configured_mpv_args() click to toggle source
# File lib/muzak/player/mpv.rb, line 171
def configured_mpv_args
  args = []

  args.concat ["--no-force-window", "--no-video"] if Config.mpv_no_art

  args << "--geometry=#{Config.art_geometry}" if Config.art_geometry

  # this is an experimental flag, but it could improve
  # muzak's load times substantially when used with a network
  # mounted music library
  args << "--prefetch-playlist" if ::MPV::Server.flag?("--prefetch-playlist")

  args
end
deactivate!() click to toggle source

Deactivate mpv by killing it and cleaning up. @return [void]

# File lib/muzak/player/mpv.rb, line 48
def deactivate!
  return unless running?

  debug "deactivating #{self.class}"

  @mpv.quit!
ensure
  @_now_playing = nil
  instance.event :player_deactivated
end
dispatch_event!(event) click to toggle source

Dispatch the given event to the active {Muzak::Instance}. @param event [String] the event @return [void] @api private

# File lib/muzak/player/mpv.rb, line 202
def dispatch_event!(event)
  case event
  when "file-loaded"
    instance.event :song_loaded, now_playing
  when "end-file"
    instance.event :song_unloaded
    @_now_playing = nil
  end
end
enqueue_album(album) click to toggle source

Tell mpv to add the given album to its queue. @param album [Album] the album to add @return [void] @note Activates mpv if not already activated.

# File lib/muzak/player/mpv.rb, line 112
def enqueue_album(album)
  activate! unless running?

  album.songs.each do |song|
    load_song song, album.cover_art
  end
end
enqueue_playlist(playlist) click to toggle source

Tell mpv to add the given playlist to its queue. @param playlist [Playlist] the playlist to add @return [void] @note Activates mpv if not already activated.

# File lib/muzak/player/mpv.rb, line 124
def enqueue_playlist(playlist)
  activate! unless running?

  playlist.songs.each do |song|
    load_song song, song.best_guess_album_art
  end
end
enqueue_song(song) click to toggle source

Tell mpv to add the given song to its queue. @param song [Song] the song to add @return [void] @note Activates mpv if not already activated.

# File lib/muzak/player/mpv.rb, line 102
def enqueue_song(song)
  activate! unless running?

  load_song song, song.best_guess_album_art
end
list_queue() click to toggle source

Get mpv's internal queue. @return [Array<Song>] all songs in mpv's queue @note This includes songs already played.

# File lib/muzak/player/mpv.rb, line 135
def list_queue
  entries = @mpv.get_property "playlist/count"

  playlist = []

  entries.times do |i|
    # TODO: this is slow and should be avoided at all costs,
    # since we have access to these Song instances earlier
    # in the object's lifecycle.
    playlist << Song.new(@mpv.get_property("playlist/#{i}/filename"))
  end

  playlist
end
load_song(song, art) click to toggle source

Load a song and optional album art into mpv. @param song [Song] the song to load @param art [String] the art file to load @return [void] @api private

# File lib/muzak/player/mpv.rb, line 191
def load_song(song, art)
  append_type = Config.autoplay ? "append-play" : "append"
  cmds = ["loadfile", song.path, append_type]
  cmds << "external-file=\"#{art}\"" if art
  @mpv.command(*cmds)
end
next_song() click to toggle source

Tell mpv to play the next song in its queue. @return [void] @note Does nothing if the current song is the last.

# File lib/muzak/player/mpv.rb, line 87
def next_song
  @mpv.command "playlist-next"
end
now_playing() click to toggle source

Get mpv's currently loaded song. @return [Song, nil] the currently loaded song

# File lib/muzak/player/mpv.rb, line 167
def now_playing
  @_now_playing ||= Song.new @mpv.get_property("path")
end
pause() click to toggle source

Tell mpv to pause playback. @return [void] @note Does nothing is playback is already paused.

# File lib/muzak/player/mpv.rb, line 71
def pause
  return unless running?

  @mpv.set_property "pause", true
end
play() click to toggle source

Tell mpv to begin playback. @return [void] @note Does nothing is playback is already in progress.

# File lib/muzak/player/mpv.rb, line 62
def play
  return unless running?

  @mpv.set_property "pause", false
end
playing?() click to toggle source

@return [Boolean] Whether or not mpv is currently playing.

# File lib/muzak/player/mpv.rb, line 78
def playing?
  return false unless running?

  !@mpv.get_property "pause"
end
previous_song() click to toggle source

Tell mpv to play the previous song in its queue. @return [void] @note Does nothing if the current song is the first.

# File lib/muzak/player/mpv.rb, line 94
def previous_song
  @mpv.command "playlist-prev"
end
running?() click to toggle source

@return [Boolean] whether or not the current instance is running.

# File lib/muzak/player/mpv.rb, line 27
def running?
  !!@mpv&.running?
end
shuffle_queue() click to toggle source

Shuffle mpv's internal queue. @return [void]

# File lib/muzak/player/mpv.rb, line 152
def shuffle_queue
  return unless running?

  @mpv.command "playlist-shuffle"
end