letmaik / pyvirtualcam

🎥 Send frames to a virtual camera from Python
GNU General Public License v2.0
452 stars 49 forks source link

No video signals from OBS/UnityCapture #76

Closed wangfys closed 2 years ago

wangfys commented 2 years ago

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()
wangfys commented 2 years ago

Okay, it seems like the OBS Studio itself can't produce video signals for the OBS camera. Maybe it's just a Windows11 or Windows11 on ARM64 problem.