Class: Segue::Mpv

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

Overview

Client for mpv's JSON IPC protocol.

mpv speaks newline delimited JSON over a unix socket. Requests carry a request_id and replies echo it back, which is what lets us ignore the asynchronous event messages mpv interleaves with responses.

Defined Under Namespace

Classes: Error

Constant Summary collapse

CONNECT_TIMEOUT =
5
LOAD_TIMEOUT =
5
POLL_INTERVAL =
0.05

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(socket_path) ⇒ Mpv

Returns a new instance of Mpv.



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

def initialize(socket_path)
  @socket_path = socket_path
  @request_id = 0
end

Instance Attribute Details

#socket_pathObject (readonly)

Returns the value of attribute socket_path.



20
21
22
# File 'lib/segue/mpv.rb', line 20

def socket_path
  @socket_path
end

Instance Method Details

#closeObject



68
69
70
71
72
73
74
75
76
77
78
# File 'lib/segue/mpv.rb', line 68

def close
  return unless @socket

  begin
    request(["quit"])
  rescue Error, IOError, SystemCallError
    # mpv may have gone already - nothing left to ask politely
  end
  @socket.close unless @socket.closed?
  @socket = nil
end

#command(*args) ⇒ Object

Raises:



45
46
47
48
49
50
# File 'lib/segue/mpv.rb', line 45

def command(*args)
  reply = request(args)
  raise Error, "#{args.first}: #{reply["error"]}" unless reply["error"] == "success"

  reply["data"]
end

#connect(timeout: CONNECT_TIMEOUT) ⇒ Object

mpv creates the socket a moment after it starts, so retry until it shows up.



28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/segue/mpv.rb', line 28

def connect(timeout: CONNECT_TIMEOUT)
  deadline = Time.now + timeout
  begin
    @socket = UNIXSocket.new(socket_path)
  rescue Errno::ENOENT, Errno::ECONNREFUSED
    raise Error, "timed out waiting for mpv socket at #{socket_path}" if Time.now > deadline

    sleep POLL_INTERVAL
    retry
  end
  self
end

#connected?Boolean

Returns:

  • (Boolean)


41
42
43
# File 'lib/segue/mpv.rb', line 41

def connected?
  !@socket.nil?
end

#get(property) ⇒ Object

Returns nil when mpv considers a property unavailable - time-pos and duration are both unavailable whenever nothing is loaded.



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

def get(property)
  request(["get_property", property])["data"]
end

#load(path, start: nil) ⇒ Object



62
63
64
65
66
# File 'lib/segue/mpv.rb', line 62

def load(path, start: nil)
  command("loadfile", path, "replace")
  wait_for_load
  command("seek", start, "absolute") if start&.positive?
end

#set(property, value) ⇒ Object



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

def set(property, value)
  command("set_property", property, value)
end