Open totaam opened 6 years ago
Found a better code sample to start from : PyImageSnap. It doesn't work for me, but that could just be virtualbox's USB pass-through causing problems.
And a screen recording example here https://gist.github.com/timsutton/0c6439eb6eb1621a5964:
#!/usr/bin/python
# pylint: disable-msg=e1101,e0611
import time
import AVFoundation as AVF
import Quartz
from Foundation import NSObject, NSURL
def main():
display_id = Quartz.CGMainDisplayID()
session = AVF.AVCaptureSession.alloc().init()
screen_input = AVF.AVCaptureScreenInput.alloc().initWithDisplayID_(display_id)
file_output = AVF.AVCaptureMovieFileOutput.alloc().init()
session.addInput_(screen_input)
session.addOutput_(file_output)
session.startRunning()
file_url = NSURL.fileURLWithPath_('foo.mov')
# Cheat and pass a dummy delegate object where normally we'd have a
# AVCaptureFileOutputRecordingDelegate
file_url = file_output.startRecordingToOutputFileURL_recordingDelegate_(
file_url, NSObject.alloc().init())
time.sleep(10)
session.stopRunning()
if __name__ == '__main__':
main()
Managed to put together a screen recording-to-delegate example based on the one above
#!/usr/bin/python
import time
import AVFoundation as AVF
import Quartz
import libdispatch
from Foundation import NSObject, NSURL
def main():
display_id = Quartz.CGMainDisplayID()
session = AVF.AVCaptureSession.alloc().init()
screen_input = AVF.AVCaptureScreenInput.alloc().initWithDisplayID_(display_id)
screen_input.setCapturesCursor_(True)
screen_input.setCapturesMouseClicks_(True)
screen_input.setScaleFactor_(1.0)
output = AVF.AVCaptureVideoDataOutput.alloc().init()
output.setAlwaysDiscardsLateVideoFrames_(True)
print("codecs:", output.availableVideoCodecTypes())
print("pixel formats:", output.availableVideoCVPixelFormatTypes())
class SampleBufferDelegate(NSObject):
def captureOutput_didOutputSampleBuffer_fromConnection_(self, captureOutput, sampleBuffer, connection):
print("captureOutput: captureOutput=%s, sampleBuffer=%s, connection=%s",
captureOutput, sampleBuffer, connection,
)
def captureOutput_didDropSampleBuffer_fromConnection_(self, captureOutput, sampleBuffer, connection):
print("dropped a frame!")
delegate = SampleBufferDelegate.alloc().init()
queue = libdispatch.dispatch_queue_create(b"Image Queue", None)
output.setSampleBufferDelegate_queue_(delegate, queue)
session.addInput_(screen_input)
session.addOutput_(output)
session.startRunning()
print("connections=", output.connections())
time.sleep(10)
session.stopRunning()
if __name__ == '__main__':
main()
avf.py
(5.2 KiB)more complete example
This OBS commit might be what we need: https://github.com/obsproject/obs-studio/pull/5875/commits/551c54ba8440fcdf4cdc221f5d50a30a68b87a7e
The API we currently use (CGRegisterScreenRefreshCallback)is deprecated, we have to switch to AVCaptureSession and AVCaptureScreenInput.
This may be blocked by the same bug as #1231, see [/attachment/ticket/1231/webcam_avfoundation.py].