How can I capture iSight frames with Python in Snow Leopard?

isight, osx-snow-leopard, pyobjc, python, qtkit

Solution

Your problem here is that you don't have an event loop. If you want to do this as a standalone script, you'll have to figure out how to create one. The PyObjC XCode templates automatically set that up for you with:

from PyObjCTools import AppHelper
AppHelper.runEventLoop()

Trying to insert that at the top of your script, however, shows that something inside `AppHelper` (probably `NSApplicationMain`) expects a plist file to extract the main class from. You can get that by creating a `setup.py` file and using `py2app`, something like this example from a PyObjc talk:

from distutils.core import setup
import py2app
plist = dict(
    NSPrincipalClass='SillyBalls',
)
setup(
    plugin=['SillyBalls.py'],
    data_files=['English.lproj'],
    options=dict(py2app=dict(
        extension='.saver',
        plist=plist,
    )),
)

Problem

I have the following PyObjC script: ``` from Foundation import NSObject import QTKit error = None capture_session = QTKit.QTCaptureSession.alloc().init() print 'capture_session', capture_session device = QTKit.QTCaptureDevice.defaultInputDeviceWithMediaType_(QTKit.QTMediaTypeVideo) print 'device', device, type(device) success = device.open_(error) print 'device open success', success, error if not success: raise Exception(error) capture_device_input = QTKit.QTCaptureDeviceInput.alloc().initWithDevice_(device) print 'capture_device_input', capture_device_input, capture_device_input.device() success = capture_session.addInput_error_(capture_device_input, error) print 'session add input success', success, error if not success: raise Exception(error) capture_decompressed_video_output = QTKit.QTCaptureDecompressedVideoOutput.alloc().init() print 'capture_decompressed_video_output', capture_decompressed_video_output class Delegate(NSObject): def captureOutput_didOutputVideoFrame_withSampleBuffer_fromConnection_(self, captureOutput, videoFrame, sampleBuffer, connection): print videoFrame, sampleBuffer, connection delegate = Delegate.alloc().init() print 'delegate', delegate capture_decompressed_video_output.setDelegate_(delegate) print 'output delegate:', capture_decompressed_video_output.delegate() success = capture_session.addOutput_error_(capture_decompressed_video_output, error) print 'capture session add output success', success, error if not success: raise Exception(error) print 'about to run session', capture_session, 'with inputs', capture_session.inputs(), 'and outputs', capture_session.outputs() capture_session.startRunning() print 'capture session is running?', capture_session.isRunning() import time time.sleep(10) ``` The program reports no errors, but iSight's green light is never activated and the delegate's frame capture callback is never called. Here's the output I get: ``` $ python prueba.py capture_session <QTCaptureSession: 0x1006c16f0> device Built-in iSight <objective-c class QTCaptureDALDevice at 0x7fff70366aa8> device open success (True, None) None capture_device_input <QTCaptureDeviceInput: 0x1002ae010> Built-in iSight session add input success (True, None) None capture_decompressed_video_output <QTCaptureDecompressedVideoOutput: 0x104239f10> delegate <Delegate: 0x10423af50> output delegate: <Delegate: 0x10423af50> capture session add output success (True, None) None about to run session <QTCaptureSession: 0x1006c16f0> with inputs ( "<QTCaptureDeviceInput: 0x1002ae010>" ) and outputs ( "<QTCaptureDecompressedVideoOutput: 0x104239f10>" ) capture session is running? True ``` PS: Please don't answer I should try PySight, I have but it won't work because Xcode can't compile CocoaSequenceGrabber in 64bit.

Original source