Class: Segue::Player

Inherits:
Object
  • Object
show all
Defined in:
lib/segue/player.rb

Overview

Drives a pair of mpv instances so one can fade up while the other fades down - mpv has no crossfade of its own.

Constant Summary collapse

MAX_VOLUME =
100
FADE_STEPS =
10
FADE_STEP_SECONDS =
0.5
QUIT_TIMEOUT =
2

Instance Method Summary collapse

Constructor Details

#initialize(executable: ENV.fetch("SEGUE_MPV", "mpv")) ⇒ Player

Returns a new instance of Player.



16
17
18
19
20
21
22
# File 'lib/segue/player.rb', line 16

def initialize(executable: ENV.fetch("SEGUE_MPV", "mpv"))
  @executable = executable
  @processes = []
  @current = spawn_mpv("a")
  @other = spawn_mpv("b")
  @stopped = nil
end

Instance Method Details

#cleanupObject



80
81
82
83
84
85
86
87
88
# File 'lib/segue/player.rb', line 80

def cleanup
  [@current, @other].compact.each(&:close)
  @current = @other = nil
  @processes.each do |pid, socket_path|
    terminate pid
    FileUtils.rm_f socket_path
  end
  @processes = []
end

#crossfade(path) ⇒ Object



49
50
51
52
53
54
55
56
# File 'lib/segue/player.rb', line 49

def crossfade(path)
  @other.set("volume", 0)
  @other.load(path)
  fade([@current, MAX_VOLUME, 0], [@other, 0, MAX_VOLUME])
  @current.command("stop")
  @current, @other = @other, @current
  @stopped = nil
end

#fadeinObject



43
44
45
46
47
# File 'lib/segue/player.rb', line 43

def fadein
  @current.set("volume", 0)
  play
  fade([@current, 0, MAX_VOLUME])
end

#fadeoutObject



39
40
41
# File 'lib/segue/player.rb', line 39

def fadeout
  fade([@current, MAX_VOLUME, 0])
end

#pauseObject



70
71
72
# File 'lib/segue/player.rb', line 70

def pause
  @current.set("pause", true)
end

#play(path = nil) ⇒ Object



58
59
60
61
62
63
64
65
66
67
68
# File 'lib/segue/player.rb', line 58

def play(path = nil)
  if path
    @current.set("volume", MAX_VOLUME)
    @current.load(path)
  elsif @stopped
    @current.load(@stopped[:path], start: @stopped[:time])
  else
    @current.set("pause", false)
  end
  @stopped = nil
end

#playing?Boolean

Returns:

  • (Boolean)


24
25
26
# File 'lib/segue/player.rb', line 24

def playing?
  loaded? && @current.get("pause") == false
end

#remainingObject



32
33
34
35
36
37
# File 'lib/segue/player.rb', line 32

def remaining
  duration = @current.get("duration")
  return 0 unless duration

  [(duration - (@current.get("time-pos") || 0)).round, 0].max
end

#stopObject

mpv unloads the file on stop, so remember where we were to let play resume.



75
76
77
78
# File 'lib/segue/player.rb', line 75

def stop
  @stopped = { path: @current.get("path"), time: @current.get("time-pos") }
  @current.command("stop")
end

#timeObject



28
29
30
# File 'lib/segue/player.rb', line 28

def time
  (@current.get("time-pos") || 0).round
end