Fast streaming camera view to video for linux (v4l) system device
I think I made progress which fits to your question.
With a modal operator I have achieved streaming a live camera view from the active Viewport to a v4l device with about 11 fps. Not that smooth, but a good start.
Of course I did not come up with this totally on my own, but i was guided by related threads or answers:

Question from bluejayke on realtime export of images
Brilliant Answer from CodeManX on question regarding screenshots

This method was tested in blender 2.82, in version 2.92 it somehow only delivers black images
Workspace &quot;Configuration&quot;:

have a 3D View
switch to Camera mode (Num 0)
Zoom Camera to 1:1 (View-&gt;Navigation-&gt;Zoom Camera 1:1)
toggle all overlays, gizmos and helper bars which overlap your camera view as they will show in your stream

These steps are not required for the pipeline to work, however what you see in your viewport gets cropped to the render size, so you may have unexpected output if the view doesn't match the camera view 1:1 or has a smaller size than your set resolution
What my code does:
I set up a modal operator which runs at 30Hz (in my use-case it also updates the scene and the camera postion but this is not included in the example).
With the ffmpeg-python package I set up a stream to the previously created virtual video device (setup via v4l2loopback).
In the modal function I grab the pixels in the camera region and put them into the ffmpeg stream.
Example:
import bpy
import bgl
import ffmpeg

class VirtualStream(bpy.types.Operator):
    bl_idname = &quot;wm.virtual_stream&quot;
    bl_label = &quot;Virtual Stream&quot;
    
    _timer = None
    _updating = False
    
    ffmpeg_proc = None
    _region = None
    _res_x = None
    _res_y = None
    
    # change to the path of your v4l device
    _video_device = &quot;/dev/video2&quot;
    
    def modal(self, context, event):
        if event.type in {'ESC'}:
            self.cancel(context)
            return {'CANCELLED'}
        if event.type == &quot;TIMER&quot; and not self._updating:
            self._updating = True
            # correct start pixel of region to camera corner
            x = self._region.x + (self._region.width - self._res_x) // 2
            y = self._region.y + (self._region.height - self._res_y) // 2
            bpy.ops.wm.redraw_timer(type=&quot;DRAW_WIN_SWAP&quot;, iterations=1)
            # read pixel values in buffer
            buf = bgl.Buffer(bgl.GL_BYTE, self._res_x * self._res_y * 3)
            bgl.glReadPixels(x, y, self._res_x, self._res_y, bgl.GL_RGB, bgl.GL_UNSIGNED_BYTE, buf)
            # convert buffer to bytes for ffmpeg
            buf_list = buf.to_list()
            myBytes = bytes(buf_list)
            # write bytes to virtual video device
            self.ffmpeg_proc.stdin.write(myBytes)
            self._updating = False
        return {'PASS_THROUGH'}
            
    
    def execute(self, context):
        # setup timer for modal 
        wm = context.window_manager
        self._timer = wm.event_timer_add(1/30, window=context.window)
        wm.modal_handler_add(self)
        # get render resolution -&gt; size of camera view
        self._res_x = bpy.context.scene.render.resolution_x
        self._res_y = bpy.context.scene.render.resolution_y
        # setup ffmpeg stream
        self.ffmpeg_proc = (
            ffmpeg.input(&quot;pipe:&quot;, format=&quot;rawvideo&quot;, pix_fmt=&quot;rgb24&quot;, s=&quot;{}x{}&quot;.format(self._res_x, self._res_y))
            .vflip()
            .output(&quot;/dev/video2&quot;, format=&quot;v4l2&quot;, pix_fmt=&quot;yuv420p&quot;)
            .overwrite_output()
            .run_async(pipe_stdin=True)
        )
        # grab region we want to capture
        for a in context.screen.areas:
            if a.type == &quot;VIEW_3D&quot;:
                for r in a.regions:
                    if r.type == &quot;WINDOW&quot;:
                        self._region = r
                        break
        self._updating = False
        return {'RUNNING_MODAL'}
    
    
    def cancel(self, context):
        context.window_manager.event_timer_remove(self._timer)
        self.ffmpeg_proc.stdin.close()
        self.ffmpeg_proc.wait()

bpy.utils.register_class(VirtualStream)

Time constraints:
As I mentioned on my machine it runs at about 11 fps, with an additional update of the scene this drops to about 7 fps depending on the updates. When timig the individual parts bgl.glreadPixels took about 50ms and the conversion to bytes also took 50ms, the other parts are virtually irrelevant.
What I don't know is why your execution of bgl.glreadPixel was so much slower than mine or how to speed up from here.