如何在使用OpenCV(Python)时隐藏/禁用ffmpeg错误?

9

我正在使用OpenCV Python来捕获视频。这是我的代码:

import cv2

cap = cv2.VideoCapture("vid.mp4")
while True:
    flag, frame =  cap.read()

    if not flag:
        cv2.imshow('video', frame)

    if cv2.waitKey(10) == 27:
        break

当一帧没有准备好时,会产生如下错误:

enter image description here

或者

Truncating packet of size 2916 to 1536
[h264 @ 0x7ffa4180be00] AVC: nal size 2912
[h264 @ 0x7ffa4180be00] AVC: nal size 2912
[h264 @ 0x7ffa4180be00] no frame!

[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7ffa41803000] stream 0, offset 0x14565: partial file

我希望找到一种方法来隐藏这个错误!我猜想这个错误是由ffmpeg产生的。有没有办法隐藏或禁用它?
当我调用cap.read()时,就会产生这个错误。我也试过用try ... except ...将其包装起来,但它不起作用,因为它不会抛出任何异常。

我认为你只需要将stderr重定向到/dev/null... - mguijarr
2
感谢 @mguijarr 的评论。是的,在使用命令行中的 ffmpeg 时,这是正确的。但是当我想在 Python 中实现它时,我应该怎么做呢? - Mehran
1个回答

2

隐藏ffmpeg错误的一种方法是将sterr重定向到其他地方。我在这个出色的例子中发现了如何隐藏错误。

import ctypes
import io
import os
import sys
import tempfile
from contextlib import contextmanager

import cv2

libc = ctypes.CDLL(None)
c_stderr = ctypes.c_void_p.in_dll(libc, 'stderr')


@contextmanager
def stderr_redirector(stream):
    original_stderr_fd = sys.stderr.fileno()

    def _redirect_stderr(to_fd):
        libc.fflush(c_stderr)
        sys.stderr.close()
        os.dup2(to_fd, original_stderr_fd)
        sys.stderr = io.TextIOWrapper(os.fdopen(original_stderr_fd, 'wb'))

    saved_stderr_fd = os.dup(original_stderr_fd)
    try:
        tfile = tempfile.TemporaryFile(mode='w+b')
        _redirect_stderr(tfile.fileno())
        yield
        _redirect_stderr(saved_stderr_fd)
        tfile.flush()
        tfile.seek(0, io.SEEK_SET)
        stream.write(tfile.read().decode())
    finally:
        tfile.close()
        os.close(saved_stderr_fd)

f = io.StringIO()
with stderr_redirector(f):
    # YOUR CODE HERE

f.close()

自Python 3.5起,标准库支持contextlib.redirect_stderr(和contextlib.redirect_stdout)来实现此功能。您应该使用它而不是重新发明轮子 - 特别是这样一个复杂的轮子! - user9876

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接