From: Jeff C. <je...@jk...> - 2017-10-30 21:54:07
|
I'm having some trouble getting sb-ext:run-program to behave the way it is documented. I'm probably doing something wrong. I've put together a simple case that illustrates. What I'm trying to do is start an external slave process that can be controlled through the :input :stream option in run-program. My understanding is that so long as I set :wait nil run-program will launch the process and return the process structure which it seems to do. Then I should be able to send commands to the process by writing to sb-ext:process-input. The documentation I am following comes from here: https://www.common-lisp.net/project/cmucl/doc/cmu-user/extensions.html#@funs52 which is where the internal doc string on sb-ext:run-program says to look. In particular, it says: /If specified as :stream, then the process-input slot// //contains an output stream. Anything written to this stream goes// // to the program as input. :input may also be an input stream// // that already contains all the input for the process. In this// // case run-program reads all the input from this stream before// //returning, so this cannot be used to interact with the process./ Mplayer can operate as a slave like this using the "-slave" flag. Here's the code I'm using to try to do this: (let* ((ostring) (ostream) (process)) (defun start-slave-process (&rest args) (setf ostring (make-array '(0) :element-type 'character :fill-pointer 0 :adjustable t) ostream (sb-impl::make-fill-pointer-output-stream ostring) process (sb-ext:run-program "/usr/bin/mplayer" args :input :stream :output ostream :wait nil))) (defun pause-slave () (format (sb-ext:process-input process) "pause\n")) (defun quit-slave () (format (sb-ext:process-input process) "quit\n") (sb-ext:process-kill process 15)) (defun close-ostream () (close ostream)) (defun get-process () process) (defun get-ostring () ostring)) So I start the process: (start-slave-process "-slave" "-quiet" "http://bbcwssc.ic.llnwd.net/stream/bbcwssc_mp1_ws-einws") Streaming media is playing (for me) at this point. And it has returned what looks like a valid process structure: (print (get-process)) ;; ==> #<SB-IMPL::PROCESS 29225 :RUNNING> But the output isn't showing up: (print (get-ostring)) ;; ==> "" And I can't control the process through the stream command pause-slave. This should toggle the stream paused and un-paused: (pause-slave) ;; ==> does nothing The the write part of the quit-slave function doesn't work. The process-kill does work. (quit-slave) ;; ==> this actually works, but because of the kill process And the output string remains empty. I thought it might flush through at this point once the process terminated, but it does not. Running the same process from an xterm looks like this: $ mplayer -slave -quiet http://bbcwssc.ic.llnwd.net/stream/bbcwssc_mp1_ws-einws MPlayer 1.2.1 (Debian), built with gcc-5.3.1 (C) 2000-2016 MPlayer Team Playing http://bbcwssc.ic.llnwd.net/stream/bbcwssc_mp1_ws-einws. Resolving bbcwssc.ic.llnwd.net for AF_INET6... Couldn't resolve name for AF_INET6: bbcwssc.ic.llnwd.net Resolving bbcwssc.ic.llnwd.net for AF_INET... Connecting to server bbcwssc.ic.llnwd.net[68.142.121.109]: 80... Name : bbc_world_service_news_internet Cache size set to 320 KBytes Cache fill: 0.00% (0 bytes) ICY Info: StreamTitle=''; Cache fill: 15.00% (49152 bytes) Audio only file format detected. ========================================================================== Opening audio decoder: [mpg123] MPEG 1.0/2.0/2.5 layers I, II, III AUDIO: 44100 Hz, 2 ch, s16le, 56.0 kbit/3.97% (ratio: 7000->176400) Selected audio codec: [mpg123] afm: mpg123 (MPEG 1.0/2.0/2.5 layers I, II, III) ========================================================================== AO: [pulse] 44100Hz 2ch s16le (2 bytes per sample) Video: no video Starting playback... pause pause quit Exiting... (Quit) The two pauses and the quit are my typed commands echoed in the output. Has anyone tried anything like this? Best regards, --Jeff |
From: Douglas K. <do...@go...> - 2017-10-30 21:56:38
|
I didn't follow everything you said, but I do see two problems: (1) "\n" isn't an escape sequence to generate a newline in Lisp (2) you probably need to force output to the control stream |
From: Jeff C. <je...@jk...> - 2017-10-30 22:07:16
|
I tried the following: (with and without the newline) (defun pause-slave () (princ "pause" (sb-ext:process-input process)) (princ #\newline (sb-ext:process-input process)) (force-output (sb-ext:process-input process))) And that didn't work either. How would you send a command analogous to typing one in the xterm and pressing the Return key? --Jeff On 10/30/2017 02:56 PM, Douglas Katzman wrote: > I didn't follow everything you said, but I do see two problems: > (1) "\n" isn't an escape sequence to generate a newline in Lisp > (2) you probably need to force output to the control stream > |
From: Stas B. <sta...@gm...> - 2017-10-30 22:12:31
|
On Tue, Oct 31, 2017 at 12:54 AM Jeff Cunningham <je...@jk...> wrote: > I'm having some trouble getting sb-ext:run-program to behave the way it is > documented. I'm probably doing something wrong. I've put together a simple > case that illustrates. What I'm trying to do is start an external slave > process that can be controlled through the :input :stream option in > run-program. My understanding is that so long as I set :wait nil > run-program will launch the process and return the process structure which > it seems to do. Then I should be able to send commands to the process by > writing to sb-ext:process-input. The documentation I am following comes > from here: > > > https://www.common-lisp.net/project/cmucl/doc/cmu-user/extensions.html#@funs52 > You are using documentation for a different implementation? |
From: Jeff C. <je...@jk...> - 2017-10-30 22:16:27
|
For the details about the PROCESS structure, yes. Near the top of the doc-string for run-program it says this: RUN-PROGRAM will return a PROCESS structure. See the CMU Common Lisp Users Manual for details about the PROCESS structure. A little further down it says this: :INPUT Either T, NIL, a pathname, a stream, or :STREAM. If T, the standard input for the current process is inherited. If NIL, /dev/null is used. If a pathname, the file so specified is used. If a stream, all the input is read from that stream and sent to the subprocess. If :STREAM, the PROCESS-INPUT slot is filled in with a stream that sends its output to the process. Defaults to NIL. --Jeff On 10/30/2017 03:12 PM, Stas Boukarev wrote: > > > On Tue, Oct 31, 2017 at 12:54 AM Jeff Cunningham > <je...@jk... <mailto:je...@jk...>> wrote: > > I'm having some trouble getting sb-ext:run-program to behave the > way it is documented. I'm probably doing something wrong. I've put > together a simple case that illustrates. What I'm trying to do is > start an external slave process that can be controlled through the > :input :stream option in run-program. My understanding is that so > long as I set :wait nil run-program will launch the process and > return the process structure which it seems to do. Then I should > be able to send commands to the process by writing to > sb-ext:process-input. The documentation I am following comes from > here: > > https://www.common-lisp.net/project/cmucl/doc/cmu-user/extensions.html#@funs52 > > You are using documentation for a different implementation? |
From: Cyrus H. <ch...@bo...> - 2017-10-30 22:16:52
|
To be fair, our documentation says "See the cmu Common Lisp Users Manual for details about the process structure." On 10/30/17 3:12 PM, Stas Boukarev wrote: > > > On Tue, Oct 31, 2017 at 12:54 AM Jeff Cunningham > <je...@jk... <mailto:je...@jk...>> wrote: > > I'm having some trouble getting sb-ext:run-program to behave the > way it is documented. I'm probably doing something wrong. I've put > together a simple case that illustrates. What I'm trying to do is > start an external slave process that can be controlled through the > :input :stream option in run-program. My understanding is that so > long as I set :wait nil run-program will launch the process and > return the process structure which it seems to do. Then I should > be able to send commands to the process by writing to > sb-ext:process-input. The documentation I am following comes from > here: > > https://www.common-lisp.net/project/cmucl/doc/cmu-user/extensions.html#@funs52 > > You are using documentation for a different implementation? > > ------------------------------------------------------------------------------ > Check out the vibrant tech community on one of the world's most > engaging tech sites, Slashdot.org! http://sdm.link/slashdot > > _______________________________________________ > Sbcl-devel mailing list > Sbc...@li... > https://lists.sourceforge.net/lists/listinfo/sbcl-devel |
From: Stas B. <sta...@gm...> - 2017-10-30 22:30:57
|
That's a failure of our documentation... On Tue, Oct 31, 2017 at 1:17 AM Cyrus Harmon <ch...@bo...> wrote: > To be fair, our documentation says "See the cmu Common Lisp Users Manual > for details about the process structure." > On 10/30/17 3:12 PM, Stas Boukarev wrote: > > > > On Tue, Oct 31, 2017 at 12:54 AM Jeff Cunningham <je...@jk...> > wrote: > >> I'm having some trouble getting sb-ext:run-program to behave the way it >> is documented. I'm probably doing something wrong. I've put together a >> simple case that illustrates. What I'm trying to do is start an external >> slave process that can be controlled through the :input :stream option in >> run-program. My understanding is that so long as I set :wait nil >> run-program will launch the process and return the process structure which >> it seems to do. Then I should be able to send commands to the process by >> writing to sb-ext:process-input. The documentation I am following comes >> from here: >> >> >> https://www.common-lisp.net/project/cmucl/doc/cmu-user/extensions.html#@funs52 >> > You are using documentation for a different implementation? > > ------------------------------------------------------------------------------ > Check out the vibrant tech community on one of the world's most > engaging tech sites, Slashdot.org! http://sdm.link/slashdot > > > _______________________________________________ > Sbcl-devel mailing lis...@li...https://lists.sourceforge.net/lists/listinfo/sbcl-devel > > > ------------------------------------------------------------------------------ > Check out the vibrant tech community on one of the world's most > engaging tech sites, Slashdot.org! http://sdm.link/slashdot > _______________________________________________ > Sbcl-devel mailing list > Sbc...@li... > https://lists.sourceforge.net/lists/listinfo/sbcl-devel > |
From: Stas B. <sta...@gm...> - 2017-10-30 22:41:46
|
The ouput stream won't automatically be filled, you'll have to call sb-sys:serve-all-events. Better to manually read from a stream created with :output :stream. On Tue, Oct 31, 2017 at 12:54 AM Jeff Cunningham <je...@jk...> wrote: > I'm having some trouble getting sb-ext:run-program to behave the way it is > documented. I'm probably doing something wrong. I've put together a simple > case that illustrates. What I'm trying to do is start an external slave > process that can be controlled through the :input :stream option in > run-program. My understanding is that so long as I set :wait nil > run-program will launch the process and return the process structure which > it seems to do. Then I should be able to send commands to the process by > writing to sb-ext:process-input. The documentation I am following comes > from here: > > > https://www.common-lisp.net/project/cmucl/doc/cmu-user/extensions.html#@funs52 > > which is where the internal doc string on sb-ext:run-program says to look. > In particular, it says: > > * If specified as :stream, then the process-input slot* > * contains an output stream. Anything written to this stream goes* > * to the program as input. :input may also be an input stream* > * that already contains all the input for the process. In this* > * case run-program reads all the input from this stream before* > * returning, so this cannot be used to interact with the process.* > > Mplayer can operate as a slave like this using the "-slave" flag. Here's > the code I'm using to try to do this: > > (let* ((ostring) > (ostream) > (process)) > > (defun start-slave-process (&rest args) > (setf ostring (make-array '(0) :element-type 'character :fill-pointer > 0 :adjustable t) > ostream (sb-impl::make-fill-pointer-output-stream ostring) > process (sb-ext:run-program "/usr/bin/mplayer" args :input > :stream :output ostream :wait nil))) > > (defun pause-slave () (format (sb-ext:process-input process) "pause\n")) > (defun quit-slave () > (format (sb-ext:process-input process) "quit\n") > (sb-ext:process-kill process 15)) > (defun close-ostream () (close ostream)) > (defun get-process () process) > (defun get-ostring () ostring)) > > So I start the process: > (start-slave-process "-slave" "-quiet" > "http://bbcwssc.ic.llnwd.net/stream/bbcwssc_mp1_ws-einws" > <http://bbcwssc.ic.llnwd.net/stream/bbcwssc_mp1_ws-einws>) > > Streaming media is playing (for me) at this point. And it has returned > what looks like a valid process structure: > (print (get-process)) ;; ==> #<SB-IMPL::PROCESS 29225 :RUNNING> > > But the output isn't showing up: > (print (get-ostring)) ;; ==> "" > > And I can't control the process through the stream command pause-slave. > This should toggle the stream paused and un-paused: > > (pause-slave) ;; ==> does nothing > > The the write part of the quit-slave function doesn't work. The > process-kill does work. > (quit-slave) ;; ==> this actually works, but because of the kill process > > And the output string remains empty. I thought it might flush through at > this point once the process terminated, but it does not. > > Running the same process from an xterm looks like this: > > $ mplayer -slave -quiet > http://bbcwssc.ic.llnwd.net/stream/bbcwssc_mp1_ws-einws > MPlayer 1.2.1 (Debian), built with gcc-5.3.1 (C) 2000-2016 MPlayer Team > > Playing http://bbcwssc.ic.llnwd.net/stream/bbcwssc_mp1_ws-einws. > Resolving bbcwssc.ic.llnwd.net for AF_INET6... > > Couldn't resolve name for AF_INET6: bbcwssc.ic.llnwd.net > Resolving bbcwssc.ic.llnwd.net for AF_INET... > Connecting to server bbcwssc.ic.llnwd.net[68.142.121.109]: 80... > > Name : bbc_world_service_news_internet > Cache size set to 320 KBytes > Cache fill: 0.00% (0 bytes) > ICY Info: StreamTitle=''; > Cache fill: 15.00% (49152 bytes) > > Audio only file format detected. > ========================================================================== > Opening audio decoder: [mpg123] MPEG 1.0/2.0/2.5 layers I, II, III > AUDIO: 44100 Hz, 2 ch, s16le, 56.0 kbit/3.97% (ratio: 7000->176400) > Selected audio codec: [mpg123] afm: mpg123 (MPEG 1.0/2.0/2.5 layers I, II, > III) > ========================================================================== > AO: [pulse] 44100Hz 2ch s16le (2 bytes per sample) > Video: no video > Starting playback... > > pause > pause > quit > > Exiting... (Quit) > > The two pauses and the quit are my typed commands echoed in the output. > > Has anyone tried anything like this? > > Best regards, > --Jeff > > > > ------------------------------------------------------------------------------ > Check out the vibrant tech community on one of the world's most > engaging tech sites, Slashdot.org! http://sdm.link/slashdot > _______________________________________________ > Sbcl-devel mailing list > Sbc...@li... > https://lists.sourceforge.net/lists/listinfo/sbcl-devel > |
From: Jeff C. <je...@jk...> - 2017-10-31 02:29:17
|
I made a little headway with that idea. Couldn't get sb-sys:server-all-events to affect anything, but using :output :stream and reading it manually with a read-line loop will read all the output. However I am still unable to control the slave process. Writing to :input :stream doesn't seem to be passing the strings to the slave process. I've tried terminating with #\newline and FORCE-OUTPUT. Here's what describe says about the :input :stream #<SB-SYS:FD-STREAM for "descriptor 16" {1002182ED3}> [stream] Slots with :INSTANCE allocation: IN-BUFFER = NIL CIN-BUFFER = NIL IN-INDEX = 512 IN = #<FUNCTION SB-KERNEL:ILL-IN> BIN = #<FUNCTION SB-KERNEL:ILL-BIN> N-BIN = #<FUNCTION SB-KERNEL:ILL-BIN> OUT = #<FUNCTION SB-IMPL::OUTPUT-CHAR-UTF-8-FULL-BUFFERED> BOUT = #<FUNCTION SB-IMPL::OUTPUT-UNSIGNED-BYTE-FULL-BUFFERED> SOUT = #<FUNCTION SB-IMPL::FD-SOUT> MISC = #<FUNCTION SB-IMPL::FD-STREAM-MISC-ROUTINE> INPUT-CHAR-POS = NIL NAME = "descriptor 16" FILE = NIL ORIGINAL = NIL DELETE-ORIGINAL = NIL ELEMENT-SIZE = 1 ELEMENT-TYPE = CHARACTER ELEMENT-MODE = :BIVALENT FD = 16 FD-TYPE = :FIFO BUFFERING = :FULL DUAL-CHANNEL-P = NIL OUTPUT-COLUMN = 15 LISTEN = NIL SERVE-EVENTS = NIL INSTEAD = "" IBUF = NIL EOF-FORCED-P = NIL OBUF = #S(SB-IMPL::BUFFER.. OUTPUT-QUEUE = NIL HANDLER = NIL TIMEOUT = NIL PATHNAME = NIL EXTERNAL-FORMAT = :UTF-8 CHAR-SIZE = #<FUNCTION SB-IMPL::BYTES-FOR-CHAR/UTF-8> OUTPUT-BYTES = #<FUNCTION SB-IMPL::OUTPUT-BYTES/UTF-8> --Jeff On 10/30/2017 03:41 PM, Stas Boukarev wrote: > The ouput stream won't automatically be filled, you'll have to call > sb-sys:serve-all-events. Better to manually read from a stream created > with :output :stream. > |
From: Jeff C. <je...@jk...> - 2017-10-31 05:02:22
|
Solved the control problem by switching to :pty T and working with the bi-directional stream. Funny that :input doesn't seem to work, but at least pty does. Thanks for the help. --Jeff On 10/30/2017 07:29 PM, Jeff Cunningham wrote: > I made a little headway with that idea. Couldn't get > sb-sys:server-all-events to affect anything, but using :output > :stream and reading it manually with a read-line loop will read all > the output. > However I am still unable to control the slave process. Writing to > :input :stream doesn't seem to be passing the strings to the slave > process. I've tried terminating with #\newline and FORCE-OUTPUT. > Here's what describe says about the :input :stream > > <snip irrelevant stuff> > > > --Jeff > > > On 10/30/2017 03:41 PM, Stas Boukarev wrote: >> The ouput stream won't automatically be filled, you'll have to call >> sb-sys:serve-all-events. Better to manually read from a stream >> created with :output :stream. >> > > > ------------------------------------------------------------------------------ > > Check out the vibrant tech community on one of the world's most > engaging tech sites, Slashdot.org! http://sdm.link/slashdot > _______________________________________________ > Sbcl-devel mailing list > Sbc...@li... > https://lists.sourceforge.net/lists/listinfo/sbcl-devel |