Module: Segue

Defined in:
lib/segue.rb,
lib/segue/mpv.rb,
lib/segue/paths.rb,
lib/segue/queue.rb,
lib/segue/ffmpeg.rb,
lib/segue/player.rb,
lib/segue/version.rb,
lib/segue/settings.rb,
lib/segue/notifiers.rb,
lib/segue/scrobbler.rb,
lib/segue/preferences.rb,
lib/segue/player_controller.rb

Defined Under Namespace

Modules: Paths Classes: Ffmpeg, Mpv, Notifiers, Player, PlayerController, Preferences, Queue, Scrobbler, Settings

Constant Summary collapse

COLOURS =
[0, 2, 5, 6, 8, 9, 11].freeze
KEYS =
{ " " => :pause, "n" => :skip, "p" => :play, "s" => :stop }.freeze
VERSION =
"0.1.0"

Class Method Summary collapse

Class Method Details

.autoplay(value) ⇒ Object



18
19
20
# File 'lib/segue.rb', line 18

def self.autoplay(value)
  Segue::Preferences.new[:autoplay] = value == "on"
end

.clearObject



22
23
24
# File 'lib/segue.rb', line 22

def self.clear
  Segue::Queue.clear
end

.crossfade(value) ⇒ Object



26
27
28
# File 'lib/segue.rb', line 26

def self.crossfade(value)
  Segue::Preferences.new[:crossfade] = value == "on"
end

.historyObject



30
31
32
33
34
35
# File 'lib/segue.rb', line 30

def self.history
  path = Segue::Paths.history
  return unless File.exist?(path)

  puts File.read(path)
end

.listObject



37
38
39
40
41
42
43
44
# File 'lib/segue.rb', line 37

def self.list
  started = Segue::Preferences.new[:started]
  offset = 0
  Segue::Queue.to_enum(:each).each_with_index do |track, index|
    puts list_line(track, index, started && Time.at(started + offset))
    offset += track[:length].to_i
  end
end

.list_line(track, index, start_time) ⇒ Object



46
47
48
49
50
51
52
53
# File 'lib/segue.rb', line 46

def self.list_line(track, index, start_time)
  parts = [Rainbow(index.to_s).magenta]
  parts << start_time.strftime("%I:%M:%S") if start_time
  parts += [Rainbow(track[:title]).green, "by", Rainbow(track[:artist]).yellow]
  parts += ["from", Rainbow(track[:album]).cyan] unless (track[:album] || "").empty?
  parts << "(#{track[:length] / 60} minutes and #{track[:length] % 60} seconds)" if track[:length]
  parts.join(" ")
end

.open_windowObject



83
84
85
86
87
88
89
90
# File 'lib/segue.rb', line 83

def self.open_window
  Curses.init_screen
  Curses.start_color
  Curses.curs_set(0)
  Curses.noecho
  COLOURS.each { |colour| Curses.init_pair(colour, colour, 0) }
  Curses::Window.new(0, 0, 1, 2).tap { |window| window.nodelay = true }
end

.pauseObject



55
56
57
# File 'lib/segue.rb', line 55

def self.pause
  Segue::Preferences.new[:pause] = true
end

.playObject



59
60
61
# File 'lib/segue.rb', line 59

def self.play
  Segue::Preferences.new[:play] = true
end

.playerObject



63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/segue.rb', line 63

def self.player
  # Start the controller before taking over the screen so that a failure to
  # launch mpv is readable rather than swallowed by curses
  player_controller = Segue::PlayerController.new
  window = open_window

  loop do
    render(window, player_controller.next)

    key = window.getch.to_s
    break if key == "q"

    send(KEYS[key]) if KEYS.key?(key)
    sleep 0.2
  end
ensure
  player_controller&.cleanup
  Curses.close_screen
end

.queue(paths) ⇒ Object



106
107
108
109
110
111
112
113
114
# File 'lib/segue.rb', line 106

def self.queue(paths)
  paths.each do |path|
    if File.file?(path)
      Segue::Queue.add(path)
    else
      Dir.glob("#{path}/**/*.*").each { |child_path| Segue::Queue.add(child_path) }
    end
  end
end

.remove(index) ⇒ Object



102
103
104
# File 'lib/segue.rb', line 102

def self.remove(index)
  Segue::Queue.remove(index) { list }
end

.render(window, lines) ⇒ Object



92
93
94
95
96
97
98
99
100
# File 'lib/segue.rb', line 92

def self.render(window, lines)
  window.setpos(0, 0)
  lines.each do |colour, text|
    window.attron(Curses.color_pair(colour)) { window << text }
    Curses.clrtoeol
  end
  (window.maxy - window.cury).times { window.deleteln }
  window.refresh
end

.scrobble(value) ⇒ Object



116
117
118
119
120
121
# File 'lib/segue.rb', line 116

def self.scrobble(value)
  preferences = Segue::Preferences.new
  preferences[:scrobble] = value == "on"
  scrobbler = Segue::Scrobbler.load if preferences.scrobble?
  preferences[:scrobble] = false unless scrobbler
end

.skipObject



123
124
125
# File 'lib/segue.rb', line 123

def self.skip
  Segue::Preferences.new[:skip] = true
end

.stopObject



127
128
129
# File 'lib/segue.rb', line 127

def self.stop
  Segue::Preferences.new[:stop] = true
end

.swap(args) ⇒ Object



131
132
133
134
# File 'lib/segue.rb', line 131

def self.swap(args)
  a, b = *args
  Segue::Queue.swap(a, b) { list }
end