Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #8523

Re: Trying to chain processes together on a pipeline

Path csiph.com!x330-a1.tempe.blueboxinc.net!usenet.pasdenom.info!aioe.org!feeder.news-service.com!newsfeed.xs4all.nl!newsfeed6.news.xs4all.nl!xs4all!newsgate.cistron.nl!newsgate.news.xs4all.nl!post.news.xs4all.nl!not-for-mail
Return-Path <python-python-list@m.gmane.org>
X-Original-To python-list@python.org
Delivered-To python-list@mail.python.org
X-Spam-Status OK 0.000
X-Spam-Evidence '*H*': 1.00; '*S*': 0.00; 'else:': 0.03; 'python.': 0.04; 'elif': 0.04; 'thread,': 0.04; '-if': 0.05; 'encoded': 0.05; 'chunk': 0.07; 'complaining': 0.07; 'raises': 0.07; 'python': 0.08; "(it's": 0.09; 'attribute': 0.09; 'bash': 0.09; 'encoder': 0.09; 'exception:': 0.09; 'received:80.91': 0.09; 'received:80.91.229': 0.09; 'received:80.91.229.12': 0.09; 'received:gmane.org': 0.09; 'received:list': 0.09; 'received:lo.gmane.org': 0.09; 'subprocess': 0.09; 'writable': 0.09; 'output': 0.11; 'exception': 0.12; 'win32': 0.12; 'skip:f 30': 0.13; 'wrote:': 0.15; '(moving': 0.16; '193': 0.16; '__init__': 0.16; 'bash,': 0.16; 'c2pwrite': 0.16; 'encoders': 0.16; 'errread,': 0.16; 'errwrite': 0.16; 'failure.': 0.16; 'msvcrt': 0.16; 'received:dip.t-dialin.net': 0.16; 'received:t-dialin.net': 0.16; 'stderr': 0.16; 'subject:Trying': 0.16; 'holds': 0.16; '>>>': 0.16; 'repeated': 0.19; 'string,': 0.19; 'yet.': 0.19; 'command': 0.19; "haven't": 0.21; 'input': 0.21; '(most': 0.21; 'skip:m 30': 0.21; 'loop': 0.22; 'trying': 0.23; 'code': 0.24; 'traceback': 0.25; 'windows': 0.27; "i'm": 0.27; 'right,': 0.28; 'skip:" 30': 0.28; 'script': 0.29; 'object': 0.30; 'module': 0.30; '-of': 0.30; 'blocks': 0.30; 'decorators': 0.30; 'from:addr:web.de': 0.30; 'nested': 0.30; 'andrew': 0.32; 'earlier': 0.32; 'used,': 0.32; 'error': 0.33; 'break': 0.33; 'ideal': 0.33; 'header:X-Complaints-To:1': 0.34; 'there': 0.34; 'points': 0.34; 'to:addr:python-list': 0.34; 'clearly': 0.35; 'assignment': 0.35; 'function.': 0.35; 'identical': 0.35; 'last):': 0.35; 'skip:" 50': 0.35; 'try:': 0.35; 'pretty': 0.35; "isn't": 0.35; 'options': 0.36; 'file': 0.36; 'skip:" 10': 0.36; 'idea': 0.36; 'option': 0.37; 'but': 0.37; 'some': 0.37; 'using': 0.38; 'received:org': 0.38; 'subject:: ': 0.38; 'else': 0.38; 'put': 0.38; 'common': 0.39; 'header:Mime-Version:1': 0.39; 'to:addr:python.org': 0.39; "there's": 0.39; 'skip:s 20': 0.40; 'where': 0.40; 'give': 0.60; 'note:': 0.68; 'safe': 0.70; 'learned': 0.73; 'wav': 0.84
X-Injected-Via-Gmane http://gmane.org/
To python-list@python.org
From Peter Otten <__peter__@web.de>
Subject Re: Trying to chain processes together on a pipeline
Date Tue, 28 Jun 2011 08:32:35 +0200
Organization None
References <4E096D3B.3080300@gmail.com>
Mime-Version 1.0
Content-Type text/plain; charset="ISO-8859-1"
Content-Transfer-Encoding 7Bit
X-Gmane-NNTP-Posting-Host p50849ff0.dip.t-dialin.net
X-BeenThere python-list@python.org
X-Mailman-Version 2.1.12
Precedence list
List-Id General discussion list for the Python programming language <python-list.python.org>
List-Unsubscribe <http://mail.python.org/mailman/options/python-list>, <mailto:python-list-request@python.org?subject=unsubscribe>
List-Archive <http://mail.python.org/pipermail/python-list>
List-Post <mailto:python-list@python.org>
List-Help <mailto:python-list-request@python.org?subject=help>
List-Subscribe <http://mail.python.org/mailman/listinfo/python-list>, <mailto:python-list-request@python.org?subject=subscribe>
Newsgroups comp.lang.python
Message-ID <mailman.470.1309242751.1164.python-list@python.org> (permalink)
Lines 132
NNTP-Posting-Host 2001:888:2000:d::a6
X-Trace 1309242751 news6.xs4all.nl 4366 [2001:888:2000:d::a6]:54490
X-Complaints-To abuse@xs4all.nl
Xref x330-a1.tempe.blueboxinc.net comp.lang.python:8523

Show key headers only | View raw


Andrew Berg wrote:

> I'm working on an audio/video converter script (moving from bash to
> Python for some extra functionality), and part of it is chaining the
> audio decoder (FFmpeg) either into SoX to change the volume and then to
> the Nero AAC encoder or directly into the Nero encoder. This is the
> chunk of code from my working bash script to give an idea of what I'm
> trying to accomplish (it's indented because it's nested inside a while
> loop and an if statement):
>>         if [ "$process_audio" = "true" ]
>>         then
>>             if [ $vol == 1.0 ]
>>             then
>>                 ffmpeg -i "${ifile_a}" -f wav - 2>$nul | neroaacenc
>> -ignorelength -q 0.4 -if - -of ${prefix}${zero}${ep}.m4a
>>             else
>>                 # the pipeline-as-file option of sox fails on Windows
>> 7, so I use the safe method since there's only one pipeline going into
>> sox
>>                 ffmpeg -i "${ifile_a}" -f sox - 2>$nul | sox -t sox -
>> -t wav - vol $vol 2>$nul | neroaacenc -ignorelength -q 0.4 -if - -of
>> ${prefix}${zero}${ep}.m4a
>>             fi
>>         else
>>             echo "Audio skipped."
>>         fi
> This is pretty easy and straightforward in bash, but not so in Python.
> This is what I have in Python (queue[position] points to an object I
> create earlier that holds a bunch of info on what needs to be encoded -
> input and output file names, command line options for the various
> encoders used, and so forth), but clearly it has some problems:
>>     try:
>>         ffmpeg_proc = subprocess.Popen(queue[position].ffmpeg_cmd,
>> stdout=subprocess.PIPE, stderr=os.devnull)
>>     except WindowsError:
>>         error_info = str(sys.exc_info()[1])
>>         last_win_error_num = find_win_error_no(error_msg=error_info)
>>         if last_win_error_num == '2': # Error 2 = 'The system cannot
>> find the file specified'
>>             logger.critical('Could not execute ' +
>> queue[position].ffmpeg_exe + ': File not found.')
>>         elif last_win_error_num == '193': # Error 193 = '%1 is not a
>> valid Win32 application'
>>             logger.critical('Could not execute ' +
>> queue[position].ffmpeg_exe + ': It\'s not a valid Win32 application.')
>>         break
>>     if queue[position].vol != 1:
>>         try:
>>             sox_proc = subprocess.Popen(queue[position].sox_cmd,
>> stdin=ffmpeg_proc.stdout, stdout=subprocess.PIPE, stderr=os.devnull)
>>         except WindowsError:
>>             error_info = str(sys.exc_info()[1])
>>             last_win_error_num = find_win_error_no(error_msg=error_info)
>>             if last_win_error_num == '2': # Error 2 = 'The system
>> cannot find the file specified'
>>                 logger.critical('Could not execute ' +
>> queue[position].sox_exe + ': File not found.')
>>             elif last_win_error_num == '193': # Error 193 = '%1 is not
>> a valid Win32 application'
>>                 logger.critical('Could not execute ' +
>> queue[position].sox_exe + ': It\'s not a valid Win32 application.')
>>             break
>>         wav_pipe = sox_proc.stdout
>>     else:
>>         wav_pipe = ffmpeg_proc.stdout
>>     try:
>>         nero_aac_proc = subprocess.Popen(queue[position].nero_aac_cmd,
>> stdin=wav_pipe)
>>     except WindowsError:
>>         error_info = str(sys.exc_info()[1])
>>         last_win_error_num = find_win_error_no(error_msg=error_info)
>>         if last_win_error_num == '2': # Error 2 = 'The system cannot
>> find the file specified'
>>             logger.critical('Could not execute ' +
>> queue[position].sox_exe + ': File not found.')
>>         elif last_win_error_num == '193': # Error 193 = '%1 is not a
>> valid Win32 application'
>>             logger.critical('Could not execute ' +
>> queue[position].sox_exe + ': It\'s not a valid Win32 application.')
>>         break
>>     
>>     ffmpeg_proc.wait()
>>     if queue[position].vol != 1:
>>         sox_proc.wait()
>>     nero_aac_proc.wait()
>>     break
> Note: those break statements are there to break out of the while loop
> this is in.
> Firstly, that first assignment to ffmpeg_proc raises an exception:
>> Traceback (most recent call last):
>>   File "C:\Users\Bahamut\workspace\Disillusion\disillusion.py", line
>> 288, in <module>
>>     ffmpeg_proc = subprocess.Popen(queue[position].ffmpeg_cmd,
>> stdout=subprocess.PIPE, stderr=os.devnull)
>>   File "C:\Python32\lib\subprocess.py", line 700, in __init__
>>     errread, errwrite) = self._get_handles(stdin, stdout, stderr)
>>   File "C:\Python32\lib\subprocess.py", line 861, in _get_handles
>>     errwrite = msvcrt.get_osfhandle(stderr.fileno())
>> AttributeError: 'str' object has no attribute 'fileno'
> I'm not really sure what it's complaining about since the exception
> propagates from the msvcrt module through the subprocess module into my
> program. I'm thinking it has to do my stderr assignment, but if that's
> not right, I don't know what is.

os.devnull is a string, but you need a writable file:

>>> subprocess.call(["ls"], stdout=os.devnull)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.6/subprocess.py", line 470, in call
    return Popen(*popenargs, **kwargs).wait()
  File "/usr/lib/python2.6/subprocess.py", line 614, in __init__
    errread, errwrite) = self._get_handles(stdin, stdout, stderr)
  File "/usr/lib/python2.6/subprocess.py", line 971, in _get_handles
    c2pwrite = stdout.fileno()
AttributeError: 'str' object has no attribute 'fileno'
>>> subprocess.call(["ls"], stdout=open(os.devnull, "w"))
0

> Secondly, there are no Popen.stdout.close() calls because I'm not sure
> where to put them.
> Thirdly, I have nearly identical except WindowsError: blocks repeated -
> I'm sure I can avoid this with decorators as suggested in a recent
> thread, but I haven't learned decorators yet. This code isn't very
> complete; I'm trying to get it to work in ideal conditions first, then
> worry about how to handle failure.

Start with factoring out common code into a good old function.

> Using Python 3 on Windows 7.

Back to comp.lang.python | Previous | Next | Find similar | Unroll thread


Thread

Re: Trying to chain processes together on a pipeline Peter Otten <__peter__@web.de> - 2011-06-28 08:32 +0200

csiph-web