This repository has been archived by the owner on Apr 4, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 441
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
#699 Add ML Kit support (iOS camera stream)
- Loading branch information
1 parent
ebdb66a
commit a79d05e
Showing
30 changed files
with
833 additions
and
27 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
import { ImageSource } from "tns-core-modules/image-source"; | ||
import { MLKitDetectFacesOptions, MLKitDetectFacesResult } from "./"; | ||
import { MLKitOptions } from "../index"; | ||
|
||
// export class MLKitFaceDetection extends MLKitFaceDetectionBase { | ||
// constructor() { | ||
// super(); | ||
// console.log(">>> MLKitFaceDetection constr"); | ||
// } | ||
// } | ||
|
||
export function detectFaces(options: MLKitDetectFacesOptions): Promise<MLKitDetectFacesResult> { | ||
return new Promise((resolve, reject) => { | ||
try { | ||
const firVision: FIRVision = FIRVision.vision(); | ||
const faceDetector: FIRVisionFaceDetector = firVision.faceDetector(); | ||
|
||
faceDetector.detectInImageCompletion(getImage(options), (faces: NSArray<FIRVisionFace>, error: NSError) => { | ||
if (error !== null) { | ||
reject(error.localizedDescription); | ||
|
||
} else if (faces !== null) { | ||
const result = <MLKitDetectFacesResult>{ | ||
faces: [] | ||
}; | ||
|
||
for (let i = 0, l = faces.count; i < l; i++) { | ||
const face: FIRVisionFace = faces.objectAtIndex(i); | ||
result.faces.push({ | ||
smilingProbability: face.hasSmilingProbability ? face.smilingProbability : undefined, | ||
leftEyeOpenProbability: face.hasLeftEyeOpenProbability ? face.leftEyeOpenProbability : undefined, | ||
rightEyeOpenProbability: face.hasRightEyeOpenProbability ? face.rightEyeOpenProbability : undefined | ||
}); | ||
} | ||
resolve(result); | ||
} | ||
}); | ||
} catch (ex) { | ||
console.log("Error in firebase.mlkit.detectFaces: " + ex); | ||
reject(ex); | ||
} | ||
}); | ||
} | ||
|
||
// TODO move | ||
function getImage(options: MLKitOptions): FIRVisionImage { | ||
const image: UIImage = options.image instanceof ImageSource ? options.image.ios : options.image.imageSource.ios; | ||
return FIRVisionImage.alloc().initWithImage(image); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
import { ContentView } from "tns-core-modules/ui/content-view"; | ||
|
||
// TODO pause/resume handling | ||
export abstract class MLKitCameraView extends ContentView { | ||
private captureSession: AVCaptureSession; | ||
private captureDevice: AVCaptureDevice; | ||
private previewLayer: CALayer; | ||
private cameraView: TNSMLKitCameraView; | ||
|
||
private bytesToByteBuffer = new Map(); | ||
private pendingFrameData = null; | ||
protected rotation; | ||
protected lastVisionImage; | ||
|
||
createNativeView(): Object { | ||
let v = super.createNativeView(); | ||
|
||
if (this.canUseCamera()) { | ||
this.initView(); | ||
} else { | ||
console.log("There's no Camera on this device :("); | ||
} | ||
return v; | ||
} | ||
|
||
private canUseCamera() { | ||
// TODO also check for availability of AVCaptureDeviceDiscoverySession (iOS 10) | ||
return AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo) !== null; | ||
} | ||
|
||
private initView() { | ||
// if (this.preferFrontCamera) { | ||
// this._reader.switchDeviceInput(); | ||
// } | ||
|
||
// find a suitable device | ||
this.captureDevice = AVCaptureDeviceDiscoverySession.discoverySessionWithDeviceTypesMediaTypePosition( | ||
<any>[AVCaptureDeviceTypeBuiltInWideAngleCamera], | ||
AVMediaTypeVideo, | ||
AVCaptureDevicePosition.Back | ||
).devices.firstObject; | ||
|
||
// begin the session | ||
this.captureSession = AVCaptureSession.new(); | ||
this.captureSession.sessionPreset = AVCaptureSessionPresetMedium; | ||
|
||
const captureDeviceInput = AVCaptureDeviceInput.deviceInputWithDeviceError(this.captureDevice); | ||
this.captureSession.addInput(captureDeviceInput); | ||
|
||
this.previewLayer = AVCaptureVideoPreviewLayer.layerWithSession(this.captureSession); | ||
|
||
if (this.ios) { | ||
this.ios.layer.addSublayer(this.previewLayer); | ||
} | ||
|
||
this.captureSession.startRunning(); | ||
|
||
this.cameraView = TNSMLKitCameraView.alloc().initWithCaptureSession(this.captureSession); | ||
this.cameraView.processEveryXFrames = 5; | ||
this.cameraView.delegate = TNSMLKitCameraViewDelegateImpl.createWithOwnerResultCallbackAndOptions( | ||
new WeakRef(this), | ||
data => { | ||
}, | ||
{}); | ||
} | ||
|
||
public onLayout(left: number, top: number, right: number, bottom: number): void { | ||
super.onLayout(left, top, right, bottom); | ||
if (this.ios && this.canUseCamera) { | ||
this.previewLayer.frame = this.ios.layer.bounds; | ||
} | ||
} | ||
|
||
abstract createDetector(): any; | ||
|
||
abstract createSuccessListener(): any; | ||
} | ||
|
||
class TNSMLKitCameraViewDelegateImpl extends NSObject implements TNSMLKitCameraViewDelegate { | ||
public static ObjCProtocols = [TNSMLKitCameraViewDelegate]; | ||
|
||
private owner: WeakRef<MLKitCameraView>; | ||
private resultCallback: (message: any) => void; | ||
private options?: any; | ||
|
||
private detector: any; | ||
private onSuccessListener: any; | ||
|
||
public static createWithOwnerResultCallbackAndOptions(owner: WeakRef<MLKitCameraView>, callback: (message: any) => void, options?: any): TNSMLKitCameraViewDelegateImpl { | ||
let delegate = <TNSMLKitCameraViewDelegateImpl>TNSMLKitCameraViewDelegateImpl.new(); | ||
delegate.owner = owner; | ||
delegate.options = options; | ||
delegate.resultCallback = callback; | ||
delegate.detector = owner.get().createDetector(); | ||
delegate.onSuccessListener = owner.get().createSuccessListener(); | ||
return delegate; | ||
} | ||
|
||
cameraDidOutputSampleBuffer(image: UIImage): void { | ||
if (image) { | ||
this.detector.detectInImageCompletion(FIRVisionImage.alloc().initWithImage(image), this.onSuccessListener); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | ||
<plist version="1.0"> | ||
<dict> | ||
<key>NSCameraUsageDescription</key> | ||
<string/> | ||
</dict> | ||
</plist> |
Oops, something went wrong.