1

I am outputting

parec -d "name"

You don't need to know this command, just know that as soon as you press enter, it outputs binary data representing audio.

My goal is to read this with python in real time, ie start it and have it in a variable "data" I can read from with something like

data = p.stdout.read()

What I tried

p = subprocess.Popen(['parec','-d','"name"'],stdout=subprocess.PIPE,shell=True)

while True:
   data = p.stdout.read()

But this results in no data being received.

parec -d "name" > result.raw

is readable with an audio-programme and contains exactly the necessary data. So what is the command for python?

Brutus Cruciatus
  • 404
  • 3
  • 18
  • 1
    you should not need the `while True` also maybe pass it the `stderr=subprocess.PIPE` as well ... maybe you are getting an error – Joran Beasley May 19 '13 at 23:42
  • How long have you waited? The pipe is likely buffered, and when you're not in the context of a terminal, flushing may be (much) less regular than you're used to. – sapi May 19 '13 at 23:47
  • @JoranBeasley the reason for while is that it should read data as soon as it is being passed through to repeat this process. Maybe there's a lock somewhere to wait till parec is finished? – Brutus Cruciatus May 19 '13 at 23:49
  • yes read will wait for process exit ... it blocks ... no need for while – Joran Beasley May 19 '13 at 23:50
  • @sapi I need it to be outputted immediately. – Brutus Cruciatus May 19 '13 at 23:50

2 Answers2

0

when you call read() on subprocess.PIPE I believe it will block until parec exits

Im pretty sure that this solution should not block :)

Found a Solution

from subprocess import Popen, PIPE, STDOUT

p = Popen('c:/python26/python printingTest.py', stdout = PIPE, 
        stderr = PIPE)
for line in iter(p.stdout.readline, ''):
    print line
p.stdout.close()

It took alot of searching but this solution can be found @ Getting realtime output using subprocess

Community
  • 1
  • 1
Joran Beasley
  • 110,522
  • 12
  • 160
  • 179
0

You should not use p.stdout.read() (this waits for all data) nor p.stdout.readline() (this reads one "line" of data, which makes little sense if it's binary). Instead, you can use p.stdout.read(4096) for example, which will wait until 4096 bytes are there and return them.

There is no way using methods on the file object to read "everything available so far", but there is a way if you go to the lower-level file handle:

data = os.read(p.stdout.fileno(), 4096)

This will wait until there is at least one byte to read, but then return all available bytes, up to a maximum length of 4096.

The number 4096 in my examples is a bit arbitrary. You can also use larger values if data comes in quickly.

Armin Rigo
  • 12,048
  • 37
  • 48