通过子过程将python的对象之类的文件传递给ffmpeg [英] Passing python's file like object to ffmpeg via subprocess

查看:181
本文介绍了通过子过程将python的对象之类的文件传递给ffmpeg的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个Django FileField,用于在Amazon s3服务器上存储wav文件.我已经设置了celery任务,以读取该文件并将其转换为mp3并将其存储到另一个FileField中.我面临的问题是我无法将输入文件传递给ffmpeg,因为该文件不是硬盘驱动器上的物理文件.为了避免这种情况,我使用stdin将文件的输入流与Django的filefield一起提供.这是示例:

I have a django FileField, which i use to store wav files on the Amazon s3 server. I have set up the celery task to read that file and convert it to mp3 and store it to another FileField. Problem i am facing is that i am unable to pass the input file to ffmpeg as the file is not the physical file on the hard disk drive. To circumvent that, i used stdin to feed the input stream of the file with the django's filefield. Here is the example:

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

其中recording_wav文件是:,它实际上存储在amazon s3服务器上. 上面的子流程调用的错误是:

where recording_wav file is: , which is actually stored on the amazon s3 server. The error for the above subprocess call is:

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

我该怎么做?预先感谢您的帮助.

How can i do this? Thanks in advance for the help.

完整追溯:

[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'

推荐答案

使用

Use subprocess.Popen.communicate to pass the input to your subprocess:

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

为了获得更多乐趣,您可以使用ffmpeg的输出来避免您的NamedTemporaryFile:

For extra fun, you could use the ffmpeg's output to avoid your NamedTemporaryFile:

command = ['ffmpeg', '-y', '-i', '-', '-f', 'mp3', '-']
process = subprocess.Popen(command, stdin=subprocess.PIPE)
recording_mp3, errordata = process.communicate(recording_wav)

这篇关于通过子过程将python的对象之类的文件传递给ffmpeg的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆