2014-09-21 119 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