4

Amazon s3サーバーにwavファイルを保存するために使用するdjango FileFieldがあります。そのファイルを読み取ってmp3に変換し、別のFileFieldに保存するようにセロリタスクを設定しました。私が直面している問題は、ファイルがハードディスクドライブ上の物理ファイルではないため、入力ファイルをffmpegに渡すことができないことです。それを回避するために、標準入力を使用して、ファイルの入力ストリームに django のファイルフィールドをフィードしました。次に例を示します。

output_file = NamedTemporaryFile(suffix='.mp3')
subprocess.call(['ffmpeg', '-y', '-i', '-', output_file.name], stdin=recording_wav)

ここで、recording_wav ファイルは次のとおりです。これは、実際には amazon s3 サーバーに保存されます。上記のサブプロセス呼び出しのエラーは次のとおりです。

AttributeError: 'cStringIO.StringO' object has no attribute 'fileno'

これどうやってするの?助けてくれてありがとう。

編集:

完全なトレースバック:

[2012-07-03 04:09:50,336: ERROR/MainProcess] Task api.tasks.convert_audio[b7ab4192-2bff-4ea4-9421-b664c8d6ae2e] raised exception: AttributeError("'cStringIO.StringO' object has no attribute 'fileno'",)
Traceback (most recent call last):
  File "/home/tejinder/envs/tmai/local/lib/python2.7/site-packages/celery/execute/trace.py", line 181, in trace_task
    R = retval = fun(*args, **kwargs)
  File "/home/tejinder/projects/tmai/../tmai/apps/api/tasks.py", line 56, in convert_audio
    subprocess.Popen(['ffmpeg', '-y', '-i', '-', output_file.name], stdin=recording_wav)
  File "/usr/lib/python2.7/subprocess.py", line 672, in __init__
    errread, errwrite) = self._get_handles(stdin, stdout, stderr)
  File "/usr/lib/python2.7/subprocess.py", line 1043, in _get_handles
    p2cread = stdin.fileno()
  File "/home/tejinder/envs/tmai/local/lib/python2.7/site-packages/django/core/files/utils.py", line 12, in <lambda>
    fileno = property(lambda self: self.file.fileno)
  File "/home/tejinder/envs/tmai/local/lib/python2.7/site-packages/django/core/files/utils.py", line 12, in <lambda>
    fileno = property(lambda self: self.file.fileno)
AttributeError: 'cStringIO.StringO' object has no attribute 'fileno'
4

2 に答える 2

3

subprocess.Popen.communicate入力をサブプロセスに渡すために使用します。

command = ['ffmpeg', '-y', '-i', '-', output_file.name]
process = subprocess.Popen(command, stdin=subprocess.PIPE)
process.communicate(recording_wav)

さらに楽しくするために、ffmpegの出力を使用してNamedTemporaryFileを回避することができます。

command = ['ffmpeg', '-y', '-i', '-', '-f', 'mp3', '-']
process = subprocess.Popen(command, stdin=subprocess.PIPE)
recording_mp3, errordata = process.communicate(recording_wav)
于 2012-07-03T16:48:48.217 に答える
1

パイプを作成し、パイプの読み取り側をサブプロセスに渡し、データを書き込み側にダンプする必要があります。

于 2012-07-02T22:39:33.327 に答える