Class: Charming::Audio::Player
- Inherits:
-
Object
- Object
- Charming::Audio::Player
- Defined in:
- lib/charming/audio/player.rb
Overview
Player plays a single sound file by spawning a system audio binary, and exposes
stop/playing?/wait to manage the child process. It never blocks the event
loop on its own — call #play for fire-and-forget playback, or drive it from a
controller run_task (spawn + #wait, with an ensure player.stop) to get a
completion event and reliable teardown when the app quits.
A backend binary is resolved on first use, in priority order: ffplay (from
ffmpeg) on every platform, then OS-native players (afplay on macOS; paplay,
mpg123, aplay on Linux). Unavailable is raised when none are installed.
Defined Under Namespace
Classes: Unavailable
Constant Summary collapse
- BACKENDS =
Candidate backends in resolution order.
:osis:any,:macos, or:linux;:argsare inserted before the file path in the spawned command. [ {command: "ffplay", os: :any, args: ["-nodisp", "-autoexit", "-loglevel", "quiet"]}, {command: "afplay", os: :macos, args: []}, {command: "paplay", os: :linux, args: []}, {command: "mpg123", os: :linux, args: ["-q"]}, {command: "aplay", os: :linux, args: ["-q"]} ].freeze
Instance Method Summary collapse
-
#available? ⇒ Boolean
True when a backend binary is installed for this platform.
-
#initialize(system: System.new) ⇒ Player
constructor
system is the OS adapter used to probe
PATHand spawn/track the player process. -
#play(path) ⇒ Object
Plays the sound file at path, stopping any sound already in progress first.
-
#playing? ⇒ Boolean
True while a spawned sound is still playing.
-
#stop ⇒ Object
Stops the current sound (if any), terminating and reaping the child process.
-
#wait ⇒ Object
Blocks until the current sound finishes, then clears it.
Constructor Details
#initialize(system: System.new) ⇒ Player
system is the OS adapter used to probe PATH and spawn/track the player
process. The default talks to the real OS; specs inject a fake.
32 33 34 35 |
# File 'lib/charming/audio/player.rb', line 32 def initialize(system: System.new) @system = system @pid = nil end |
Instance Method Details
#available? ⇒ Boolean
True when a backend binary is installed for this platform. Lets callers degrade gracefully (e.g. skip a chime) instead of rescuing Unavailable.
73 74 75 |
# File 'lib/charming/audio/player.rb', line 73 def available? !backend.nil? end |
#play(path) ⇒ Object
Plays the sound file at path, stopping any sound already in progress first. Spawns the resolved backend and returns the child PID. Raises Unavailable when no backend binary is installed for this platform.
40 41 42 43 44 |
# File 'lib/charming/audio/player.rb', line 40 def play(path) backend = resolve_backend! stop if @pid = @system.spawn([backend[:command], *backend[:args], path.to_s]) end |
#playing? ⇒ Boolean
True while a spawned sound is still playing.
57 58 59 |
# File 'lib/charming/audio/player.rb', line 57 def !@pid.nil? && @system.alive?(@pid) end |
#stop ⇒ Object
Stops the current sound (if any), terminating and reaping the child process. Safe to call when nothing is playing.
48 49 50 51 52 53 54 |
# File 'lib/charming/audio/player.rb', line 48 def stop return unless @pid @system.terminate(@pid) @system.wait(@pid) @pid = nil end |
#wait ⇒ Object
Blocks until the current sound finishes, then clears it. Intended for use inside
a background run_task. If the task thread is killed mid-wait (e.g. on app
shutdown), @pid is left intact so an ensure player.stop can reap the child.
64 65 66 67 68 69 |
# File 'lib/charming/audio/player.rb', line 64 def wait return unless @pid @system.wait(@pid) @pid = nil end |