objective c - Cocoa - detect event when camera started recording -
in osx application i'm using code below show preview camera.
[[self session] beginconfiguration]; nserror *error = nil; avcapturedeviceinput *newvideodeviceinput = [avcapturedeviceinput deviceinputwithdevice:capturedevice error:&error]; if (capturedevice != nil) { [[self session] removeinput: [self videodeviceinput]]; if([[self session] canaddinput: newvideodeviceinput]) { [[self session] addinput:newvideodeviceinput]; [self setvideodeviceinput:newvideodeviceinput]; } else { dlog(@"wtf?"); } } [[self session] commitconfiguration];
yet, need detect exact time when preview camera becomes available.
in other words i'm trying detect same moment in facetime under osx, animation starts once camera provides preview.
what best way achieve this?
i know question old, stumbled upon when looking same question, , have found answers here goes.
for starters, avfoundation high level, you'll need drop down lower level, coremediaio. there's not lot of documentation on this, need perform couple queries.
to this, we'll use combination of calls. first, cmioobjectgetpropertydatasize
lets size of data we'll query next, can use when call cmioobjectgetpropertydata
. set property data size call, need start @ top, using property address:
var opa = cmioobjectpropertyaddress( mselector: cmioobjectpropertyselector(kcmiohardwarepropertydevices), mscope: cmioobjectpropertyscope(kcmioobjectpropertyscopeglobal), melement: cmioobjectpropertyelement(kcmioobjectpropertyelementmaster) )
next, we'll set variables keep data we'll need:
var (datasize, dataused) = (uint32(0), uint32(0)) var result = cmioobjectgetpropertydatasize(cmioobjectid(kcmioobjectsystemobject), &opa, 0, nil, &datasize) var devices: unsafemutablerawpointer? = nil
from point on, we'll need wait until data out, let's busy loop:
repeat { if devices != nil { free(devices) devices = nil } devices = malloc(int(datasize)) result = cmioobjectgetpropertydata(cmioobjectid(kcmioobjectsystemobject), &opa, 0, nil, datasize, &dataused, devices); } while result == osstatus(kcmiohardwarebadpropertysizeerror)
once past point in our execution, devices
point potentially many devices. need loop through them, this:
if let devices = devices { offset in stride(from: 0, to: datasize, by: memorylayout<cmioobjectid>.size) { let current = devices.advanced(by: int(offset)).assumingmemorybound(to: cmioobjectid.self) // current.pointee object id want keep track of somehow } }
finally, clean devices
free(devices)
now @ point, you'll want use object id saved above make query. need new property address:
var cmioobjectpropertyaddress( mselector: cmioobjectpropertyselector(kcmiodevicepropertydeviceisrunningsomewhere), mscope: cmioobjectpropertyscope(kcmioobjectpropertyscopewildcard), melement: cmioobjectpropertyelement(kcmioobjectpropertyelementwildcard) )
this tells coremediaio want know if device running somewhere (read: in app), wildcarding rest of fields. next meat of query, camera
below corresponds id saved before:
var (datasize, dataused) = (uint32(0), uint32(0)) var result = cmioobjectgetpropertydatasize(camera, &opa, 0, nil, &datasize) if result == osstatus(kcmiohardwarenoerror) { if let data = malloc(int(datasize)) { result = cmioobjectgetpropertydata(camera, &opa, 0, nil, datasize, &dataused, data) let on = data.assumingmemorybound(to: uint8.self) // on.pointee != 0 means it's in use somewhere, 0 means not in use anywhere } }
with above code samples should have enough test whether or not camera in use. need device once (the first part of answer); check if it's in use however, you'll have @ time want information. exercise, consider playing cmioobjectaddpropertylistenerblock
notified on event changes in use property address used above.
while answer 3 years late op, hope helps in future. examples here given swift 3.0.
Comments
Post a Comment