将视频文件作为字节流式传输到stdin

时间:2017-12-20 18:25:44

标签: python video ffmpeg pipe stdin

我正在创建一个进程,其中python打开一个视频文件,并将其流式传输到ffmpeg命令的stdin中。我认为我有正确的想法,但文件打开的方式不适用于标准输入。到目前为止,这是我的代码:

def create_pipe():

    return Popen([    'ffmpeg',
                      '-loglevel', 'panic',
                      '-s', '1920x1080',
                      '-pix_fmt', 'yuvj420p',
                      '-y',
                      '-f', 'image2pipe',
                      '-vcodec', 'mjpeg',
                      '-r', self.fps,
                      '-i', '-',
                      '-r', self.fps,
                      '-s', '1920x1080',
                      '-f', 'mov',
                      '-vcodec', 'prores',
                      '-profile:v', '3',
                      '-aspect', '16:9', '-y',
                      'output_file_name' + '.mov'], stdin=PIPE)



in_pipe = create_pipe()
with open("~/Desktop/IMG_1973.mov", "rb") as f:
    in_pipe.communicate(input=f)

这会产生错误:

TypeError: a bytes-like object is required, not '_io.BufferedReader'

将视频文件打开/流式传输到此管道的正确方法是什么?我还需要成为一个流,而不是将整个内容读入内存。

PS。请忽略我可以在ffmpeg中原生打开文件...我正在创建一个包装器,如果我可以控制输入,那就更好了。

1 个答案:

答案 0 :(得分:1)

首先确保输入格式可以通过管道传输。对于ISO BMFF,moov原子必须位于文件的开头才能使其工作。

如果它是可管道的,那么使用generator读取文件并将其传递给子进程:

def read_bytes(input_file, read_size=8192):
    """ read 'read_size' bytes at once """
    while True:
        bytes_ = input_file.read(read_size)
        if not bytes_:
            break
        yield bytes_


def main():
    in_pipe = create_pipe()

    with open("in.mov", "rb") as f:
        for bytes_ in read_bytes(f):
            in_pipe.stdin.write(bytes_)

    in_pipe.stdin.close()
    in_pipe.wait()