I was wondering if it is possible to 'stream' data using the OpenCV VideoWriter
class in Python?
Normally for handling data in memory that would otherwise go to disk I use BytesIO (or StringIO).
My attempt to use BytesIO fails though:
import cv2
from io import BytesIO
stream = cv2.VideoCapture(0)
fourcc = cv2.VideoWriter_fourcc('x264')
data = BytesIO()
# added these to try to make data appear more like a string
data.name = 'stream.{}'.format('av1')
data.__str__ = lambda x: x.name
try:
video = cv2.VideoWriter(data, fourcc=fourcc, fps=30., frameSize=(640, 480))
start = data.tell()
# Check if camera opened successfully
if (stream.isOpened() == False):
print("Unable to read camera feed", file=sys.stderr)
exit(1)
# record loop
while True:
_, frame = stream.read()
video.write(frame)
data.seek(start)
# do stuff with frame bytes
# ...
data.seek(start)
finally:
try:
video.release()
except:
pass
finally:
stream.release()
However instead of writing the BytesIO
object I end up with the following message:
Traceback (most recent call last):
File "video_server.py", line 54, in talk_to_client
video = cv2.VideoWriter(data, fourcc=fourcc, fps=fps, frameSize=(width, height))
TypeError: Required argument 'apiPreference' (pos 2) not found
... So when I modify the VideoWriter call to be cv2.VideoWriter(data, apiPreference=0, fourcc=fourcc, fps=30., frameSize=(640, 480))
(I read that 0 means auto, but I also tried cv2.CAP_FFMPEG
), I instead get the following error:
Traceback (most recent call last):
File "video_server.py", line 54, in talk_to_client
video = cv2.VideoWriter(data, apiPreference=0, fourcc=fourcc, fps=fps, frameSize=(width, height))
TypeError: bad argument type for built-in operation
So my question is, is it possible to write encoded video using the cv2.VideoWriter
class in memory and if so how is it done?
At this point I'm fresh out of ideas, so any help would be most welcome :-)