Problem: I am trying to use a python function, capture_image(unique_id, dest_filename), for MacOS that is supposed to capture a still image from a video camera using the AVFoundation framework and the pyobjc-framework-AVFoundation framework.
Expected result: Given an AVFoundation unique_id and a dest_filename passed as parameters, a JPG still image should be captured from the camera with AVFoundation unique id. The image should be written to the JPG file with the name dest_filename.
In my test I called this function 5 times and I expected to see this output:
writing /tmp/images/image_1.jpg
writing /tmp/images/image_2.jpg
writing /tmp/images/image_3.jpg
writing /tmp/images/image_4.jpg
writing /tmp/images/image_5.jpg
list_of_image_files_written=['image_1.jpg','image_2.jpg','image_3.jpg','image_4.jpg','image_5.jpg']
Process finished with exit code 0
Observed result: The function silently fails to write the captured image to the desired file.
No Runtime errors are thrown.
In my test I called this function 5 times and I actually saw output (note that image directory is actually empty - no JPGs were actually written:
writing /tmp/images/image_1.jpg
writing /tmp/images/image_2.jpg
writing /tmp/images/image_3.jpg
writing /tmp/images/image_4.jpg
writing /tmp/images/image_5.jpg
list_of_image_files_written=[]
Process finished with exit code 0
The Pycharm IDE does show these compile time errors and warnings:
- Unresolved reference 'NSData': 31
- Unresolved reference 'NSDataWritingAtomic': 32
- Cannot find reference 'AVCaptureSession' in '__init__py | __init__py: 8
- Cannot find reference 'AVCaptureDevice' in '__init__py | __init__py: 9
- Cannot find reference 'AVMediaTypeVideo' in '__init__py | __init__py: 9
- Cannot find reference 'AVCaptureDeviceInput' in '__init__py | __init__py: 17
- Cannot find reference 'AVCaptureStillImageOutput' in '__init__py | __init__py: 18
- Cannot find reference 'AVMediaTypeVideo' in '__init__py | __init__py: 27
- Cannot find reference 'AVVideoCodecKey' in '__init__py | __init__py: 28
- Cannot find reference 'AVVideoCodecTypeJPEG' in '__init__py | __init__py: 28
- Cannot find reference 'AVCaptureStillImageOutput' in '__init__py | __init__py: 31
- Local variable 'output_settings' value is not used: 28
- PEP 8: E128 continuation line under_indented for visual indent: 30
- PEP 8: E128 continuation line under_indented for visual indent: 31
I am running on MacOS Ventura 13.2.1 using PyCharm.
I have searched the AVFoundation webpages as well as OpenStack and google, but without success in finding a better example.
The code:
import os
import AVFoundation
import time
def capture_image(unique_id, dest_filename):
# Set up AVFoundation capture session
session = AVFoundation.AVCaptureSession.alloc().init()
devices = AVFoundation.AVCaptureDevice.devicesWithMediaType_(AVFoundation.AVMediaTypeVideo)
device = None
for dev in devices:
if dev.uniqueID() == unique_id:
device = dev
break
if device is None:
raise ValueError("No camera found with unique ID: " + unique_id)
input_session = AVFoundation.AVCaptureDeviceInput.deviceInputWithDevice_error_(device, None)[0]
output_session = AVFoundation.AVCaptureStillImageOutput.alloc().init()
session.addInput_(input_session)
session.addOutput_(output_session)
session.startRunning()
# Wait for the capture to be ready
time.sleep(2)
# Capture the image
connection = output_session.connectionWithMediaType_(AVFoundation.AVMediaTypeVideo)
output_settings = {AVFoundation.AVVideoCodecKey: AVFoundation.AVVideoCodecTypeJPEG}
output_session.captureStillImageAsynchronouslyFromConnection_completionHandler_(connection,
lambda buffer, error:
NSData.dataWithData_(AVFoundation.AVCaptureStillImageOutput.jpegStillImageNSDataRepresentation_(buffer))
.writeToFile_options_error_(dest_filename, NSDataWritingAtomic, None))
# Stop the session
session.stopRunning()
print(f'writing {dest_filename}')
return dest_filename
if __name__ == '__main__':
images_dict = {
'0x143141300bda5829': '/tmp/images/image_1.jpg',
'0x143141100bda5829': '/tmp/images/image_2.jpg',
'0x143200000bda5829': '/tmp/images/image_3.jpg',
'0x143300000bda5829': '/tmp/images/image_4.jpg',
'0x143121200bda5829': '/tmp/images/image_5.jpg',
}
for the_unique_id in images_dict:
capture_image(the_unique_id, images_dict[the_unique_id])
list_of_image_files_written = os.listdir('/tmp/images')
print(f'{list_of_image_files_written=}')
from MacOS capture of still image from AVFoundation camera silently fails
No comments:
Post a Comment