簡體   English   中英

為什么子進程 ffmpeg 會損壞文件?

[英]Why subprocess ffmpeg corrupt the file?

我有以下代碼,它讀取視頻並將其保存在另一個路徑中,問題是當文件被保存時這是不可重現的?

import subprocess
import shlex
from io import BytesIO

file = open("a.mkv", "rb")

with open('a.mkv', 'rb') as fh:
    buf = BytesIO(fh.read())


args = shlex.split('ffmpeg -i pipe: -codec copy -f rawvideo pipe:')
proc = subprocess.Popen(args, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out, err = proc.communicate(input=buf.getbuffer())
proc.wait()

f = open("a.mp4", "wb")
f.write(out)
f.close()

我需要保留緩沖區,視頻大小正確,我該如何解決?

你可以使用ffmpeg-python

pip install ffmpeg-python

然后:

import subprocess
import shlex
import ffmpeg
from io import BytesIO

file = open("a.mkv", "rb")

with open('a.mkv', 'rb') as fh:
    buf = BytesIO(fh.read())

process = (
    ffmpeg
    .input('pipe:') \
    .output('a.mp4') \
    .overwrite_output() \
    .run_async(pipe_stdin=True) \
)

process.communicate(input=buf.getbuffer())

並且沒有任何方法可以制作 pipe 的 stream 數據,如 node.js,例如,啟動一個 pipe 從 s3 下載字節,處理 ffmpeg 並上傳到 s3,在 8831499416 中,我猜測字節可以做 8488填充內存,然后在 python 中,想法是在后端服務器中創建一個臨時文件,然后寫入文件

是的,有,但是 Python 沒有像 Node.js 那樣規定的機制。您需要運行自己的線程(或asyncio協程),一個向 FFmpeg 進程發送數據,另一個從 FFmpeg 進程接收數據。 這是我會做什么的草圖

from threading import Thread
import subprocess as sp

# let's say getting mp4 and output mkv, copying all the streams
# NOTE: you cannot pipe out mp4
args = ['-f','mp4','-','-c','copy','-f','matroska','-']

proc = sp.Popen(args,stdin=sp.PIPE,stdout=sp.PIPE)

def writer():

   # get downloaded bytes data 
   data = ...

    while True:
        # get next data block
        data = self._queue.get()
        self._queue.task_done()
        if data is None:
            break
        
        try:
            nbytes = proc.stdin.write(data)
        except:
            # stdout stream closed/FFmpeg terminated, end the thread as well
            break
        if not nbytes and proc.stdin.closed:  # just in case
            break
   
def reader():

    # output block size
    blocksize = ... # set to something reasonable
                    # I use the frame byte size for rawdata in but would be 
                    # different for receiving encoded data

    while True:
        try:
            data = proc.stdout.read(blocksize)
        except:
            # stdout stream closed/FFmpeg terminated, end the thread as well
            break
        if not data: # done no more data
            break

        # upload the data
        ...

writer = Thread(target=writer)
reader = Thread(target=reader)

writer.start()
reader.start()

writer.join() # first wait until all the data are written
proc.stdin.close() # triggers ffmpeg to stop waiting for input and wrap up its encoding
proc.wait() # waits for ffmpeg
reader.join() # wait till all the ffmpeg outputs are processed

我對我的ffmpegio.streams.SimpleFilterBase class使用不同的方法嘗試了多種不同的嘗試,並選擇了這種方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM