Class: MPlayer

Inherits:
Object
  • Object
show all
Includes:
ColorDebugMessages, Error
Defined in:
lib/easy_mplayer.rb,
lib/easy_mplayer/main.rb,
lib/easy_mplayer/errors.rb,
lib/easy_mplayer/worker.rb,
lib/easy_mplayer/helpers.rb,
lib/easy_mplayer/callback.rb,
lib/easy_mplayer/commands.rb

Defined Under Namespace

Modules: Error Classes: Callback, CallbackList, Command, Worker

Constant Summary collapse

DEFAULT_OPTS =

all of these can be overridden by passing them to #new

{
  :program               => '/usr/bin/mplayer',
  :message_style         => :info,
  :seek_size             => 10,
  :thread_safe_callbacks => true
}
DEBUG_MESSAGE_TYPES =

the color_debug_message parameter sets we can switch between, for convenience. (flags for ColorDebugMessages)

{
  :quiet => {
  },
  :error_only => {
    :warn       => true
  },
  :info => {
    :warn       => true,
    :info       => true
  },
  :debug => {
    :warn       => true,
    :info       => true,
    :debug      => true,
    :class_only => false
  }
}

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(new_opts = Hash.new) ⇒ MPlayer

create a new object, with the named options valid options:

:program               Path to the mplayer binary itself
                       (default: /usr/bin/mplayer)
:path                  Path to the media file to be played
:message_style         How verbose our debug messages should
                       be (see #set_message_style)
:seek_size             Time, in seconds, to seek
                       forwards/reverse by default (default:
                       10 seconds)
:thread_safe_callbacks If we should buffer callbacks back to
                       the main thread, so they are called off
                       the #playing? polling-loop (default: true)


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

def initialize(new_opts=Hash.new)
  @opts = DEFAULT_OPTS.merge(new_opts)
  set_message_style opts[:message_style]
  
  unless File.executable?(@opts[:program])
    raise NoPlayerFound.new(@opts[:program]) 
  end
  
  @stats     = Hash.new
  @callbacks = Hash.new
  @worker    = nil

  self.class.class_callbacks.each do |opts|
    opts[:scope] = self
    CallbackList.register opts
  end
end

Instance Attribute Details

#callbacksObject (readonly)

Returns the value of attribute callbacks.



30
31
32
# File 'lib/easy_mplayer/main.rb', line 30

def callbacks
  @callbacks
end

#optsObject (readonly)

Returns the value of attribute opts.



30
31
32
# File 'lib/easy_mplayer/main.rb', line 30

def opts
  @opts
end

#statsObject (readonly)

Returns the value of attribute stats.



30
31
32
# File 'lib/easy_mplayer/main.rb', line 30

def stats
  @stats
end

Class Method Details

.callback(*names, &block) ⇒ Object

register a block with the named callback(s). This is the same as the instance-method, generally, but it uses instance_exec to give the block the same scope (the MPlayer instance)



40
41
42
43
44
45
46
47
48
# File 'lib/easy_mplayer/main.rb', line 40

def callback(*names, &block)
  names.each do |name|
    class_callbacks << {
      :name  => name,
      :type  => :class,
      :block => block
    }
  end
end

.class_callbacksObject

:nodoc:



33
34
35
# File 'lib/easy_mplayer/main.rb', line 33

def class_callbacks # :nodoc:
  @@class_callbacks ||= Array.new
end

Instance Method Details

#callback(*names, &block) ⇒ Object

register a function into each of the named callback chains



161
162
163
164
165
# File 'lib/easy_mplayer/main.rb', line 161

def callback(*names, &block)
  names.each do |name|
    CallbackList.register :name => name, :block => block, :type => :instance
  end
end

#callback!(name, *args) ⇒ Object

call an entire callback chain, passing in a list of args



155
156
157
158
# File 'lib/easy_mplayer/main.rb', line 155

def callback!(name, *args) # :nodoc:
  #puts "CALLBACK! #{name.inspect} #{args.inspect}"
  CallbackList.run!(name, args)
end

#create_workerObject

:nodoc:



187
188
189
190
191
192
193
# File 'lib/easy_mplayer/main.rb', line 187

def create_worker # :nodoc:
  callback! :creating_worker
  @worker = Worker.new(self)
  @stats  = Hash.new
  @paused = false
  callback! :worker_running
end

#embed(&block) ⇒ Object

takes a block, that should return the X11 window_id of a window that mplayer can use as a render target. This will cause mplayer to embed its output into that window, as if it was a native widget.



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

def embed(&block)
  @opts[:embed] = block
end

#inspectObject

:nodoc:



145
146
147
148
149
150
151
152
# File 'lib/easy_mplayer/main.rb', line 145

def inspect # :nodoc:
  vals = [['running', running?],
          ['paused',  paused?]]
  vals << ['info', stats.inspect] if running?
  "#<#{self.class} " + vals.map do |x|
    x.first + '=' + x.last.to_s
  end.join(' ') + '>'
end

#must_be_ready!Object

:nodoc:



105
106
107
# File 'lib/easy_mplayer/main.rb', line 105

def must_be_ready! # :nodoc:
  ready? or raise NoTargetPath.new(@opts[:path])
end

#pathObject

returns the path we are currently playing



110
111
112
# File 'lib/easy_mplayer/main.rb', line 110

def path
  @opts[:path]
end

#path=(val) ⇒ Object

sets the path to #play - this does not interrupt a currently playing file. #stop and #play should be called again.



116
117
118
# File 'lib/easy_mplayer/main.rb', line 116

def path=(val)
  @opts[:path] = val
end

#pauseObject

pause playback if we are running



27
28
29
30
31
32
33
34
# File 'lib/easy_mplayer/helpers.rb', line 27

def pause
  return unless running?
  return if paused?
  info "PAUSE!"
  send_command :pause
  @paused = true
  callback! :pause, true
end

#pause_or_unpauseObject

use this instead of #pause or #unpause, and the flag will be toggled with each call



48
49
50
# File 'lib/easy_mplayer/helpers.rb', line 48

def pause_or_unpause
  paused? ? unpause : pause
end

#paused?Boolean

true if we are running, yet the media has stopped

Returns:

  • (Boolean)


168
169
170
# File 'lib/easy_mplayer/main.rb', line 168

def paused?
  @paused
end

#playObject

spawn the mplayer process, which also starts the media playing. It is requires that #opts point to a valid media file



11
12
13
14
15
16
17
# File 'lib/easy_mplayer/helpers.rb', line 11

def play
  must_be_ready!
  stop if running?
  
  info "PLAY: #{opts[:path]}"
  worker.startup!
end

#play_to_endObject

a blocking version of #play for trivial uses. It returns only after the mplayer process finally terminates itself



4
5
6
7
# File 'lib/easy_mplayer/helpers.rb', line 4

def play_to_end
  play
  sleep 1 while running?
end

#ready?Boolean

true if we can call #play without an exception

Returns:

  • (Boolean)


101
102
103
# File 'lib/easy_mplayer/main.rb', line 101

def ready?
  @opts[:path] and File.readable?(@opts[:path])
end

#running?Boolean

true if the mplayer process is active and running

Returns:

  • (Boolean)


173
174
175
# File 'lib/easy_mplayer/main.rb', line 173

def running?
  !!@worker and @worker.ok?
end

#seek_by(amount) ⇒ Object

seek by a relative amount, in seconds. requires a float. Negative values rewind to a previous point.



73
74
75
76
77
# File 'lib/easy_mplayer/helpers.rb', line 73

def seek_by(amount)
  return unless running?
  info "SEEK BY: #{amount}"
  send_command :seek, amount, 0
end

#seek_forward(amount = opts[:seek_size]) ⇒ Object

seek forward a given number of seconds, or opts[:seek_size] seconds by default



81
82
83
# File 'lib/easy_mplayer/helpers.rb', line 81

def seek_forward(amount = opts[:seek_size])
  seek_by(amount)
end

#seek_reverse(amount = opts[:seek_size]) ⇒ Object

seek backwards (rewind) by a given number of seconds, or opts[:seek_size] seconds by default. Note that a /positive/ value here rewinds!



88
89
90
# File 'lib/easy_mplayer/helpers.rb', line 88

def seek_reverse(amount = opts[:seek_size])
  seek_by(-amount)
end

#seek_startObject

reset back to the beginning of the file



93
94
95
# File 'lib/easy_mplayer/helpers.rb', line 93

def seek_start
  seek_to_percent(0.0)
end

#seek_to_percent(percent) ⇒ Object

Seek to an absolute position in a file, by percent of the total size. requires a float argument, that is (0.0 <= percent <= 100.0)



54
55
56
57
58
59
60
61
# File 'lib/easy_mplayer/helpers.rb', line 54

def seek_to_percent(percent)
  return if percent.to_i == @stats[:position]
  percent = percent.to_f
  percent = 0.0   if percent < 0
  percent = 100.0 if percent > 100
  info "SEEK TO: #{percent}%"
  send_command :seek, percent, 1
end

#seek_to_time(seconds) ⇒ Object

seek to an absolute position in a file, by seconds. requires a float between 0.0 and the length (in seconds) of the file being played.



65
66
67
68
69
# File 'lib/easy_mplayer/helpers.rb', line 65

def seek_to_time(seconds)
  return unless running?
  info "SEEK TO: #{seconds} seconds"
  send_command :seek, seconds, 1
end

#send_command(*args) ⇒ Object

pipe a command to mplayer via slave mode



178
179
180
# File 'lib/easy_mplayer/main.rb', line 178

def send_command(*args)
  worker.send_command(*args)
end

#set_message_style(type) ⇒ Object

can be any of:

:quiet      Supperss all output!
:error_only Off except for errors
:info       Also show information messages
:debug      Heavy debug output (spammy)


132
133
134
135
136
137
138
139
140
141
142
143
# File 'lib/easy_mplayer/main.rb', line 132

def set_message_style(type)
  hsh = DEBUG_MESSAGE_TYPES[type.to_sym] or
    raise BadMsgType.new(type.inspect)
  hsh = hsh.dup
  hsh[:debug]       ||= false
  hsh[:info]        ||= false
  hsh[:warn]        ||= false
  hsh[:class_only]  ||= true
  hsh[:prefix_only] ||= false
  ColorDebugMessages.global_debug_flags(hsh)
  opts[:message_style] = type
end

#stopObject

kill off the mplayer process. This invalidates any running media, though it can be restarted again with another call to #play



21
22
23
24
# File 'lib/easy_mplayer/helpers.rb', line 21

def stop
  info "STOP!"
  @worker.shutdown! if @worker
end

#unpauseObject

opposite of #pause



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

def unpause
  return unless running?
  return unless paused?
  info "UNPAUSE!"
  send_command :pause
  @paused = false
  callback! :unpause, false
end

#update_stat(name, newval) ⇒ Object

:nodoc:



195
196
197
198
199
200
201
202
# File 'lib/easy_mplayer/main.rb', line 195

def update_stat(name, newval) # :nodoc:
  name = name.to_sym
  if @stats[name] != newval
    debug "STATS[:#{name}] #{@stats[name].inspect} -> #{newval.inspect}"
    @stats[name] = newval
    callback! name, newval
  end
end

#workerObject

:nodoc:



182
183
184
185
# File 'lib/easy_mplayer/main.rb', line 182

def worker # :nodoc:
  create_worker if @worker.nil?
  @worker
end