I am trying to process a video by OpenCV in Python and then send each frame to a virtual camera (i.e., v4l2loopback). I have seen questions asked where OpenCV output is piped to ffmpeg and saved into a file, and other questions where a video file is piped to v4l2 using ffmpeg, but no question where these two are combined. I can do either of the above two things on their own, but not combined.
My Python code uses a subprocess to pipe each frame to ffmpeg. The ffmpeg command for piping the output of OpenCV to an .mp4 file is
ffmpeg -y -f rawvideo -vcodec rawvideo -s 1280x720 -pix_fmt bgr24 -i - -vcodec libx264 -crf 0 -preset fast output.mp4
This works and I have tested it.
The ffmpeg command to pipe a video file to the v4l2 virtual camera is
ffmpeg -re -i input.mp4 -map 0:v -f v4l2 /dev/video0
This also works and I have tested it.
I tried combining the above two commands and came up with
ffmpeg -y -f rawvideo -vcodec rawvideo -s 1280x720 -pix_fmt bgr24 -i - -vcodec libx264 -crf 0 -preset fast -map 0:v -f v4l2 /dev/video0
but I get the following error
[NULL @ 0x55a12fcc60] Unable to find a suitable output format for '' : Invalid argument
I would be glad if anyone could help me figure this out.
Thanks.
I see two issues here:
The Unable to find a suitable output format
error is probably from a quotation/escaping issue within the command in your code. Running the same command from a command-line interface executes properly.
Once you fix the quoting issue you will get another error: V4L2 output device supports only a single raw video stream
. This means you can't use libx264 to output to v4l2. So instead let it automatically choose rawvideo output:
ffmpeg -y -f rawvideo -video_size 1280x720 -pixel_format bgr24 -i - -f v4l2 /dev/video0
If the colors look wrong, either use a different -pixel_format
value (see ffmpeg -pix_fmts
), or the player does not support the output pixel format being used by v4l2. In that case add -vf format=yuv420p
output option (anywhere after -i
and before /dev/video0
).
More info:
ffmpeg -h demuxer=rawvideo
)