2017-10-20 98 views
0

我试图从python使用ffmpeg。我需要执行的命令是:python中的子进程命令行中没有反斜杠的引号

ffmpeg -i test_file-1kB.mp4 -i test_file.mp4 -filter_complex psnr="stats_file=test_file.mp4-1kB.psnr" -f null - 

然而,我的输出,这是获得传递给子看起来是用反斜杠转义双引号,像这样:

In[1]: print(subprocess.list2cmdline(psnr_args)) 
ffmpeg -i test_file-1kB.mp4 -i test_file.mp4 -filter_complex psnr=\"stats_file=test_file.mp4-1kB.psnr\" -f null - 

要使用子,我将我的命令行参数逐个构建到列表中,然后将列表传递给子进程。

psnr_args = [] 
    psnr_args.append("ffmpeg") 

    #add first input, the encoded video 
    psnr_args.append("-i") 
    psnr_args.append(full_output_file_name) 

    #add second input, the original video 
    psnr_args.append("-i") 
    psnr_args.append(video_file) 

    #Setup the psnr log file 
    psnr_args.append("-filter_complex") 
    psnr_args.append('psnr="stats_file=%s.psnr"' % vstats_abs_filename) 

    #Output the video to null 
    psnr_args.append("-f") 
    psnr_args.append("null") 
    psnr_args.append("-") 
    print(subprocess.list2cmdline(psnr_args)) 
    run_info_psnr = subprocess.run(psnr_args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) 
+1

引号是**的指令**,而不是ffmpeg。如果你没有shell,你不应该有文字引号。把它们留下。 –

回答

0

经过更多的捣鼓,我找到了一个解决方案,在这种情况下,但可能无法在所有情况下工作。如果我使用双引号作为外引号,并使用单引号作为内引号,则子进程的输出在同一位置使用单引号且不带反斜线。这是ffmpeg可以接受的。但是,对于双引号是唯一解决方案的其他人来说,这不会是一个解决方案。

psnr_args.append("psnr='stats_file=%s.psnr'" % vstats_abs_filename) 

输出到子看起来是这样的:

In[1]: print(subprocess.list2cmdline(psnr_args)) 
ffmpeg -i test_file-1kB.mp4 -i test_file.mp4 -filter_complex psnr='stats_file=test_file.mp4-1kB.psnr' -f null - 
+0

'list2cmdline'是一个Windows主机。如果你想以一种对Unix系列系统有意义的方式将列表转换为命令行,可以在Python 2中使用'''.join(pss.rgs)中的.join(x的管道.quote(x))'或者' shlex.quote'替换Python 3中的'pipes.quote'。 –

+0

简单引号在windows中没有特别的含义。 –

+0

@ Jean-FrançoisFabre,(1)true。 (2)是否是针对我的? –

1

在外壳的说法:

psnr="stats_file=test_file.mp4-1kB.psnr" 

绝对相同

psnr=stats_file=test_file.mp4-1kB.psnr 

在shell自己的处理过程中删除了引号。他们是而不是命令的一部分传递给ffmpeg,这并不指望或理解它们。由于您直接告诉Python子进程模块调用文字参数向量,因此不涉及shell,因此shell语法不应存在。

0

这也与ffmpeg AV过滤器链语法有关。您需要运行命令如xxxx -filter_complex "psnr='stats.txt'" xxxx。为了得到这个,你应该确保封装过滤器链的双引号到达里面。子处理器需要一个扁平列表作为第一个参数,其中该命令是第一个条目。所以['ffmpeg', '-i', "t1.mp4", "-filter_compelx", '"psnr=\'stats.txt\'"', .... and so on ]