2014-09-21 2 views
2

У меня странная проблема с попыткой выполнить команду ffmpeg с использованием Popen. У меня есть следующий фрагмент кода, который я использую для выполнения экстерном команд в Python:Выполнение команды ffmpeg с использованием Popen

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, но я точно не знаю.

С наилучшими пожеланиями,

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

Этот вывод выводится из файла fail_commands.log. Иными словами, результат выводится после «ОШИБКИ:». – dragonator

ответ

2

Проблема в том, что вы в том числе двойные кавычки в имени файла. Используйте это вместо:

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

Я могу поклясться, что я пробовал это, и это не сработало. Но догадываюсь, что после этого я изменил что-то еще. Просто сделайте для меня все более ясным - двойные кавычки - это только в терминальном использовании, чтобы сообщить интерпретируемому, что следующие вещь - единственный аргумент (если он содержит пробелы)? – dragonator

+1

Исправить; оболочка использует пробелы для разделения аргументов внутри строки; цитаты защищают замкнутые пространства. Python не должен анализировать одну строку в виде списка аргументов; вы просто используете объект 'list'. – chepner