haskell-player-0.1.3.3: src/Sound/Player/AudioPlay.hs
module Sound.Player.AudioPlay (
play,
pause,
resume,
stop
) where
import System.Process (ProcessHandle, StdStream(CreatePipe),
CreateProcess(std_err), createProcess, proc, terminateProcess)
import System.Posix (ProcessID)
import System.Posix.Signals (signalProcess)
import System.Process.Internals (ProcessHandle__(OpenHandle, ClosedHandle),
withProcessHandle)
-- | Creates an @afplay@ process to play file at @path@.
--
-- Note: it suppresses process' @stderr@.
play :: FilePath -> IO ProcessHandle
play path = do
(_, _, _, processHandle) <-
-- TODO: update System.Process version to use NoStream
createProcess (proc "afplay" [path]) {
std_err = CreatePipe
}
return processHandle
-- | Sends a @17@ signal to @ph@'s process. If @ph@ is the handle of a running
-- @afplay@ process it will pause playback.
pause :: ProcessHandle -> IO ()
pause ph =
maybe (return ()) (signalProcess 17) =<< getPid ph
-- | Sends a @19@ signal to @ph@'s process. If @ph@ is the handle of a running
-- @afplay@ process it will resume playback.
resume :: ProcessHandle -> IO ()
resume ph =
maybe (return ()) (signalProcess 19) =<< getPid ph
-- | Terminates the selected process. If @ph@ is the handle of a running
-- @afplay@ process it will stop playback.
stop :: ProcessHandle -> IO ()
stop = terminateProcess
-- See https://mail.haskell.org/pipermail/haskell-cafe/2012-October/104028.html
getPid :: ProcessHandle -> IO (Maybe ProcessID)
getPid ph = withProcessHandle ph (return . go)
where
go (OpenHandle pid) = Just pid
go (ClosedHandle _) = Nothing