using createProcess and waitForProcess, but mpg123 plays for only 6 seconds

Hi guys, I'm building an application that needs to wrap an external mp3 player, in this case mpg123. Here is my code: import System.IO import System.Process import Control.Concurrent mpgLoop = do let sh = "mpg123 -R" (Just hin, Just hout, _, hdl) <- createProcess (shell sh){ std_in = CreatePipe, std_out=CreatePipe } --hPutStrLn hin "SILENCE" hPutStrLn hin "LOAD /home/rnons/Music/test.mp3" hFlush hin waitForProcess hdl return () main = do forkIO mpgLoop -- threadDelay 20000000 getChar I expected with "waitForProcess", this program will be able to run till the song ends. However, mpg123 plays for only 6 seconds. Maybe I missed something? rnons

rnons
mpgLoop = do let sh = "mpg123 -R" (Just hin, Just hout, _, hdl) <- createProcess (shell sh){ std_in = CreatePipe, std_out=CreatePipe } --hPutStrLn hin "SILENCE" hPutStrLn hin "LOAD /home/rnons/Music/test.mp3" hFlush hin waitForProcess hdl return ()
[...]
I expected with "waitForProcess", this program will be able to run till the song ends. However, mpg123 plays for only 6 seconds.
Maybe I missed something?
Just a guess: the problem may be that "a Handle will be automatically closed when the garbage collector detects that it has become unreferenced by the program"[1], and in the program above, the liveness of the hin/hout references ends before mpg123 is finished playing. And 'mpg123 -R' shuts down as soon as it detects its stdin (or stdout) getting EOF... so that's what you're experiencing most likely here. Try to keep hin/hout "alive" a bit longer, and mpg123 should survive longer. Also you should most probably consume the output comming from 'mpg123 -R' via 'hout', as otherwise it the buffer might build up and mpg123 might block. hth, hvr [1]: http://hackage.haskell.org/packages/archive/base/4.6.0.0/doc/html/System-IO....

Herbert Valerio Riedel
Try to keep hin/hout "alive" a bit longer, and mpg123 should survive longer. Also you should most probably consume the output comming from 'mpg123 -R' via 'hout', as otherwise it the buffer might build up and mpg123 might block.
[1]: http://hackage.haskell.org/packages/archive/base/4.6.0.0/doc/html/System-IO....
Shame of me, I've opened that link several times without noticing that paragraph. You're quite right. After understanding the details, I think there can be many solutions. But at present, I'm satisfied with this quick fix: import System.Exit import System.IO import System.Process import Control.Concurrent mpgLoop = do let sh = "mpg123 -R" (Just hin, Just hout, _, hdl) <- createProcess (shell sh){ std_in = CreatePipe, std_out = CreatePipe } hPutStrLn hin "SILENCE" -- mildly prevent buffer blocking hPutStrLn hin "LOAD /home/rnons/Music/test.mp3" hFlush hin waitForProcess hdl >>= exitWith hPutStrLn hin "STOP" -- keep hin "alive" a bit longer hGetContents hout hFlush hin return () main = do forkIO mpgLoop getChar Thank you very much! rnons

Yes, the automatic closing of handles has confused me as well when I wrote Proctest: http://hackage.haskell.org/packages/archive/proctest/latest/doc/html/Test-Pr... It might contain useful examples on how to deal with processes. Niklas On 15/11/12 14:42, Herbert Valerio Riedel wrote:
rnons
writes: [...]
mpgLoop = do let sh = "mpg123 -R" (Just hin, Just hout, _, hdl) <- createProcess (shell sh){ std_in = CreatePipe, std_out=CreatePipe } --hPutStrLn hin "SILENCE" hPutStrLn hin "LOAD /home/rnons/Music/test.mp3" hFlush hin waitForProcess hdl return ()
[...]
I expected with "waitForProcess", this program will be able to run till the song ends. However, mpg123 plays for only 6 seconds.
Maybe I missed something?
Just a guess: the problem may be that "a Handle will be automatically closed when the garbage collector detects that it has become unreferenced by the program"[1], and in the program above, the liveness of the hin/hout references ends before mpg123 is finished playing. And 'mpg123 -R' shuts down as soon as it detects its stdin (or stdout) getting EOF... so that's what you're experiencing most likely here.
Try to keep hin/hout "alive" a bit longer, and mpg123 should survive longer. Also you should most probably consume the output comming from 'mpg123 -R' via 'hout', as otherwise it the buffer might build up and mpg123 might block.
hth, hvr
[1]: http://hackage.haskell.org/packages/archive/base/4.6.0.0/doc/html/System-IO....
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
participants (3)
-
Herbert Valerio Riedel
-
Niklas Hambüchen
-
rnons