A custom stream source is working on desktop but not on mobile

Description
In my project, the “getUserMedia” method was modified to create a “virtual camera”. This means that when the method is called with the virtual camera id, it will return a stream from the “captureStream” method of a hidden canvas element, which has a 3D avatar rendered. Additionally, the “enumerateDevices” method was also modified so that when it is called, the virtual camera will be listed as well.

The virtual camera id is passed in the methods “createLocalVideoTrack” (preview) and “startVideo” (actual room), and it’s working correctly in the desktop browser: the 3D avatar is streaming as expected. However, the problem I’m currently facing happens in the mobile browser: the avatar stream is working on the preview page, but not in the room, the avatar isn’t streaming (nothing is being streamed), although it is rendering the avatar in the canvas element correctly.

Being able to stream this avatar is essential for my project, so I would appreciate your help in making it work on mobile too.

Browser Console Error
There are no console errors.

Which Web Video SDK version?
^1.11.0

Video SDK Code Snippets

      const initialVideoOption: CaptureVideoOption = {
        hd: false,
        fullHd: false,
        ptz: false,
        originalRatio: true,
        cameraId
      }

      if (anonymous) {
        await startEngine(cameraId)
        initialVideoOption.cameraId = 'jb_virtual_cam'

        await mediaStream?.startVideo(initialVideoOption)
      }
  • The method startEngine starts the avatar render and it’s working as expected.
  • “jb_virtual_cam” is the id of the “virtual camera”
  • The method “startVideo” should stream the canvas stream from the device “jb_virtual_cam”, but it isn’t working on mobile.

To Reproduce

  1. modify the method enumerateDevices
  MediaDevices.prototype.enumerateDevices = async function () {
    const res = await enumerateDevicesFn.call(navigator.mediaDevices)

    const dv: MediaDeviceInfoAttributes = {
      deviceId: 'custom_virtual_camera_id',
      groupId: 'custom_virtual_devices',
      kind: 'videoinput',
      label: 'virtual webcam'
    }

    res.push({
      ...dv,
      toJSON: () => {
        return dv
      }
    })

    return res
  }
  1. Modify the method getUserMedia
  MediaDevices.prototype.getUserMedia = async function (...args: any) {
    if (args.length && args[0].video && args[0].video.deviceId) {
      if (
        args[0].video.deviceId === 'custom_virtual_camera_id' ||
        args[0].video.deviceId.exact === 'custom_virtual_camera_id'
      ) {
        const constraints = {
          video: { ...(args?.video ?? {}) },
          audio: false
        }
        const res = await getUserMediaFn.call(
          navigator.mediaDevices,
          constraints
        )

        const canvas: HTMLCanvasElement | null = document.querySelector('#canvas-with-avatar')

        if (res && canvas) {
          return canvas.captureStream(30)
        }
      }
    }

    const res = await getUserMediaFn.call(navigator.mediaDevices, ...args)

    return res
  }
  1. Try to use the virtual camera with the zoom video-sdk. In this case the camera id is “custom_virtual_camera_id”

Device:

  • Device: Motorola Moto G54
  • OS: Android 14
  • Browser: Chrome
  • Browser Version: Chrome 127.0.6533.106