Estoy tratando de capturar un solo fotograma de la cámara Apple iSight integrada en un Macbook Pro usando Python (versión 2.7 o 2.6) y el PyObjC (versión 2.2).Cómo capturar marcos de Apple iSight usando Python y PyObjC?
Como punto de partida, utilicé la pregunta this old StackOverflow. Para verificar que tenga sentido, hice una referencia cruzada contra el ejemplo Apple's MyRecorder que parece estar basado en. Desafortunadamente, mi script no funciona.
Mis grandes preguntas son:
- Am I inicializar la cámara correctamente?
- ¿Estoy iniciando correctamente el ciclo de eventos?
- ¿Había alguna otra configuración que se suponía que debía hacer?
En el script de ejemplo pegado a continuación, la operación prevista es que después de llamar a startImageCapture(), debería comenzar a imprimir los mensajes "Obtuve un fotograma ..." de CaptureDelegate. Sin embargo, la luz de la cámara nunca se enciende y la devolución de llamada del delegado nunca se ejecuta.
Además, no hay fallas durante startImageCapture(), todas las funciones pretenden tener éxito y encuentra con éxito el dispositivo iSight. El análisis del objeto de sesión en pdb muestra que tiene objetos de entrada y salida válidos, la salida tiene un delegado asignado, el dispositivo no está siendo utilizado por otro proceso y la sesión se marca como ejecutada después de llamar a startRunning().
Aquí está el código:
#!/usr/bin/env python2.7
import sys
import os
import time
import objc
import QTKit
import AppKit
from Foundation import NSObject
from Foundation import NSTimer
from PyObjCTools import AppHelper
objc.setVerbose(True)
class CaptureDelegate(NSObject):
def captureOutput_didOutputVideoFrame_withSampleBuffer_fromConnection_(self, captureOutput,
videoFrame, sampleBuffer,
connection):
# This should get called for every captured frame
print "Got a frame: %s" % videoFrame
class QuitClass(NSObject):
def quitMainLoop_(self, aTimer):
# Just stop the main loop.
print "Quitting main loop."
AppHelper.stopEventLoop()
def startImageCapture():
error = None
# Create a QT Capture session
session = QTKit.QTCaptureSession.alloc().init()
# Find iSight device and open it
dev = QTKit.QTCaptureDevice.defaultInputDeviceWithMediaType_(QTKit.QTMediaTypeVideo)
print "Device: %s" % dev
if not dev.open_(error):
print "Couldn't open capture device."
return
# Create an input instance with the device we found and add to session
input = QTKit.QTCaptureDeviceInput.alloc().initWithDevice_(dev)
if not session.addInput_error_(input, error):
print "Couldn't add input device."
return
# Create an output instance with a delegate for callbacks and add to session
output = QTKit.QTCaptureDecompressedVideoOutput.alloc().init()
delegate = CaptureDelegate.alloc().init()
output.setDelegate_(delegate)
if not session.addOutput_error_(output, error):
print "Failed to add output delegate."
return
# Start the capture
print "Initiating capture..."
session.startRunning()
def main():
# Open camera and start capturing frames
startImageCapture()
# Setup a timer to quit in 10 seconds (hack for now)
quitInst = QuitClass.alloc().init()
NSTimer.scheduledTimerWithTimeInterval_target_selector_userInfo_repeats_(10.0,
quitInst,
'quitMainLoop:',
None,
False)
# Start Cocoa's main event loop
AppHelper.runConsoleEventLoop(installInterrupt=True)
print "After event loop"
if __name__ == "__main__":
main()
Gracias por cualquier ayuda que puede proporcionar!
Cool man, por cierto, debe marcar su propio aceptar como 'aceptado' :) –
Este script funciona muy bien, pero falla al escribir el archivo de bytes. Deberías cambiar la apertura ('nombre de archivo', 'w') para abrir ('nombre de archivo', 'wb') para abrir un archivo en modo byte, luego funciona. – andli