Class: MPV::Client
- Inherits:
-
Object
- Object
- MPV::Client
- Defined in:
- lib/mpv_ipc/client.rb
Overview
Represents a connection to an ‘mpv` process over an IPC socket.
Defined Under Namespace
Classes: Event, KeyEvent, ObserverEvent, Reply
Class Method Summary collapse
-
.script ⇒ MPV::Client
Alternative constructor for mpv embedded script mode.
Instance Method Summary collapse
-
#alive? ⇒ Boolean
Checks whether the mpv connection is still alive.
-
#clear_osd_messages ⇒ void
Deletes all messages on the OSD.
-
#command(*args) ⇒ Reply
Sends a command to the ‘mpv` process.
-
#command!(*args) ⇒ Object
Sends a command to the ‘mpv` process and then checks if it was successful.
-
#create_osd_message(text, timeout: nil) ⇒ Integer
Creates a new message and adds it to the OSD.
-
#delete_osd_message(id) ⇒ void
Deletes one of the messages on the OSD.
-
#edit_osd_message(id, text, timeout: nil) ⇒ Boolean
Edits one of the messages on the OSD.
-
#enter_modal_mode(message, keys, exit_key: "ESC") {|KeyEvent| ... } ⇒ String
Enters a modal mode, similar to Vim’s modes, but exits after a single keypress or when the exit key is pressed.
-
#get_property(name) ⇒ Reply
Retrieves a property from the ‘mpv` process.
-
#get_property!(name) ⇒ Object
Retrieves a property from the ‘mpv` process and then confirms success.
-
#initialize(conn) ⇒ Client
constructor
Creates a new MPV::Client instance.
-
#observe_property(name) {|ObserverEvent| ... } ⇒ Integer
Observes property changes.
-
#quit! ⇒ Boolean
Sends a ‘quit` command to shut down the `mpv` process and releases the communication with it.
-
#register_event_listener(name = "") {|Event| ... } ⇒ void
Registers an event listener.
-
#register_keybindings(*keys, section: nil, flags: :default) {|KeyEvent| ... } ⇒ String
Registers a keybinding section.
-
#register_message_handler(message) {|Array| ... } ⇒ void
Registers a client-message handler.
-
#register_shutdown_callback {|Boolean| ... } ⇒ void
Registers a shutdown callback for notification or cleanup.
-
#release! ⇒ void
Terminates the mpv communication.
-
#set_property(name, value) ⇒ Reply
Sends a property change to the ‘mpv` process.
-
#set_property!(name, value) ⇒ Object
Sends a property change to the ‘mpv` process and then confirms success.
-
#unobserve_property(id) ⇒ void
Unobserves property changes.
-
#unregister_event_listener(name = "") ⇒ void
Unregisters an event listener.
-
#unregister_keybindings(section) ⇒ void
Unregisters a keybinding section.
-
#unregister_message_handler(message) ⇒ void
Unregisters a client-message handler.
-
#unregister_shutdown_callback ⇒ void
Unregisters the current shutdown callback.
-
#wait(timeout = nil) ⇒ Boolean
Waits for the mpv connection to terminate.
Constructor Details
#initialize(conn) ⇒ Client
Creates a new MPV::Client instance.
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
# File 'lib/mpv_ipc/client.rb', line 34 def initialize(conn) @socket = case conn when String then UNIXSocket.new(@path = conn) when Integer then Socket.for_fd(conn) else conn end @request_id = Concurrent::AtomicFixnum.new(MIN_REQ_ID - 1) @reply_queue = MultiQueue.new(RESPONSE_TIMEOUT) @event_listeners = Concurrent::Hash.new @property_observers = Concurrent::Hash.new @message_handlers = Concurrent::Hash.new @keybinding_handlers = Concurrent::Hash.new @osd_messages = Concurrent::Hash.new @event_queue = Queue.new @cmd_mutex = Mutex.new @keybinding_mutex = Mutex.new @osd_mutex = Mutex.new @shutdown_callback = nil @link_thread = Thread.new(&method(:link_loop)) @link_thread.name = "mpv link" @event_thread = Thread.new(&method(:event_loop)) @event_thread.name = "mpv event" end |
Class Method Details
.script ⇒ MPV::Client
Alternative constructor for mpv embedded script mode.
21 22 23 24 25 26 27 |
# File 'lib/mpv_ipc/client.rb', line 21 def self.script require "optparse" OptionParser.new do |opts| opts.on("--mpv-ipc-fd=N", Integer){ |fd| return new(fd) } end.parse! raise ArgumentError, "--mpv-ipc-fd argument not provided" end |
Instance Method Details
#alive? ⇒ Boolean
Checks whether the mpv connection is still alive.
60 61 62 |
# File 'lib/mpv_ipc/client.rb', line 60 def alive? @link_thread.alive? end |
#clear_osd_messages ⇒ void
This method returns an undefined value.
Deletes all messages on the OSD.
349 350 351 352 353 354 355 356 357 358 |
# File 'lib/mpv_ipc/client.rb', line 349 def @osd_mutex.synchronize do unless @osd_messages.empty? @osd_messages.each_value{ |(_, scheduler)| scheduler&.cancel } @osd_messages.clear end end nil end |
#command(*args) ⇒ Reply
Sends a command to the ‘mpv` process.
101 102 103 104 105 106 107 108 109 110 |
# File 'lib/mpv_ipc/client.rb', line 101 def command(*args) raise ReleasedConnectionError unless alive? @reply_queue.open(next_id) do |queue| payload = { command: args, request_id: queue.id, async: true } @cmd_mutex.synchronize{ @socket.puts(JSON.fast_generate(payload)) } queue.pop end rescue IOError, SystemCallError => exc raise ConnectionError, exc end |
#command!(*args) ⇒ Object
Sends a command to the ‘mpv` process and then checks if it was successful.
122 123 124 |
# File 'lib/mpv_ipc/client.rb', line 122 def command!(*args) command(*args).data! end |
#create_osd_message(text, timeout: nil) ⇒ Integer
Creates a new message and adds it to the OSD.
287 288 289 290 291 292 293 294 295 |
# File 'lib/mpv_ipc/client.rb', line 287 def (text, timeout: nil) id = next_id @osd_messages[id] = nil, nil (id, text, timeout: timeout) id rescue @osd_messages.delete(id) raise end |
#delete_osd_message(id) ⇒ void
This method returns an undefined value.
Deletes one of the messages on the OSD.
336 337 338 339 340 341 342 343 344 |
# File 'lib/mpv_ipc/client.rb', line 336 def (id) @osd_mutex.synchronize do if record = @osd_messages.delete(id) record[1]&.cancel end end nil end |
#edit_osd_message(id, text, timeout: nil) ⇒ Boolean
Edits one of the messages on the OSD.
304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 |
# File 'lib/mpv_ipc/client.rb', line 304 def (id, text, timeout: nil) text = Ass::Text.new(text) unless text.is_a?(Ass::Text) @osd_mutex.synchronize do if record = @osd_messages[id] record[0] = text.to_script if timeout if timeout.positive? unless record[1]&.reschedule(timeout) record[1] = task = Concurrent::ScheduledTask.execute(timeout) do @osd_mutex.synchronize do if @osd_messages.dig(id, 1) == task @osd_messages.delete(id) end end end end elsif record[1] record[1].cancel record[1] = nil end end end !!record end end |
#enter_modal_mode(message, keys, exit_key: "ESC") {|KeyEvent| ... } ⇒ String
Enters a modal mode, similar to Vim’s modes, but exits after a single keypress or when the exit key is pressed.
375 376 377 378 379 380 381 382 383 384 385 |
# File 'lib/mpv_ipc/client.rb', line 375 def enter_modal_mode(, keys, exit_key: "ESC", &block) osd_id = () register_keybindings(*keys, exit_key, flags: :force) do |event| (osd_id) rescue nil unregister_keybindings(event.section) rescue nil block.call(event) if block_given? && event.key != exit_key end rescue (osd_id) rescue nil raise end |
#get_property(name) ⇒ Reply
Retrieves a property from the ‘mpv` process.
134 135 136 |
# File 'lib/mpv_ipc/client.rb', line 134 def get_property(name) command("get_property", name) end |
#get_property!(name) ⇒ Object
Retrieves a property from the ‘mpv` process and then confirms success.
146 147 148 |
# File 'lib/mpv_ipc/client.rb', line 146 def get_property!(name) get_property(name).data! end |
#observe_property(name) {|ObserverEvent| ... } ⇒ Integer
Observes property changes.
185 186 187 188 189 190 191 192 193 |
# File 'lib/mpv_ipc/client.rb', line 185 def observe_property(name, &block) id = next_id @property_observers[id] = block command!("observe_property", id, name) id rescue @property_observers.delete(id) raise end |
#quit! ⇒ Boolean
Sends a ‘quit` command to shut down the `mpv` process and releases the communication with it.
81 82 83 84 85 86 87 88 89 |
# File 'lib/mpv_ipc/client.rb', line 81 def quit! command!("quit") @link_thread.join true rescue @link_thread.exit @link_thread.join false end |
#register_event_listener(name = "") {|Event| ... } ⇒ void
This method returns an undefined value.
Registers an event listener.
208 209 210 |
# File 'lib/mpv_ipc/client.rb', line 208 def register_event_listener(name="", &block) @event_listeners[name] = block end |
#register_keybindings(*keys, section: nil, flags: :default) {|KeyEvent| ... } ⇒ String
Registers a keybinding section.
255 256 257 258 259 260 261 262 263 264 265 266 267 |
# File 'lib/mpv_ipc/client.rb', line 255 def register_keybindings(*keys, section: nil, flags: :default, &block) section ||= "sect_#{next_id}" contents = keys.flatten.map{ |key| "#{key} script-binding #{client_name}/#{section}" } @keybinding_mutex.synchronize do @keybinding_handlers[section] = block command!("define-section", section, contents.join("\n"), flags) command!("enable-section", section) rescue @keybinding_handlers.delete(section) raise end section end |
#register_message_handler(message) {|Array| ... } ⇒ void
This method returns an undefined value.
Registers a client-message handler.
229 230 231 |
# File 'lib/mpv_ipc/client.rb', line 229 def (, &block) @message_handlers[] = block end |
#register_shutdown_callback {|Boolean| ... } ⇒ void
This method returns an undefined value.
Registers a shutdown callback for notification or cleanup.
391 392 393 |
# File 'lib/mpv_ipc/client.rb', line 391 def register_shutdown_callback(&block) @shutdown_callback = block end |
#release! ⇒ void
This method returns an undefined value.
Terminates the mpv communication.
73 74 75 76 |
# File 'lib/mpv_ipc/client.rb', line 73 def release! @link_thread.exit @link_thread.join end |
#set_property(name, value) ⇒ Reply
Sends a property change to the ‘mpv` process.
159 160 161 |
# File 'lib/mpv_ipc/client.rb', line 159 def set_property(name, value) command("set_property", name, value) end |
#set_property!(name, value) ⇒ Object
Sends a property change to the ‘mpv` process and then confirms success.
172 173 174 |
# File 'lib/mpv_ipc/client.rb', line 172 def set_property!(name, value) set_property(name, value).data! end |
#unobserve_property(id) ⇒ void
This method returns an undefined value.
Unobserves property changes.
199 200 201 202 |
# File 'lib/mpv_ipc/client.rb', line 199 def unobserve_property(id) command!("unobserve_property", id) @property_observers.delete(id) end |
#unregister_event_listener(name = "") ⇒ void
This method returns an undefined value.
Unregisters an event listener.
215 216 217 |
# File 'lib/mpv_ipc/client.rb', line 215 def unregister_event_listener(name="") @event_listeners.delete(name) end |
#unregister_keybindings(section) ⇒ void
This method returns an undefined value.
Unregisters a keybinding section.
273 274 275 276 277 278 279 |
# File 'lib/mpv_ipc/client.rb', line 273 def unregister_keybindings(section) @keybinding_mutex.synchronize do command!("disable-section", section) command!("define-section", section, "") @keybinding_handlers.delete(section) end end |
#unregister_message_handler(message) ⇒ void
This method returns an undefined value.
Unregisters a client-message handler.
236 237 238 |
# File 'lib/mpv_ipc/client.rb', line 236 def () @message_handlers.delete() end |
#unregister_shutdown_callback ⇒ void
This method returns an undefined value.
Unregisters the current shutdown callback.
397 398 399 |
# File 'lib/mpv_ipc/client.rb', line 397 def unregister_shutdown_callback @shutdown_callback = nil end |
#wait(timeout = nil) ⇒ Boolean
Waits for the mpv connection to terminate.
67 68 69 |
# File 'lib/mpv_ipc/client.rb', line 67 def wait(timeout=nil) !!@link_thread.join(timeout) end |