9

I'm using OpenCV python to capture a video. This is my code

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

When a frame is not ready it produces an error like this

enter image description here

or

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

I wanted to find a way to hide this error! I guess that this error is being produced by ffmpeg. Is there any way to hide or disable it?

This error is produced when I call cap.read(). And I also tried to wrap it with try ... except ... but it doesn't work because it doesn't throw any exceptions.

2
  • I think you just need to redirect stderr to /dev/null... Commented Sep 29, 2013 at 20:32
  • 2
    Thanks @mguijarr for your comment. Yes that's true when you are using ffmpeg in command line. But when I want to do it in python, what should I do? Commented Oct 1, 2013 at 1:48

1 Answer 1

2

One way to hide ffmpeg errors is by redirecting sterr elsewhere. I found this brilliant example on how to hide the errors.

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()
Sign up to request clarification or add additional context in comments.

1 Comment

Since Python 3.5, there is standard library support for this as contextlib.redirect_stderr (and contextlib.redirect_stdout). You should probably use that rather than reinventing the wheel - especially such a complicated wheel!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.