2016-01-20 43 views
0

使用下面的腳本時,我得到Unknown argument: |,我不確定它爲什麼不喜歡|。我在Windows上,與Python 2.7.11:Python Popen - 未知參數:|

import subprocess 
from subprocess import Popen, PIPE, STDOUT 
import time 

command = 'VSPipe.exe --y4m script.vpy - | ffmpeg.exe -f yuv4mpegpipe -i - -c:v prores -an output.mov' 

process1 = Popen(command, stderr=PIPE, shell=False) 

while True: 
    line = process1.stderr.readline().decode('utf-8') 
    print line 
    time.sleep(2) 

UPDATE: 使用建議下面我現在已經嘗試過這一點,但我正在逐漸pipe:: Operation not permitted。我究竟做錯了什麼?

import subprocess 
from subprocess import Popen, PIPE, STDOUT 
import time 

command1 = 'VSPipe.exe --y4m script.vpy -' 
command2 = 'ffmpeg.exe -f yuv4mpegpipe -i - -c:v prores -an output.mov' 

process1 = Popen(command1, stdout=PIPE) 
process2 = Popen(command2, stdin=process1.stdout, stderr=PIPE) 

print process2.communicate() 

另一個更新: 因此,使用下面的建議,並嘗試其他的東西,我一直得到相同的結果pipe:: Operation not permitted。下面是完整的sdterr,還有什麼我可以試試:

"F:/ffmpeg/VapourSynth/VSPipe.exe" --y4m "C:/Users/myself/Desktop/script.vpy" - 
"F:/ffmpeg/ffmpeg.exe" -f yuv4mpegpipe -i - -c:v prores -an -y "//192.168.0.100/media/temp/OutMov.mov" 
ffmpeg version N-77203-gb8e5b1d Copyright (c) 2000-2015 the FFmpeg developers 
    built with gcc 5.2.0 (GCC) 
    configuration: --arch=x86 --target-os=mingw32 --cross-prefix=/Users/myself/Desktop/Download/ffmpeg-windows-build-helpers-master/sandbox/mingw-w64-i686/bin/i686-w64-mingw32- --pkg-config=pkg-config --disable-w32threads --enable-gpl --enable-libsoxr --enable-fontconfig --enable-libass --enable-libutvideo --enable-libbluray --enable-iconv --enable-libtwolame --extra-cflags=-DLIBTWOLAME_STATIC --enable-libzvbi --enable-libcaca --enable-libmodplug --extra-libs=-lstdc++ --extra-libs=-lpng --enable-libvidstab --enable-libx265 --enable-decklink --extra-libs=-loleaut32 --enable-libx264 --enable-libxvid --enable-libmp3lame --enable-version3 --enable-zlib --enable-librtmp --enable-libvorbis --enable-libtheora --enable-libspeex --enable-libopenjpeg --enable-gnutls --enable-libgsm --enable-libfreetype --enable-libopus --enable-frei0r --enable-filter=frei0r --enable-libvo-aacenc --enable-bzlib --enable-libxavs --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libvo-amrwbenc --enable-libschroedinger --enable-libvpx --enable-libilbc --enable-libwavpack --enable-libwebp --enable-libgme --enable-dxva2 --enable-libdcadec --enable-avisynth --enable-gray --enable-libopenh264 --extra-libs=-lpsapi --extra-cflags= --enable-static --disable-shared --prefix=/Users/myself/Desktop/Download/ffmpeg-windows-build-helpers-master/sandbox/mingw-w64-i686/i686-w64-mingw32 --enable-nonfree --enable-libfdk-aac --disable-libfaac --enable-nvenc --enable-runtime-cpudetect 
    libavutil  55. 10.100/55. 10.100 
    libavcodec  57. 17.100/57. 17.100 
    libavformat 57. 19.100/57. 19.100 
    libavdevice 57. 0.100/57. 0.100 
    libavfilter  6. 20.100/6. 20.100 
    libswscale  4. 0.100/4. 0.100 
    libswresample 2. 0.101/2. 0.101 
    libpostproc 54. 0.100/54. 0.100 
pipe:: Operation not permitted 

UPDATE: 而她是ffmpeg的報告:

F:/ffmpeg/ffmpeg.exe -f yuv4mpegpipe -i - -c:v prores -an -y //192.168.0.100/media/temp/OutMov.mov -report 
ffmpeg version N-77203-gb8e5b1d Copyright (c) 2000-2015 the FFmpeg developers 
    built with gcc 5.2.0 (GCC) 
    configuration: --arch=x86 --target-os=mingw32 --cross-prefix=/Users/myself/Desktop/Download/ffmpeg-windows-build-helpers-master/sandbox/mingw-w64-i686/bin/i686-w64-mingw32- --pkg-config=pkg-config --disable-w32threads --enable-gpl --enable-libsoxr --enable-fontconfig --enable-libass --enable-libutvideo --enable-libbluray --enable-iconv --enable-libtwolame --extra-cflags=-DLIBTWOLAME_STATIC --enable-libzvbi --enable-libcaca --enable-libmodplug --extra-libs=-lstdc++ --extra-libs=-lpng --enable-libvidstab --enable-libx265 --enable-decklink --extra-libs=-loleaut32 --enable-libx264 --enable-libxvid --enable-libmp3lame --enable-version3 --enable-zlib --enable-librtmp --enable-libvorbis --enable-libtheora --enable-libspeex --enable-libopenjpeg --enable-gnutls --enable-libgsm --enable-libfreetype --enable-libopus --enable-frei0r --enable-filter=frei0r --enable-libvo-aacenc --enable-bzlib --enable-libxavs --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libvo-amrwbenc --enable-libschroedinger --enable-li libavutil  55. 10.100/55. 10.100 
    libavcodec  57. 17.100/57. 17.100 
    libavformat 57. 19.100/57. 19.100 
    libavdevice 57. 0.100/57. 0.100 
    libavfilter  6. 20.100/6. 20.100 
    libswscale  4. 0.100/4. 0.100 
    libswresample 2. 0.101/2. 0.101 
    libpostproc 54. 0.100/54. 0.100 
Splitting the commandline. 
Reading option '-f' ... matched as option 'f' (force format) with argument 'yuv4mpegpipe'. 
Reading option '-i' ... matched as input file with argument '-'. 
Reading option '-c:v' ... matched as option 'c' (codec name) with argument 'prores'. 
Reading option '-an' ... matched as option 'an' (disable audio) with argument '1'. 
Reading option '-y' ... matched as option 'y' (overwrite output files) with argument '1'. 
Reading option '//192.168.0.100/media/temp/OutMov.mov' ... matched as output file. 
Reading option '-report' ... matched as option 'report' (generate a report) with argument '1'. 
Finished splitting the commandline. 
Parsing a group of options: global . 
Applying option y (overwrite output files) with argument 1. 
Applying option report (generate a report) with argument 1. 
Successfully parsed a group of options. 
Parsing a group of options: input file -. 
Applying option f (force format) with argument yuv4mpegpipe. 
Successfully parsed a group of options. 
Opening an input file: -. 
[AVIOContext @ 006d9800] Statistics: 0 bytes read, 0 seeks 
pipe:: Operation not permitted 

UPDATE: 使用此代碼,我仍然得到同樣的結果pipe:: Operation not permitted

import subprocess 
import os 
from subprocess import Popen, PIPE, STDOUT 
import shlex 

VsPipe = 'F:/ffmpeg/VapourSynth/VSPipe.exe' 
vpyScript = 'C:/Users/myself/Desktop/Boychoir-preview_SMALL_JobID_189.vpy' 
ffmpeg = 'F:/ffmpeg/ffmpeg.exe' 
outputPath = '//192.168.0.100/media/temp/OutMov.mov' 

command1 = shlex.split('"%s" --y4m "%s" - ' % (VsPipe, vpyScript)) 
command2 = shlex.split('"%s" -f yuv4mpegpipe -i - -c:v prores -an -y "%s" -report' % (ffmpeg, outputPath)) 

process1 = subprocess.Popen(command1, stdout=subprocess.PIPE) 
ls_out, _ = process1.communicate() 
process2 = subprocess.Popen(command2, stdin=subprocess.PIPE, stderr=subprocess.PIPE) 

grep_out, grep_err = process2.communicate(input=ls_out) 
print grep_err 

UPDATE: 固定的,竟然是一個文件路徑權限問題,謝謝FO所有的幫助。

+0

不能使用 '|'在命令一起管道命令參考http://stackoverflow.com/questions/7389662/link-several-popen-commands-with-pipes。 –

+0

發現這個http://stackoverflow.com/questions/9356960/ffmpeg-operation-not-permitted-error-while-conversion –

+0

似乎沒有關係,但無論如何感謝。 – speedyrazor

回答

2

當您將shell設置爲False時,args(即第一個)參數應該是程序的名稱(如果它是字符串的話)。否則,它應該是一串字符串,第一個是程序,其餘的是參數。

使用管道時,外殼的重要性在於,在該行:

VSPipe.exe --y4m script.vpy - | ffmpeg.exe -f yuv4mpegpipe -i - -c:v prores -an output.mov 

都沒有考慮的參數。 VSPipe.exe的參數是--y4mscript.vpyffmpeg.exe的參數是-f,yuv4mpegpipe,-i等shell是什麼處理管道 - 它啓動兩個程序(提供他們的參數),但它通過首先創建一個管道,使stdout從第一個連接到stdin第二。

如果你沒有支持管道的shell,你可以通過啓動它們來模擬python,然後將輸出從第一個輸出到第二個。

0

從子docs

使用POPEN用,當你需要管道通信()方法。

大廈@ skyking的回答和更新的代碼,它看起來像你只需要使用通信():

# Simple Windows script to confirm existence of Desktop directory in users home space 
# ls -al | grep Desktop 
# This requires Windows Git to be installed for unix utils like ls, grep 

# NOTE: you may have problems with this if you're using built in Windows shell 
# utilities like dir etc.. This is because these are built into the shell and 
# aren't executables on your path. Use shell=True if you have to use these. 

import os 
import subprocess 

# Change to home directory 
os.chdir(os.path.expanduser("~")) 

# Command parameters sent to Popen initializer should be lists 
# Here we are only interested in the output so PIPE stdout 
ls_process = subprocess.Popen(['ls', '-al'], stdout=subprocess.PIPE) 

# When working with subprocess PIPE we need to use the communicate() method 
# We're only interested in stdout so _ is used to throw away stderr (which will be 
# None anyway since we didn't pipe stderr) 
ls_out, _ = ls_process.communicate() 

# We then create our second process but this time we're interested in piping the 
# first command into stdin, using stdout and potentially stderr if there was a problem 
grep_process = subprocess.Popen(['grep', 'Desktop'], 
            stdin=subprocess.PIPE, 
            stdout=subprocess.PIPE, 
            stderr=subprocess.PIPE) 

# We use communicate() again but this time we give the output string of the first command 
# as a parameter to communicate() 
grep_out, grep_err = grep_process.communicate(input=ls_out) 

print grep_out 

子過程是一個艱難的模塊來獲得正確的第一時間,我們很高興地看在其他項目中使用它的實例。

另一個好的提示是儘量保持平臺獨立的東西。即使你不打算在Windows以外的任何地方運行它,它也會幫助你避免你正在使用的系統的特性。

+0

我已經修改了這個問題來包含'print process2.communicate()',但是我仍然得到了'pipe :: Operation not allowed' – speedyrazor

+0

我已經更新了我的代碼,以顯示使用'communications()'方法。希望這可以幫助! – afunkyrobot

+0

對不起,同樣的結果,我已更新我的問題與另一個更新: – speedyrazor

0

首先,我會建議你到用戶完整路徑的所有.exe這裏我用來做到這一點的代碼。

import os 
import re 
import subprocess 
from subprocess import Popen, PIPE, STDOUT 
import shlex 

def _get_locate_command_result(bin_name, 
           which_command="which", default_path=""): 
    # check_output returns bytes for python3 and str for py2 
    try: 
     result_locate = subprocess.check_output(
      shlex.split("%s %s" % (which_command, bin_name)), env=os.environ) 
     result_locate_table = re.split(r"\r?\n", result_locate.decode()) 
     try: 
      bin_path = result_locate_table[0].strip() 
     except IndexError: 
      bin_path = bin_name 
     return bin_path 


    except subprocess.CalledProcessError: 
     return default_path 

對於Windows:

path = get_locate_command_result(bin_name, which_command="where", default_path=default_path) 

所以,你可以嘗試類似的東西(未測試):

# use "" beacause of '\' 
command1 = ('"%s" --y4m script.vpy -' 
      % _get_locate_command_result("VSPipe.exe", "where", "VSPipe.exe")) 
command2 = ('"%s" -f yuv4mpegpipe -i - -c:v prores -an output.mov' 
      % _get_locate_command_result("VSPipe.exe", "where", "ffmpeg.exe")) 

# Popen needs sequence of string 
cmd1 = shlex.split(command1) 
cmd2 = shlex.split(command2) 

process1 = Popen(cmd1, stdout=PIPE) 
process2 = Popen(cmd2, stdin=process1.stdout, stderr=PIPE) 

print(process2.communicate()) 
+0

我已經在我的代碼中使用完整路徑的所有.exe文件,爲了簡潔起見,我在這裏排除了它。假設腳本可以找到所有的exe和文件。此外,這僅適用於Windows。 – speedyrazor

+0

我應該使用shlex.split(cmd)來返回一串字符串。 –

+0

在shlex.split(cmd)中添加,但仍然使用相同的管道::不允許操作 – speedyrazor