GithubHelp home page GithubHelp logo

letmaik / pyvirtualcam Goto Github PK

View Code? Open in Web Editor NEW
462.0 12.0 48.0 12.24 MB

๐ŸŽฅ Send frames to a virtual camera from Python

License: GNU General Public License v2.0

Python 28.40% C++ 62.50% C 4.64% Objective-C 0.35% Objective-C++ 4.12%
virtual-camera python

pyvirtualcam's Introduction

pyvirtualcam

pyvirtualcam sends frames to a virtual camera from Python.

Usage

import colorsys
import numpy as np
import pyvirtualcam

with pyvirtualcam.Camera(width=1280, height=720, fps=20) as cam:
    print(f'Using virtual camera: {cam.device}')
    frame = np.zeros((cam.height, cam.width, 3), np.uint8)  # RGB
    while True:
        h, s, v = (cam.frames_sent % 100) / 100, 1.0, 1.0
        r, g, b = colorsys.hsv_to_rgb(h, s, v)
        frame[:] = (r * 255, g * 255, b * 255)
        cam.send(frame)
        cam.sleep_until_next_frame()

pyvirtualcam uses the first available virtual camera it finds (see later section).

For more examples, including using different pixel formats like BGR, or selecting a specific camera device, check out the examples/ folder.

See also the API Documentation.

Installation

This package works on Windows, macOS, and Linux. Install it from PyPI with:

pip install pyvirtualcam

pyvirtualcam relies on existing virtual cameras which have to be installed first. See the next section for details.

Supported virtual cameras

Windows: OBS

OBS includes a built-in virtual camera for Windows (since 26.0).

To use the OBS virtual camera, simply install OBS.

Note that OBS provides a single camera instance only, so it is not possible to send frames from Python to the built-in OBS virtual camera, capture the camera in OBS, mix it with other content, and output it again to OBS' built-in virtual camera. To achieve such a workflow, use another virtual camera from Python (like Unity Capture) so that OBS' built-in virtual camera is free for use in OBS.

Windows: Unity Capture

Unity Capture provides a virtual camera originally meant for streaming Unity games. Compared to most other virtual cameras it supports RGBA frames (frames with transparency) which in turn can be captured in OBS for further processing.

To use the Unity Capture virtual camera, follow the installation instructions on the project site.

macOS: OBS

OBS includes a built-in virtual camera for macOS (since 26.1).

NOTE: Starting with pyvirtualcam 0.10, only OBS 28 or higher is supported. Install an older version if you need OBS 26 / 27 support.

HELP WANTED: pyvirtualcam requires code updates to run on macOS 14 and higher. If you own a Mac, consider contributing: #111 (comment).

To use the OBS virtual camera, follow these one-time setup steps:

  • Install OBS.
  • Start OBS.
  • Click "Start Virtual Camera" (bottom right), then "Stop Virtual Camera".
  • Close OBS.

Note that OBS provides a single camera instance only, so it is not possible to send frames from Python, capture the camera in OBS, mix it with other content, and output it again as virtual camera.

Linux: v4l2loopback

pyvirtualcam uses v4l2loopback virtual cameras on Linux.

To create a v4l2loopback virtual camera on Ubuntu, run the following:

sudo apt install v4l2loopback-dkms
sudo modprobe v4l2loopback devices=1

For further information, see the v4l2loopback documentation.

Build from source

Linux/macOS

git clone https://github.com/letmaik/pyvirtualcam --recursive
cd pyvirtualcam
pip install .

Windows

These instructions are experimental and support is not provided for them. Typically, there should be no need to build manually since wheels are hosted on PyPI.

You need to have Visual Studio installed to build pyvirtualcam.

In a PowerShell window:

$env:USE_CONDA = '1'
$env:PYTHON_VERSION = '3.7'
$env:PYTHON_ARCH = '64'
$env:NUMPY_VERSION = '1.14'
git clone https://github.com/letmaik/pyvirtualcam --recursive
cd pyvirtualcam
powershell .github/scripts/build-windows.ps1

The above will download all build dependencies (including a Python installation) and is fully configured through the four environment variables. Set USE_CONDA = '0' to build within an existing Python environment.

pyvirtualcam's People

Contributors

graphemecluster avatar guerout-arnaud avatar jaiaid avatar jayfoxrox avatar koratkar avatar letmaik avatar vinnik-dmitry07 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

pyvirtualcam's Issues

"No v4l2 loopback device found" after using pyvirtualcam once with `exclusive_caps=1`

  • Operating system: Arch Linux
  • pyvirtualcam version: 0.8.0
  • Virtual camera (OBS, v4l2loopback, UnityCapture): v4l2loopback
  • Virtual camera version: 0.12.5-1

Describe the bug
After running a script using pyvirtualcam the next run causes this error:

RuntimeError: 'v4l2loopback' backend: No v4l2 loopback device found at /dev/video[0-99]. Did you run 'modprobe v4l2loopback'? See also pyvirtualcam's documentation.

Only after unloading and reloading the kernel module I can run another script using pyvirtualcam.

To Reproduce
Every single sample code causes this error.

#!/usr/bin/env python3
import pyvirtualcam
import numpy as np

with pyvirtualcam.Camera(width=1280, height=720, fps=20) as cam:
    print(f'Using virtual camera: {cam.device}')
    frame = np.zeros((cam.height, cam.width, 3), np.uint8)  # RGB
    while True:
        frame[:] = cam.frames_sent % 255  # grayscale animation
        cam.send(frame)
        cam.sleep_until_next_frame()

I even rewrote a script to not use the with statement and call cam.close() (and even cam._backend.close()) directly.

Numpy 2.0 is out, pyvirtualcam doesn't work with it

  • Operating system: Windows 11
  • Python version: 3.12.2
  • pyvirtualcam version: 0.11.1 (from pip install)
  • Virtual camera (OBS, v4l2loopback, UnityCapture): OBS
  • Virtual camera version: 30.1.2

Describe the bug
Pyvirtualcam does not work with the new Numpy 2.0. You may want to update your dependencies to make that explicit, or update the code to support 2.0.

To Reproduce
I installed the code for my Oak D Lite camera:
pipenv shell
pipenv install depthai pyvirtualcam
This ended up installing Numpy 2.0.0.

I then ran their sample code to build a UVC camera. The result crashed from inside your camera.py, line 348 frame = np.array(frame.reshape(-1), copy=False, order='C') with the error:

ValueError: Unable to avoid copy while creating an array as requested.
If using `np.array(obj, copy=False)` replace it with `np.asarray(obj)` to allow a copy when needed (no behavior change in NumPy 1.x).

When I made the change suggested, I got a video feed that showed a flat grey color that flickered in brightness.

I then downgraded Numpy to 1.26 (pipenv install numpy==1.26) and the camera feed started working fine. When I reverted my change to your file, the camera feed continued to work fine.

failed to import on arm64

  • Operating system: armbin jammy
  • Python version: 3.10.6
  • pyvirtualcam version: git/master

git clone the latest code,

python3 setup.py build/ install seems fine,

but when i import the module, it show:

**ImportError: /usr/local/lib/python3.10/dist-packages/pyvirtualcam-0.10.2-py3.10-linux-aarch64.egg/pyvirtualcam/_native_linux_v4l2loopback.cpython-310-aarch64-linux-gnu.so: undefined symbol: CanonicalFourCC
**

Virtual Camera may not be cleaning up after usage

For example, here is a simple snippet to reproduce the error

import pyvirtualcam

with pyvirtualcam.Camera(640, 480, 20, 0, print_fps=True) as cam:
    print("Everything works fine")

with pyvirtualcam.Camera(640, 480, 20, 0, print_fps=True) as cam:
    print("Here it throws the error")

This outputs as follows:

Everything works fine
virtual camera output already started
Traceback (most recent call last):
  File "d:\vcam\ultra-virtual-cam-filter\test.py", line 6, in <module>
    with pyvirtualcam.Camera(640, 480, 20, 0, print_fps=True) as cam:
  File "C:\Users\rahat\.conda\envs\vcam\lib\site-packages\pyvirtualcam\camera.py", line 86, in __init__
    _native_windows.start(width, height, fps, delay)
RuntimeError: error starting virtual camera output

So, my guess is, maybe it is not calling the below function at all?

macOS: OBS 18 support

OBS 18 comes with an updated macOS virtual camera that is incompatible with the previous one.
Therefore, pyvirtualcam needs to be updated to support it.

Users who need to use OBS 17 will have to install an older pyvirtualcam release going forward. Supporting both would be too much maintenance effort.

Compare:
https://github.com/obsproject/obs-studio/tree/27.2.4/plugins/mac-virtualcam/src/obs-plugin
https://github.com/obsproject/obs-studio/tree/28.0.1/plugins/mac-virtualcam/src/obs-plugin

Some initial work was done in https://github.com/letmaik/pyvirtualcam/compare/macos-obs18-support

Cannot open installed OBS camera when running from a service

  • Operating system: Winwdows 10
  • pyvirtualcam version: 0.8.0
  • Virtual camera (OBS, v4l2loopback, UnityCapture): OBS
  • Virtual camera version: win-dshow

Decription
Using pywin32==301 and auto-py-to-exe==2.9.0 to install pyvirtualcam as Windows service, I'm getting following error:
'obs' backend: virtual camera output could not be started

To Reproduce

def main():
    try:
        with pyvirtualcam.Camera(width=1280, height=720, fps=20, backend='obs') as cam:
            print(f'Using virtual camera: {cam.device}\n')
            frame = np.zeros((cam.height, cam.width, 3), np.uint8)  # RGB
            while True:
                frame[:] = cam.frames_sent % 255  # grayscale animation
                cam.send(frame)
                cam.sleep_until_next_frame()
    except Exception as e:
        with open(r"C:\ProgramData\error.txt", 'a') as f:
            f.write(str(e)+'\n')


class Service(win32serviceutil.ServiceFramework):
    _svc_name_ = "TEST_VID0"
    _svc_display_name_ = "test video zeros 0"

    def __init__(self, *args):
        # win32serviceutil.ServiceFramework.__init__(self, *args)
        super().__init__(*args)
        self.hWaitStop = win32event.CreateEvent(None, 0, 0, None)
        socket.setdefaulttimeout(5)
        self.stop_requested = False

    def SvcStop(self):
        self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
        win32event.SetEvent(self.hWaitStop)
        self.ReportServiceStatus(win32service.SERVICE_STOPPED)
        self.stop_requested = True

    def SvcDoRun(self):
        self.ReportServiceStatus(win32service.SERVICE_RUNNING)
        self.main()

    def main(self):
        main()


if __name__ == '__main__':
    if len(sys.argv) == 1:
        servicemanager.Initialize()
        servicemanager.PrepareToHostSingle(Service)
        servicemanager.StartServiceCtrlDispatcher()
    else:
        win32serviceutil.HandleCommandLine(Service)
  • compile main() function using auto-py-to-exe - works like a charm (writing to programdata requires administrative priveleges, so it's recommended to start exe as admin, or change destination folder to where all users can write), you should see in any camera preview gray screen that changes color
  • then compile whole file using auto-py-to-exe and use file.exe install then file.exe start, you should see specified error in the text file - C:\ProgramData\error.txt

NOTE: It's not first time when i'm using pywin32 to install python programs as a service, it definetely works, provided code is a default code to create any service which main loop lies in main() function. To delete service use file.exe remove. My guess is that system services somehow cannot access camera from where they are started, but i have no clue why and thats why i ask for help, any comment on this would be helpful.

Virtual camera is not usable in OBS

(Note: I never tried this package on Windows; but this is from experience with my macOS port from #16)

Because this package pretends to be OBS, it's not possible to use the virtual camera in OBS, to be fed into yet another virtual camera.

Instead of this package, I'll likely switch to creating a IP-based camera to be fed into OBS (which then creates the virtual-camera itself).

The design should be improved, so this package creates its own unique virtual webcam devices (which also work in OBS).
This will also be important for supporting multiple virtual cameras at once.

Wheels for macOS ARM64

  • Operating system: macOS
  • Python version: 3.10.6
  • pyvirtualcam version: -
  • Virtual camera (OBS, v4l2loopback, UnityCapture): -
  • Virtual camera version: -

Describe the bug

$ pip install pyvirtualcam
ERROR: Could not find a version that satisfies the requirement pyvirtualcam (from versions: none)
ERROR: No matching distribution found for pyvirtualcam

Related issue: #15.

Could this be because of M1?

Unable to download via pip

Hello,
thanks for your work. I've tried to download pyvirtualcam with pip install pyvirtualcam and it raises this error:

ERROR: Could not find a version that satisfies the requirement pyvirtualcam
ERROR: No matching distribution found for pyvirtualcam

Any help is appreciated.
Thank you

AttributeError: module 'pyvirtualcam' has no attribute 'Camera'

I am trying to use pyvirtualcam to set up a virtual camera; however, I get this error every time I try to run my code.

AttributeError: module 'pyvirtualcam' has no attribute 'Camera'

I have installed obs-virtualcam and all necessary dependencies, but this error still occurs. Does anyone know why this is happening?

Deprecate "delay" argument

The delay argument is not in use anymore in any of the supported virtual cameras. To avoid breaking existing code, it should first be deprecated and at some point later removed.

Error when running setup.py

When I run setup.py on Windows 10, I always have the following problem:
C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\BIN\x86_amd64\cl.exe /c /nologo /Ox /W3 /GL /DNDEBUG /MD -DVERSION_INFO="0.8.0" -Ipyvirtualcam/native_windows_obs -Ic:\users\administrator\pyvirtualcam.eggs\pybind11-2.7.1-py3.8.egg\pybind11\include -Iexternal/libyuv/include -IC:\Users\Administrator\AppData\Local\Programs\Python\Python38\include -IC:\Users\Administrator\AppData\Local\Programs\Python\Python38\include "-IC:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\INCLUDE" "-IC:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\ATLMFC\INCLUDE" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.10240.0\ucrt" "-IC:\Program Files (x86)\Windows Kits\NETFXSDK\4.6.1\include\um" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.10240.0\shared" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.10240.0\um" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.10240.0\winrt" "-IC:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include" "-IC:\Program Files (x86)\Windows Kits\10\Lib\10.0.10240.0\ucrt" /EHsc /Tppyvirtualcam/native_windows_obs/main.cpp /Fobuild\temp.win-amd64-3.8\Release\pyvirtualcam/native_windows_obs/main.obj /EHsc /std:c++17
Cl: command line warning D9002: ignore unknown option "/ STD :c++17"
main.cpp
pyvirtualcam/native_windows_obs/main.cpp(2): fatal error C1083: ๆ— ๆณ•ๆ‰“ๅผ€ๅŒ…ๆ‹ฌๆ–‡ไปถ: โ€œoptionalโ€: No such file or directory
error: command 'C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\BIN\x86_amd64\cl.exe' failed with exit status 2

May I ask how to solve these problems? Looking forward to your reply!

Sending ARGB Frames

I am sorry to open an issue here but I am trying to send ARGB data (with shape (h,w,4)) to OBS but it seems that neither the shape is correct nor the OBS Virtual Camera support ARGB data. I've asked a question on StackOverflow but I think no one would be able to answer my question, so I decided to ask here. Any help would be much appreciated.

Multiple OBS Virtual cameras in OBS - using additional obs-virtual-cam plugin

Hi wanted to drop this note about having multiple OBS Virtual cameras.

Since Virtual Camera has been integrated in the OBS code base one can only activate a single virtual camera.

This plugin - https://github.com/Fenrirthviti/obs-virtual-cam (a fork from the original plugin) allows you to add 4 more. It works with latest version of OBS fine and just adds 4 extra cameras. (Windows).

Thanks again for writing this library and the documentation.

pyvirtualcam does not detect OBS on macOS 14: 'obs' backend: OBS Virtual Camera is not installed

  • Operating system: macOS 14.0
  • Python version: 3.10
  • pyvirtualcam version: 0.10.2
  • Virtual camera (OBS, v4l2loopback, UnityCapture): OBS
  • Virtual camera version: 30.0.0-beta3

Describe the bug
OBS in 30.0.0 beta versions changed its implementation of the virtualcam to make it compatible for macOS 14 Sonoma. Now, the pyvirtualcam code does not detect the OBS virtualcam even though it is detected by Zoom or Google Meet.

The following error is thrown:

RuntimeError: 'obs' backend: OBS Virtual Camera is not installed in your system. Use the Virtual Camera function in OBS to trigger installation.

To Reproduce

The OBS virtualcam is detected by pyvirtualcam by the following Python script:

        self.virtualcam = pyvirtualcam.Camera(
            # set standard dimensions, see https://github.com/letmaik/pyvirtualcam/issues/110#issuecomment-1624273288
            width=1280,
            height=720,
            fps=30,
            device="OBS Virtual Camera",
            fmt=pyvirtualcam.PixelFormat.BGR
        )

Streaming is very slow

I am sending data from C++ to Python in order to stream on a webcam.
The streaming itself, without data from C++, works great and without big delay using this code.

import cv2
import numpy as np
from numpy import asarray
import pyvirtualcam

vc = cv2.VideoCapture(0)

if not vc.isOpened():
    raise RuntimeError('Could not open video source')

try:
    with pyvirtualcam.Camera(width=640, height=480, fps=20) as cam:

        while True:
            # Read frame from webcam
            s,frame = vc.read()
            frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
            array_frame = asarray(frame)
            frame = np.zeros((cam.height, cam.width, 4), np.uint8)
            frame[:,:,:3] = array_frame
            cam.send(frame)
            cam.sleep_until_next_frame()
finally:
    vc.release()

So it seems like the streaming is not the issue.
With the following code, I can stream data from C++ with almost the same minimal delay to Python and display it using opencv.

import pyvirtualcam
import numpy as np
from numpy import asarray
import cv2

camera = pyvirtualcam.Camera(width=640, height=480, fps=20)

def foo_bar(img=None):  
    if img is not None:
        cv2.imshow("From Python", img)
        img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
        array_frame = asarray(img)
        img = np.zeros((camera.height, camera.width, 4), np.uint8)
        img[:,:,:3] = array_frame
        camera.send(img)
        # camera.sleep_until_next_frame()

But the webcam feed has a delay of around 2 seconds.

OBS plugin used from local folder

Is there a way to use the obs plugin from a local folder instead of loading it from the ~/Library folder. This would bypass the need for the user to install obs as it can be packaged with the python app in relative folder.

Thanks! This would help me a lot.

v4l2loopback: 'error writing frame: Invalid argument' when cam.send()

  • Operating system: Ubuntu18.04
  • Python version: python3.7.13
  • pyvirtualcam version: 0.9.1
  • Virtual camera (OBS, v4l2loopback, UnityCapture): v4l2loopback
  • Virtual camera version: 5.4.192

Hi, I'm trying to transfer images to virtual camera(v4l2loopback) using pyturalcam, and I just ran your example

import pyvirtualcam
import numpy as np

with pyvirtualcam.Camera(width=1280, height=720, fps=20) as cam:
    print(f'Using virtual camera: {cam.device}')
    frame = np.zeros((cam.height, cam.width, 3), np.uint8)  # RGB
    while True:
        frame[:] = cam.frames_sent % 255  # grayscale animation
        cam.send(frame)
        cam.sleep_until_next_frame()

And I got the error:

error writing frame: Invalid argumenterror

I found out through debugging that the error was printed while executing the line 'cam.send(frame)',
What is the reason for this? Hope you can help.

ERROR: No matching distribution found for pyvirtualcam

  • Operating system: MacOS Sonoma 14.1.1
  • Python version: 3.11.7
  • pyvirtualcam version: 0.11.0
  • Virtual camera (OBS, v4l2loopback, UnityCapture): OBS
  • Virtual camera version:

pip3 install pyvirtualcam gives me the following error:

ERROR: Could not find a version that satisfies the requirement pyvirtualcam (from versions: none)
ERROR: No matching distribution found for pyvirtualcam

The same happens if I try to use the PyCharm package installer. Would greatly appreciate help!
...

To Reproduce

pip3 install pyvirtualcam

Package not installing

Tried to load the package with pip from VS Code. Getting this error, even after loading OBS Studio:

ERROR: Could not find a version that satisfies the requirement pyvirtualcam (from versions: none)
ERROR: No matching distribution found for pyvirtualcam

ImportError: cannot import name '_native_macos_obs' from partially initialized module 'pyvirtualcam' on macOS

  • Operating system: macOS
  • Python version: 3.10.6
  • pyvirtualcam version: latest (installed from source)
  • Virtual camera (OBS, v4l2loopback, UnityCapture): OBS
  • Virtual camera version: 28.0.3

Describe the bug

>>> import pyvirtualcam
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/rickwierenga/workspace/nomoremeetings/pyvirtualcam/pyvirtualcam/__init__.py", line 3, in <module>
    from .camera import Camera, PixelFormat, Backend, register_backend
  File "/Users/rickwierenga/workspace/nomoremeetings/pyvirtualcam/pyvirtualcam/camera.py", line 112, in <module>
    from pyvirtualcam import _native_macos_obs
ImportError: cannot import name '_native_macos_obs' from partially initialized module 'pyvirtualcam' (most likely due to a circular import) (/Users/rickwierenga/workspace/nomoremeetings/pyvirtualcam/pyvirtualcam/__init__.py)

OBS Virtual Camera not detected on Windows

  • Operating system: Windows 11 Enterprise 21H2 (22000.194)
  • pyvirtualcam version: 0.8.0
  • Virtual camera (OBS, v4l2loopback, UnityCapture): OBS 27.0.1 (64bit Win)
  • Virtual camera version: Built-in to OBS
  • Python version: 3.6.0 64bit (Windows)

Describe the bug
With OBS Virtual camera started, pyvirtualcam is not finding the OBS Device.
Running /samples/simple.py reports:

Traceback (most recent call last):
  File "obs_vcam_test.py", line 4, in <module>
    with pyvirtualcam.Camera(width=1280, height=720, fps=20) as cam:
  File "C:\Users\xxxxxx\AppData\Local\Programs\Python\Python36\lib\site-packages\pyvirtualcam\camera.py", line 219, in __init__
    raise RuntimeError('\n'.join(errors))
RuntimeError: 'obs' backend: virtual camera output could not be started
'unitycapture' backend: No camera registered. Did you install any camera?

Looking at: https://github.com/letmaik/pyvirtualcam/blob/master/pyvirtualcam/native_windows_obs/virtual_output.h#L38
I see it looks up a registry key which is present on my machine:
image

Note; yes it's an old python version; but i'm working with some Tensorflow 1.x code at the moment which needs it :)
I've tested this with python 3.9.2 also, and get the same issue.

To Reproduce
Run samples/simple.py

Cam in use

err:

OBSVirtualVideo handle exists already
shared_queue_check() failed

Maybe there is a way to change the image when the camera is in use?

Feature Request: Build for Linux aarch64/arm64 on PyPI

Hello,

There is currently no way to install this on linux running arm64 via PyPI. I'd like to request this additional build given there are many arm-based linux systems now. Or, perhaps at least adding the source package to PyPI so that it can be built from source via pip.

Thanks

EDIT: I did confirm I can build from source by doing pip install git+https://github.com/letmaik/pyvirtualcam.git so even just making sure that the source tar.gz is available as an option on PyPI is sufficient.

Latency

I'm reading a RTSP Stream from a DVR, and trying to make a virtual webcam device to be available on my Windows 10. It works pretty nice, but there is a delay, about 1,92 sec latency. Tested on other python app and on AMCAP, and always the latency is that high.
Is it related to pyvirtualcam or to OBS stuff? Is there any way to get a lower latency? Thank you all.

load dll failed

After installing pyvirtualcam:
when I import the package as: import pyvirtualcam
always show :
File "C:\Python37_64\lib\site-packages\pyvirtualcam_init_.py", line 3, in
from .camera import Camera
File "C:\Python37_64\lib\site-packages\pyvirtualcam\camera.py", line 11, in
from pyvirtualcam import _native_windows
ImportError: DLL load failed: The specified module could not be found.

Do I need put any other dll in the system path๏ผŸ

Env:
WIndows 10
python 3.7.9 64bit
OBS-VirtualCam 2.0.4

use command:
regsvr32 /n /i:1 "obs-virtualcam\bin\32bit\obs-virtualsource.dll"
regsvr32 /n /i:1 "obs-virtualcam\bin\64bit\obs-virtualsource.dll"

854 * 480 resolution causes "pixel buffer size mismatch" on macOS

  • Operating system: MacOS Venture 13.5
  • Python version: 3.8
  • pyvirtualcam version: 0.10.2
  • Virtual camera (OBS, v4l2loopback, UnityCapture): OBS
  • Virtual camera version: 29.1.3

Describe the bug
...
Running a python script sending frames from a video which has worked perfectly one year ago. The same script keeps on throwing the error

pixel buffer size mismatch

Notes:

  1. This happened no matter which color conversion was done (*any combination).
  2. cv2.imshow() works perfectly.
  3. OBS Studio works perfectly, i.e. sends the same video to a virtual cam which can be seen in Google Meet or Zoom.

To Reproduce
Trying to run from this repository the example script webcam_filter.py

import logging
import argparse
import pyvirtualcam
from pyvirtualcam import PixelFormat
import cv2

parser = argparse.ArgumentParser()
parser.add_argument("--video_path", help="path to input video file", default="video/dicaprio1-silent_rgb.mp4")
parser.add_argument("--fps", action="store_true", help="output fps every second")
parser.add_argument("--device", help="virtual camera device, e.g. /dev/video0 (optional)")
args = parser.parse_args()

print(args.video_path)

video = cv2.VideoCapture(args.video_path)
if not video.isOpened():
    raise ValueError("error opening video")
length = int(video.get(cv2.CAP_PROP_FRAME_COUNT))
width = int(video.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(video.get(cv2.CAP_PROP_FRAME_HEIGHT))
fps = video.get(cv2.CAP_PROP_FPS)

print(f"width {width} height{height}")

with pyvirtualcam.Camera(width=width, height=height, fps=fps, fmt=PixelFormat.BGR,
                         device=args.device) as cam:

    print(f'Virtual cam started: {cam.device} ({cam.width}x{cam.height} @ {cam.fps}fps)')
    # Set the resolution of the virtual camera


    count = 0
    while True:
        # Restart video on last frame.
        if count == length:
            count = 0
            video.set(cv2.CAP_PROP_POS_FRAMES, 0)

        # Read video frame.
        ret, frame = video.read()
        if not ret:
            raise RuntimeError('Error fetching frame')

        cv2.imshow('frame: ', frame)
        # frame = cv2.cvtColor(frame, cv2.COLOR_RGB2BGR)
        # frame = cv2.cvtColor(frame, cv2.COLOR_RGB2BGR) # UVYV

        # Send to virtual cam.
        cam.send(frame)

        # Wait until it's time for the next frame
        cam.sleep_until_next_frame()

        count += 1
image

No video signals from OBS/UnityCapture

  • Operating system: Windows 11 on ARM64
  • pyvirtualcam version: 0.8.0
  • Virtual camera (OBS, v4l2loopback, UnityCapture): OBS and UnityCapture
  • Virtual camera version: OBS 27.1.3

Describe the bug
I never had experience in using a virtual camera before. I don't know the cause of this bug. Maybe it's because of Windows11, or maybe it's because of Windows11 on ARM64.

I ran the 'webcam_filter.py' in the sample folder and found this bug.

Before I run the script, Zoom meeting shows that I have two cameras, a front camera, and a rear camera. And these two cameras work fine.
When using OBS to add a filter on the front camera (camera 0):
After I run the script, Zoom meeting shows that I have three cameras, a front camera, a rear camera, and an OBS camera. I found that the front camera is black, the rear camera works fine, and the OBS camera has no video signals.
When using UnityCapture, it's the same.

I tested that the script does capture the video signal of the front camera by adding a 'cv2.imshow' so I can monitor all the original frames. So I guess the front camera is black in Zoom because the camera is occupied by the script. But why the OBS/UnityCapture camera doesn't have any signals?

To Reproduce

# This scripts uses OpenCV to capture webcam output, applies a filter,
# and sends it to the virtual camera.
# It also shows how to use BGR as pixel format.

import argparse
import cv2
import pyvirtualcam
from pyvirtualcam import PixelFormat

parser = argparse.ArgumentParser()
parser.add_argument("--camera", type=int, default=0, help="ID of webcam device (default: 0)")
parser.add_argument("--fps", action="store_true", help="output fps every second")
parser.add_argument("--filter", choices=["shake", "none"], default="shake")
args = parser.parse_args()

# Set up webcam capture.
vc = cv2.VideoCapture(args.camera, cv2.CAP_DSHOW)

if not vc.isOpened():
    raise RuntimeError('Could not open video source')

pref_width = 1280
pref_height = 720
pref_fps_in = 30
vc.set(cv2.CAP_PROP_FRAME_WIDTH, pref_width)
vc.set(cv2.CAP_PROP_FRAME_HEIGHT, pref_height)
vc.set(cv2.CAP_PROP_FPS, pref_fps_in)

# Query final capture device values (may be different from preferred settings).
width = int(vc.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(vc.get(cv2.CAP_PROP_FRAME_HEIGHT))
fps_in = vc.get(cv2.CAP_PROP_FPS)
print(f'Webcam capture started ({width}x{height} @ {fps_in}fps)')

fps_out = 20

with pyvirtualcam.Camera(width, height, fps_out, fmt=PixelFormat.BGR, print_fps=args.fps) as cam:
    print(f'Virtual cam started: {cam.device} ({cam.width}x{cam.height} @ {cam.fps}fps)')

    # Shake two channels horizontally each frame.
    channels = [[0, 1], [0, 2], [1, 2]]

    while True:
        # Read frame from webcam.
        ret, frame = vc.read()
        # I add this two line to monitor the original frames
        cv2.imshow("test", frame) 
        cv2.waitKey(1)

        if not ret:
            raise RuntimeError('Error fetching frame')

        if args.filter == "shake":
            dx = 15 - cam.frames_sent % 5
            c1, c2 = channels[cam.frames_sent % 3]
            frame[:,:-dx,c1] = frame[:,dx:,c1]
            frame[:,dx:,c2] = frame[:,:-dx,c2]

        # Send to virtual cam.
        cam.send(frame)

        # Wait until it's time for the next frame.
        cam.sleep_until_next_frame()

Resolution of framebuffer is not verified

User passes explicit size here:

void start(int width, int height, double fps, int delay) {
if (!virtual_output_start(width, height, fps, delay))
throw std::runtime_error("error starting virtual camera output");
}

Framebuffer is then passed here:

void send(py::array_t<uint8_t, py::array::c_style> frame) {
py::buffer_info buf = frame.request();
if (buf.ndim != 3)
throw std::runtime_error("ndim must be 3 (h,w,c)");
if (buf.shape[2] != 4)
throw std::runtime_error("frame must have 4 channels (rgba)");
size_t n_lines = buf.shape[0];
size_t line_size = buf.shape[1] * buf.shape[2];
uint8_t** data = (uint8_t**) malloc(sizeof(uint8_t*) * n_lines);
for (size_t i=0; i < n_lines; i++)
data[i] = (uint8_t*)buf.ptr + i*line_size;
virtual_video(data);
free(data);
}

However, the framebuffer can be much larger or smaller than the set width / height. This could lead to buffer-overflows probably.

Not installable on python 32Bit

I tried to install pyvirtualcam on python 3.9 32bit with command pip install pyvirtualcam.

ERROR: Could not find a version that satisfies the requirement pyvirtualcam
ERROR: No matching distribution found for pyvirtualcam

Issue with Selecting Specific UnityCapture Devices in pyvirtualcam

Environment

Operating System: Windows 11
Python Version: 3.12.2
pyvirtualcam Version: Latest
Virtual Camera Used: UnityCapture
Virtual Camera Version: Latest

Describe the bug

I'm encountering a bug when using pyvirtualcam with multiple UnityCapture devices. Specifically, after installing 10 UnityCapture devices and attempting to select and use a device other than the first one through pyvirtualcam, none of the devices function as intended. Instead, all UnityCapture devices mirror the output designated only for the first device.

To Reproduce

  1. Install multiple UnityCapture devices (e.g., 10 devices).
  2. Attempt to use a specific device (other than the first one) using the following script:
frame = np.zeros((480, 640, 3), np.uint8)  
frame[:] = (255, 255, 0)  # yellow

with pyvirtualcam.Camera(width=640, height=480, fps=20, backend="unitycapture", device="Unity Video Capture #2") as cam:
    print(f'Using virtual camera: {cam.device}')
    while True:
        cam.send(frame)
        cam.sleep_until_next_frame()
  1. Running a script intended for the first UnityCapture device subsequently affects all devices:
frame = np.zeros((480, 640, 3), np.uint8)  
frame[:] = (255, 0, 0)  # red

with pyvirtualcam.Camera(width=640, height=480, fps=20, backend="unitycapture", device="Unity Video Capture") as cam:
    print(f'Using virtual camera: {cam.device}')
    while True:
        cam.send(frame)
        cam.sleep_until_next_frame()

Performance drop on M1 Mac

  • Operating system: M1 mac
  • Python version: Python 3.8
  • pyvirtualcam version: Latest
  • Virtual camera (OBS, v4l2loopback, UnityCapture): OBS
  • Virtual camera version: Latest

Describe the bug
Noticeable performance drop when using pyvirtualcam on M1 mac versus Intel mac. Output stream is laggy and has low FPS. Didn't change any of the source code so not sure where I am going wrong.

can't set output resolution

Thanks vor this lib. It works fine for me. But there ist one Problem

After multiple tests it is not possible to set the outputresolution.

cam = pyvirtualcam.Camera(width=1920, height=1080, fps=18, print_fps=True)
cam = pyvirtualcam.Camera(width=1280, height=720, fps=18, print_fps=True)
cam = pyvirtualcam.Camera(width=768, height=432, fps=18, print_fps=True)
cam = pyvirtualcam.Camera(width=480, height=270, fps=18, print_fps=True)
and all with
cam = pyvirtualcam.Camera(480, 270, fps=18, print_fps=True)
all of these inits procuces the same Output: 1920x1080 with very large img sizes
How can I reduce the Quality to get a better stream with bad uploadspeed.
Or how can i set the default output resolution.

v4l2loopback: report per-device errors when no device was chosen

Currently, if device=".." is not used with v4l2loopback then devices from 0 to 100 are tried in sequence and all per-device error messages are swallowed and replaced by a final error "No v4l2 loopback device found..." (there is one exception to this which is that permission errors are raised immediately and not swallowed, as they would appear with all devices). Thus, to diagnose problems, a specific device has to be chosen such that the actual error is returned in the exception. This is annoying and could be improved.

One problem with reporting all per-device errors is that nearly all of them will be "Device ... does not exist" which is not very interesting. Only other kinds of errors should be included in the final exception message to prevent a big wall of text. Alternatively, same error messages could be grouped together.

Few Colors

Hello,

I am using your software which is working on MAC. However, I get the following
message from one of the webcam tests:

Your webcam uses too few colors. Perhaps this is due to poor visibility or bad quality webcam.

How can be resolved?

Thanks

macOS 11: test captures in CI are darker than in 10.15

As far as I see, the only relevant change was GitHub Action's upgrade to macOS 11.

Old:

Current:

In both old and current, the OBS version used in CI was the same: 26.1.2.

Log excerpt showing the diff for current:

FAILED ../test/test_capture.py::test_capture[diff-RGB-obs] - assert 24.0 <= 2
FAILED ../test/test_capture.py::test_capture[diff-BGR-obs] - assert 24.0 <= 2
FAILED ../test/test_capture.py::test_capture[diff-I420-obs] - assert 33.0 <= 2
FAILED ../test/test_capture.py::test_capture[diff-NV12-obs] - assert 33.0 <= 2
FAILED ../test/test_capture.py::test_capture[diff-YUYV-obs] - assert 33.0 <= 2
FAILED ../test/test_capture.py::test_capture[diff-UYVY-obs] - assert 33.0 <= 2

Comparison

This is for UYVY which is the native pixel format of this camera, so theoretically it should be closest to the reference.

Reference

test_UYVY_in

Old

test_UYVY_out_diff_Darwin_obs_py37

Current

test_UYVY_out_diff_Darwin_obs_py37

I'm not sure where the issue is coming from. It would be good to get independent user verification from someone running macOS 11.

I should note that the test capture mechanism used here relies on OpenCV's VideoCapture, but the OpenCV Python package version is pinned to 4.5.1.48 (see dev-requirements.txt for why), both in old and current.

Things to try:

  1. Bumping the OBS version in CI to the latest is worth a try, maybe some fixes were needed for macOS 11, though it's unlikely. EDIT: Tried that but didn't help: https://github.com/letmaik/pyvirtualcam/runs/5300762692

  2. Run the CI workflow to use macOS 10.15 which is still available. Currently it uses macos-latest which switched to macos 11 recently. EDIT: This avoids the issue! https://github.com/letmaik/pyvirtualcam/actions/runs/1886403645

Status: To keep CI green, I switched back to 10.15 in the meantime. EDIT: CI is now using macOS 11 because 10.15 is EOL. The capture tests have been relaxed to accept a larger diff for macOS. See #96.

Call for help: If someone has macOS 11, try the following experiment and report back:

  1. Output a fixed test image on the virtual camera in OBS (the app, not using Python).
  2. Start some video app like Zoom and take a screenshot of the virtual cam image.
  3. Check if they are identical or not.
  4. If the screenshot is darker, then the issue can be reported to OBS and is not related to pyvirtualcam.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.