2014-09-21 92 views
2

我尝试使用Popen执行ffmpeg命令时出现了一个奇怪的问题。 我有下面一段代码,我使用了Python中执行一个外部命令:使用Popen执行ffmpeg命令

from subprocess import Popen, PIPE 
from datetime import datetime 


class Executor(object): 

    @classmethod 
    def execute(cls, command): 
     """ 
     Executing a given command and 
     writing into a log file in cases where errors arise. 
     """ 
     p = Popen(command, stdin=PIPE, stdout=PIPE, stderr=PIPE) 
     output, err = p.communicate() 
     if p.returncode: 
      with open("failed_commands.log", 'a') as log: 
       now = datetime.now() 
       log.write('{}/{}/{} , {}:{}:{}\n\n'.format(now.day, now.month, 
                  now.year, now.hour, 
                  now.minute, 
                  now.second)) 

       log.write("COMMAND:\n{}\n\n".format(" ".join(command))) 
       log.write("OUTPUT:\n{}\n\n".format(output.decode("utf-8"))) 
       log.write("ERRORS:\n{}\n".format(err.decode("utf-8"))) 
       log.write('-'*40) 
       log.write('\n') 

      return '' 

     if not output: 
      output += ' ' 

     return output 

我与他人的命令测试它,但是当我尝试执行ffmpeg命令 - 它失败。 我试图将一些音频格式转换为mp3格式。 这里是我的命令的例子:

ffmpeg -i "/path/old_song.m4a" "/path/new_song.mp3" 

...简单that.When我在它工作正常终端中运行它,但是当我尝试使用它没有上述功能来执行它。 这里是确切的错误:

---------------------------------------- 
21/9/2014 , 19:48:50 

COMMAND: 
ffmpeg -i "/path/old_song.m4a" "/path/new_song.mp3" 

OUTPUT: 


ERRORS: 
ffmpeg version 2.2.3 Copyright (c) 2000-2014 the FFmpeg developers 
    built on Jun 9 2014 08:01:43 with gcc 4.9.0 (GCC) 20140521 (prerelease) 
    configuration: --prefix=/usr --disable-debug --disable-static --enable-avisynth --enable-avresample --enable-dxva2 --enable-fontconfig --enable-gnutls --enable-gpl --enable-libass --enable-libbluray --enable-libfreetype --enable-libgsm --enable-libmodplug --enable-libmp3lame --enable-libopencore_amrnb --enable-libopencore_amrwb --enable-libopenjpeg --enable-libopus --enable-libpulse --enable-librtmp --enable-libschroedinger --enable-libspeex --enable-libtheora --enable-libv4l2 --enable-libvorbis --enable-libvpx --enable-libx264 --enable-libx265 --enable-libxvid --enable-pic --enable-postproc --enable-runtime-cpudetect --enable-shared --enable-swresample --enable-vdpau --enable-version3 --enable-x11grab 
    libavutil  52. 66.100/52. 66.100 
    libavcodec  55. 52.102/55. 52.102 
    libavformat 55. 33.100/55. 33.100 
    libavdevice 55. 10.100/55. 10.100 
    libavfilter  4. 2.100/4. 2.100 
    libavresample 1. 2. 0/1. 2. 0 
    libswscale  2. 5.102/2. 5.102 
    libswresample 0. 18.100/0. 18.100 
    libpostproc 52. 3.100/52. 3.100 
"/path/old_song.m4a": No such file or directory 
Conversion failed! 

---------------------------------------- 

...和你能想到的 - 该文件存在。

我认为在将命令传递给Popen.communicate时有一些东西,但我不完全清楚。

亲切的问候,

特奥多尔D. PS:我将命令传递给Executor.execute as Python列表。

PSS:调用Executor.execute

def process_conversion(self): 
    for song in self.files_to_convert: 
     current_format = song.rsplit('.', 1)[-1] 

     old_file = '"{}{}{}"'.format(self.target_dir, os.sep, song) 
     new_file = '"{}{}{}"'.format(self.target_dir, os.sep, 
            song.replace(current_format, 'mp3')) 

     command = ["ffmpeg", "-i", old_file, new_file] 
     Executor.execute(command) 
+2

您遗漏了一条关键信息:确切地调用Executor.execute来产生该输出。 – chepner 2014-09-21 17:51:02

+0

此输出来自failed_commands.log文件。换句话说,输出在“ERRORS:”之后。 – dragonator 2014-09-21 18:46:39

回答

2

的问题是要包括在文件名的双引号。改为:

old_file = '{}{}{}'.format(self.target_dir, os.sep, song) 
+0

我可以发誓,我已经尝试过,但它没有奏效。但是我猜想在此之后我已经改变了一些东西。只是为了让我的事情更清楚 - 双引号是nessecery只在终端使用告诉解释,以下东西是单个参数(如果它包含空格)? – dragonator 2014-09-21 20:10:15

+1

正确; shell使用空格来分隔字符串中的参数;报价保护封闭的空间。 Python不必将单个字符串解析为参数列表;你只需使用一个'list'对象。 – chepner 2014-09-21 20:15:43