2014-09-21 4 views
2

Popen을 사용하여 ffmpeg 명령을 실행하는 데 이상한 문제가 있습니다. 내가 파이썬에서 외부 명령을 실행하는 데 사용할 다음 코드 조각이 :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" 

... 희생자 였죠 간단 나는 그것이 잘 작동 터미널에서 실행,하지만 난 실패 위의 함수를 사용하여 실행하려고 할 때. 다음은 정확한 오류입니다 :

---------------------------------------- 
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에 전달할 때 뭔가가 있다고 생각하지만 정확하게 알지 못합니다.

종류와 관련,

Teodor 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

+0

이 출력은 failed_commands.log 파일에서 나옵니다. 즉, 출력은 "ERRORS :"다음에옵니다. – dragonator

답변

2

문제는 당신이 파일의 이름에 따옴표가 포함되어 있다는 점이다. 다음과 같이 대신 사용하십시오 :

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

나는 그것을 시도했지만 작동하지 않았다고 맹세 할 수있다. 그러나 그 후에 다른 것을 바꿨을 것 같다. 나를 위해 명확하게하기 위해서 - 이중 따옴표는 터미널 사용시에만 다음과 같이 해석한다. thing은 하나의 인수입니다 (공백이 포함 된 경우)? – dragonator

+1

정확함; 셸은 공백을 사용하여 문자열 내의 인수를 구분합니다. 따옴표는 닫힌 공간을 보호합니다. 파이썬은 단일 문자열을 인수 목록으로 구문 분석 할 필요가 없습니다. 당신은'list' 객체를 사용합니다. – chepner