@nativescript-community/ui-cameraview
Version:
A CameraView allowing custom live processing for NativeScript
356 lines • 15 kB
JavaScript
import { CameraViewBase, ScaleType, autoFocusProperty, flashModeProperty, frontMirroredProperty, stretchProperty, zoomProperty } from './index.common';
import { Property, Utils } from '@nativescript/core';
function getScaleType(scaleType) {
if (typeof scaleType === 'string') {
switch (scaleType) {
case ScaleType.FitCenter:
case ScaleType.AspectFit:
case ScaleType.FitEnd:
case ScaleType.FitStart:
return AVLayerVideoGravityResizeAspect;
default:
case ScaleType.Center:
case ScaleType.Fill:
case ScaleType.AspectFill:
return AVLayerVideoGravityResizeAspectFill;
}
}
return AVLayerVideoGravityResizeAspectFill;
}
export function deviceHasCamera() {
return NextLevel.shared.canCapturePhoto;
}
var ProcessRawVideoSampleBufferDelegateImpl = /** @class */ (function (_super) {
__extends(ProcessRawVideoSampleBufferDelegateImpl, _super);
function ProcessRawVideoSampleBufferDelegateImpl() {
return _super !== null && _super.apply(this, arguments) || this;
}
ProcessRawVideoSampleBufferDelegateImpl.prototype.cameraViewRenderToCustomContextWithImageBufferOnQueue = function (cameraView, imageBuffer, queue) { };
ProcessRawVideoSampleBufferDelegateImpl.prototype.cameraViewWillProcessRawVideoSampleBufferOnQueue = function (cameraView, sampleBuffer, queue) {
var _a, _b, _c;
var owner = (_a = this._owner) === null || _a === void 0 ? void 0 : _a.get();
(_c = (_b = this._owner) === null || _b === void 0 ? void 0 : _b.get()) === null || _c === void 0 ? void 0 : _c.notify({ eventName: 'frame', object: owner, cameraView: cameraView, sampleBuffer: sampleBuffer, queue: queue });
};
ProcessRawVideoSampleBufferDelegateImpl.initWithOwner = function (owner) {
var delegate = ProcessRawVideoSampleBufferDelegateImpl.new();
delegate._owner = new WeakRef(owner);
return delegate;
};
ProcessRawVideoSampleBufferDelegateImpl.ObjCProtocols = [ProcessRawVideoSampleBufferDelegate];
return ProcessRawVideoSampleBufferDelegateImpl;
}(NSObject));
var NSCameraViewVideoDelegateImpl = /** @class */ (function (_super) {
__extends(NSCameraViewVideoDelegateImpl, _super);
function NSCameraViewVideoDelegateImpl() {
return _super !== null && _super.apply(this, arguments) || this;
}
NSCameraViewVideoDelegateImpl.prototype.cameraViewDidCompletePhotoCaptureFromVideoFrame = function (cameraView, photoDict) {
var _a, _b;
(_b = (_a = this._owner) === null || _a === void 0 ? void 0 : _a.get()) === null || _b === void 0 ? void 0 : _b.cameraViewDidCompletePhotoCaptureFromVideoFrame(photoDict);
};
NSCameraViewVideoDelegateImpl.initWithOwner = function (owner) {
var delegate = NSCameraViewVideoDelegateImpl.new();
delegate._owner = new WeakRef(owner);
return delegate;
};
NSCameraViewVideoDelegateImpl.ObjCProtocols = [NSCameraViewVideoDelegate];
return NSCameraViewVideoDelegateImpl;
}(NSObject));
var NSCameraViewPhotoDelegateImpl = /** @class */ (function (_super) {
__extends(NSCameraViewPhotoDelegateImpl, _super);
function NSCameraViewPhotoDelegateImpl() {
return _super !== null && _super.apply(this, arguments) || this;
}
NSCameraViewPhotoDelegateImpl.prototype.cameraViewDidCapturePhotoWithConfiguration = function (cameraView, photoConfiguration) { };
NSCameraViewPhotoDelegateImpl.prototype.cameraViewDidFinishProcessingPhotoPhotoDictPhotoConfiguration = function (cameraView, photo, photoDict, photoConfiguration) {
var _a, _b;
// TODO: move this to swift
var size = photo.size;
UIGraphicsBeginImageContextWithOptions(size, false, photo.scale);
photo.drawInRect(CGRectMake(0, 0, size.width, size.height));
var resizedImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
(_b = (_a = this._owner) === null || _a === void 0 ? void 0 : _a.get()) === null || _b === void 0 ? void 0 : _b.cameraViewDidFinishProcessingPhotoPhotoDictPhotoConfiguration(resizedImage, photoDict);
};
NSCameraViewPhotoDelegateImpl.initWithOwner = function (owner) {
var delegate = NSCameraViewPhotoDelegateImpl.new();
delegate._owner = new WeakRef(owner);
return delegate;
};
NSCameraViewPhotoDelegateImpl.ObjCProtocols = [NSCameraViewPhotoDelegate];
return NSCameraViewPhotoDelegateImpl;
}(NSObject));
var NSCameraViewDelegateImpl = /** @class */ (function (_super) {
__extends(NSCameraViewDelegateImpl, _super);
function NSCameraViewDelegateImpl() {
return _super !== null && _super.apply(this, arguments) || this;
}
NSCameraViewDelegateImpl.prototype.sessionDidStart = function (cameraView) {
var owner = this._owner.get();
if (owner) {
owner.notify({ eventName: 'cameraOpen' });
}
};
NSCameraViewDelegateImpl.prototype.sessionDidStop = function (cameraView) {
var owner = this._owner.get();
if (owner) {
owner.notify({ eventName: 'cameraClose' });
}
};
NSCameraViewDelegateImpl.prototype.didUpdateVideoZoomFactor = function (zoom) {
var owner = this._owner.get();
if (owner) {
owner.notify({ eventName: 'zoom', zoom: zoom });
}
};
NSCameraViewDelegateImpl.initWithOwner = function (owner) {
var delegate = NSCameraViewDelegateImpl.new();
delegate._owner = new WeakRef(owner);
return delegate;
};
NSCameraViewDelegateImpl.ObjCProtocols = [NSCameraViewDelegate];
return NSCameraViewDelegateImpl;
}(NSObject));
export const iosCaptureModeProperty = new Property({
name: 'iosCaptureMode',
defaultValue: 1
});
export class CameraView extends CameraViewBase {
constructor() {
super(...arguments);
this.videoCaptureListener = new Set();
this.photoCaptureListener = new Set();
this._frameChangeCount = 0;
this.previewStarted = false;
}
cameraViewDidFinishProcessingPhotoPhotoDictPhotoConfiguration(photo, photoDict) {
// const cgImage = photo.CGImageRepresentation();
// const orientation = photo.metadata.objectForKey(kCGImagePropertyOrientation);
// const image = UIImage.imageWithCGImageScaleOrientation(cgImage, 1, orientation);
this.photoCaptureListener.forEach((c) => c(photo, photoDict));
}
cameraViewDidProcessPhotoCaptureWithPhotoConfiguration(photoDict) { }
cameraViewDidCompletePhotoCaptureFromVideoFrame(photoDict) {
this.videoCaptureListener.forEach((c) => c(photoDict));
}
createNativeView() {
return NSCameraView.alloc().initWithFrame(CGRectZero);
}
initNativeView() {
super.initNativeView();
const nativeView = this.nativeViewProtected;
nativeView.photoDelegate = this.photoDelegate = NSCameraViewPhotoDelegateImpl.initWithOwner(this);
nativeView.videoDelegate = this.videoDelegate = NSCameraViewVideoDelegateImpl.initWithOwner(this);
nativeView.delegate = this.delegate = NSCameraViewDelegateImpl.initWithOwner(this);
}
disposeNativeView() {
this.stopPreview();
this.detachProcessor();
const nativeView = this.nativeViewProtected;
nativeView.videoDelegate = this.videoDelegate = null;
nativeView.photoDelegate = this.photoDelegate = null;
nativeView.delegate = this.delegate = null;
super.disposeNativeView();
}
get processor() {
return this._processor;
}
set processor(value) {
this._processor = value;
if (this.nativeViewProtected) {
this.nativeViewProtected.processingDelegate = this._processor;
}
}
get minZoom() {
return this.nativeViewProtected?.minVideoZoomFactor;
}
get maxZoom() {
return this.nativeViewProtected?.maxVideoZoomFactor;
}
get neutralZoom() {
return this.nativeViewProtected?.neutralVideoZoomFactor;
}
addEventListener(arg, callback, thisArg) {
super.addEventListener(arg, callback, thisArg);
if (arg === CameraViewBase.FRAME_EVENT) {
this._frameChangeCount++;
this.createProcessor();
}
}
removeEventListener(arg, callback, thisArg) {
super.removeEventListener(arg, callback, thisArg);
if (arg === CameraViewBase.FRAME_EVENT) {
this._frameChangeCount--;
if (this._frameChangeCount === 0) {
this.detachProcessor();
}
}
}
createProcessor() {
if (!this.processor) {
this.processor = ProcessRawVideoSampleBufferDelegateImpl.initWithOwner(this);
if (this.nativeViewProtected) {
this.nativeViewProtected.processingDelegate = this.processor;
}
}
}
detachProcessor() {
if (this.processor) {
if (this.nativeViewProtected) {
this.nativeViewProtected.processingDelegate = null;
}
this.processor = null;
}
}
onLoaded() {
super.onLoaded();
if (this.processor) {
this.nativeViewProtected.processingDelegate = this.processor;
}
this.startPreview();
}
onUnloaded() {
this.stopPreview();
this.nativeViewProtected.processingDelegate = null;
super.onUnloaded();
}
startPreview() {
const nativeView = this.nativeViewProtected;
if (!nativeView || this.previewStarted || !this.readyToStartPreview) {
return;
}
this.previewStarted = true;
nativeView.startPreviewAndReturnError();
}
stopPreview() {
if (!this.previewStarted) {
return;
}
this.previewStarted = false;
this.nativeViewProtected?.stopPreview();
}
focusAtPoint(x, y) {
// NextLevel expects a point between 0,1
const width = this.getMeasuredWidth();
const height = this.getMeasuredHeight();
console.log('focusAtPoint', width, height, x, y);
this.nativeViewProtected?.focusAtAdjustedPointOfInterest(CGPointMake(Utils.layout.toDevicePixels(x) / width, Utils.layout.toDevicePixels(y) / height));
}
async takePicture(options = {}) {
return new Promise((resolve, reject) => {
try {
// if (!this.nativeViewProtected.canCaptureVideo) {
// return reject(new Error('this device cant capture photo: ' + this.nativeViewProtected.canCaptureVideo));
// }
// const onPhoto = (photoDict: NSDictionary<any, any>) => {
// this.videoCaptureListener.delete(onPhoto);
// const photoData = photoDict.objectForKey('NextLevelPhotoJPEGKey');
// console.log('photoData', photoData, photoDict);
// resolve({ image: new UIImage({ data: photoData }) });
// };
// this.videoCaptureListener.add(onPhoto);
// console.log('capturePhotoFromVideo');
// this.nativeViewProtected?.capturePhotoFromVideo();
if (!this.nativeViewProtected.canCapturePhoto) {
return reject(new Error('this device cant capture photo: ' + this.nativeViewProtected.canCapturePhoto));
}
const onPhoto = (image, photoDict) => {
resolve({ image });
};
this.photoCaptureListener.add(onPhoto);
this.nativeViewProtected?.capturePhoto(JSON.stringify(options));
}
catch (error) {
reject(error);
}
});
}
toggleCamera() {
this.nativeViewProtected.toggleCamera();
}
[iosCaptureModeProperty.setNative](value) {
let intValue;
if (typeof value === 'string') {
switch (value) {
case 'video':
intValue = 0;
break;
case 'audio':
intValue = 2;
break;
case 'videoWithoutAudio':
intValue = 3;
break;
case 'videoPhotoWithoutAudio':
intValue = 4;
break;
case 'movie':
intValue = 5;
break;
case 'arKit':
intValue = 6;
break;
case 'arKitWithoutAudio':
intValue = 7;
break;
default:
case 'photo':
intValue = 1;
break;
}
}
else {
intValue = value;
}
this.nativeViewProtected.captureMode = intValue;
}
[flashModeProperty.setNative](value) {
const nativeView = this.nativeViewProtected;
if (typeof value === 'string') {
switch (value) {
case 'off':
nativeView.torchMode = 0 /* AVCaptureTorchMode.Off */;
nativeView.flashMode = 0 /* AVCaptureFlashMode.Off */;
break;
case 'on':
nativeView.torchMode = 0 /* AVCaptureTorchMode.Off */;
nativeView.flashMode = 1 /* AVCaptureFlashMode.On */;
break;
case 'auto':
nativeView.torchMode = 0 /* AVCaptureTorchMode.Off */;
nativeView.flashMode = 2 /* AVCaptureFlashMode.Auto */;
break;
case 'torch':
nativeView.flashMode = 0 /* AVCaptureFlashMode.Off */;
nativeView.torchMode = 1 /* AVCaptureTorchMode.On */;
break;
}
}
else {
nativeView.torchMode = 0 /* AVCaptureTorchMode.Off */;
nativeView.flashMode = value;
}
}
[autoFocusProperty.setNative](value) {
if (typeof value === 'boolean') {
this.nativeViewProtected.focusMode = value ? 2 /* AVCaptureFocusMode.ContinuousAutoFocus */ : 0 /* AVCaptureFocusMode.Locked */;
}
else {
this.nativeViewProtected.focusMode = value;
}
}
[stretchProperty.setNative](value) {
this.nativeViewProtected.videoGravity = getScaleType(value);
}
[zoomProperty.setNative](value) {
this.nativeViewProtected.videoZoomFactor = value;
}
[frontMirroredProperty.setNative](value) {
this.nativeViewProtected.frontMirrored = value;
}
getAllAvailablePictureSizes() {
// TODO: implement
}
}
iosCaptureModeProperty.register(CameraView);
//# sourceMappingURL=index.ios.js.map