rnons | 15 Nov 12:18 2012
Picon

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?
(Continue reading)

Herbert Valerio Riedel | 15 Nov 15:42 2012
Picon

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

rnons <remotenonsense <at> gmail.com> 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
(Continue reading)

rnons | 15 Nov 17:09 2012
Picon

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

Herbert Valerio Riedel <hvr <at> gnu.org> wrote:

>
> 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.html#t:Handle

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
(Continue reading)

Niklas Hamb├╝chen | 15 Nov 17:21 2012

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

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-Proctest.html

It might contain useful examples on how to deal with processes.

Niklas

On 15/11/12 14:42, Herbert Valerio Riedel wrote:
> rnons <remotenonsense <at> gmail.com> 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?
> 
(Continue reading)


Gmane