11

我正在尝试将 ffmpeg 与 Python 的 subprocess 模块一起使用来转换一些音频文件。我从 URL 中获取音频文件,并希望能够将 Python 文件对象传递给 ffmpeg,而不是先将它们保存到磁盘。如果我可以只取回文件流而不是让 ffmpeg 将输出保存到文件中,那也很好。

作为参考,这就是我现在正在做的事情:

tmp = "/dev/shm"
audio_wav_file = requests.get(audio_url)
##              ##                         ##
## This is what I don't want to have to do ##
wavfile = open(tmp+filename, 'wrb')   
wavfile.write(audio_wav_file.content)
wavfile.close()
##              ##                         ##
conversion = subprocess.Popen('ffmpeg -i "'+tmp+filename+'" -y "'+tmp+filename_noext+'.flac" 2>&1', shell = True, stdout = subprocess.PIPE).stdout.read()

有谁知道如何做到这一点?

谢谢!

4

4 回答 4

7

使用 ffmpeg,您可以将-其用作输入/输出文件名,以指示它应该从标准输入读取数据/写入标准输出。

然后你可以使用stdin/stdout参数Popen来读/写你的数据。

一个例子:

from subprocess import Popen, PIPE

with open("test.avi", "rb") as infile:
    p=Popen(["ffmpeg", "-i", "-", "-f", "matroska", "-vcodec", "mpeg4",
        "-acodec", "aac", "-strict", "experimental", "-"],
           stdin=infile, stdout=PIPE)
    while True:
        data = p.stdout.read(1024)
        if len(data) == 0:
            break
        # do something with data...
        print(data)
    print p.wait() # should have finisted anyway

相反,您为您提供文件stdin也可以使用 aPIPE并直接写入进程输入流 ( p.stdin)。或者在您的情况下,您只需使用 wavfile ...

请注意,您必须明确指定输出格式和编解码器,因为 ffmpeg 无法像通常那样从文件扩展名中猜测它们。
它只适用于不需要可搜索输出流的多路复用器,但 flac 应该可以工作......

于 2012-05-01T17:33:32.653 回答
2

对于仍在阅读本文的任何人:这可以通过使用FFMPEG 的管道协议而不使用子进程来完成。如果使用包调用 FFMPEG ffmpeg-python,则可以将 FFMPEG 命令的stdout, stderr输出输入 Python 变量,如下所示

out, err = inpstream.output('pipe:', ... ).run(capture_stdout=True)
于 2020-03-25T18:24:08.440 回答
0

Since it looks like you're on Unix (no .exe on the end of 'ffmpeg'), I would recommend using a named pipe, a.k.a. fifo:

mkfifo multimedia-pipe

Have the Python script write the audio data into 'multimedia-file' and ask FFmpeg to read from the same file. I have used this pattern to decode multimedia files into their huge, raw representations for validation without having to occupy disk space.

Alternatively, try passing the 'http://...' URL directly to FFmpeg's input option.

于 2012-05-01T16:55:58.823 回答
0

PyAV 可以与docs中的路径或类似文件的对象一起使用:

file (str) -- 要打开的文件,可以是字符串或类似文件的对象。

(如果你有一个字节数组,你可以在传递给它io.BytesIO之前将它包装起来av.open

于 2022-01-26T15:46:21.557 回答