class Mpg321::ProcessWrapper
Constants
- LOCALIZED_ENOENT_MESSAGE
This corresponds to the system-specific “No such file or directory” message. TODO: Would love to use strerror(3) instead, but Ruby doesn’t expose that.
Public Class Methods
new()
click to toggle source
# File lib/mpg321/process_wrapper.rb, line 5 def initialize spawn_mpg321 @callbacks = Hash.new { |h, e| h[e] = Array.new } @read_thr = async_handle_stdoe end
Public Instance Methods
on(event, &block)
click to toggle source
# File lib/mpg321/process_wrapper.rb, line 16 def on(event, &block) @callbacks[event] << block end
quit()
click to toggle source
# File lib/mpg321/process_wrapper.rb, line 20 def quit send_command 'Q' @read_thr.join @wait_thr.value end
send_command(command, *args)
click to toggle source
# File lib/mpg321/process_wrapper.rb, line 12 def send_command command, *args @stdin.puts [command, *(args.map(&:to_s))].join(' ') end
Private Instance Methods
async_handle_stdoe()
click to toggle source
:nocov:
# File lib/mpg321/process_wrapper.rb, line 41 def async_handle_stdoe Thread.new do begin loop { read_stdoe_line } rescue EOFError # Stream exhausted, ignore. end end end
emit(event, *args)
click to toggle source
# File lib/mpg321/process_wrapper.rb, line 36 def emit(event, *args) @callbacks[event].each { |cb| cb.call *args } end
read_stdoe_line()
click to toggle source
# File lib/mpg321/process_wrapper.rb, line 51 def read_stdoe_line line = @stdoe.readline case line[0..1] when '@F' parts = line.split(' ') emit :status_update, { current_frame: parts[1].to_i, frames_remaining: parts[2].to_i, current_time: parts[3].to_f, time_remaining: parts[4].to_f } when '@P' # mpg321 sends '@P 3' when the song has finished playing. if line[3] == '3' emit :playback_finished end when '@E' # This is sent in case of illegal syntax, e.g. an empty string # as parameter to the LOAD command. emit :error, line.strip else # Any critical error is sent to stderr and is not preprended # by an @ character. mpg321 immediately exits afterwards. if line[0] != '@' if line.include? LOCALIZED_ENOENT_MESSAGE # Handle file not found gracefully and restart mpg321. @wait_thr.join spawn_mpg321 emit :file_not_found else # TODO: This leaves the instance in a unusable state. Subsequent # calls to #send_message etc. will respond with EPIPE. emit :error, line.strip end end end end
spawn_mpg321()
click to toggle source
# File lib/mpg321/process_wrapper.rb, line 32 def spawn_mpg321 @stdin, @stdoe, @wait_thr = Open3.popen2e 'mpg321 -R mpg321_ruby' end