ngx-webcam
Version:
A simple Angular webcam component. Pure & minimal, no Flash-fallback. <a href="https://basst314.github.io/ngx-webcam/?" target="_blank">See the Demo!</a>
1 lines • 32.1 kB
Source Map (JSON)
{"version":3,"file":"ngx-webcam.mjs","sources":["../../src/app/modules/webcam/domain/webcam-image.ts","../../src/app/modules/webcam/util/webcam.util.ts","../../src/app/modules/webcam/webcam/webcam.component.ts","../../src/app/modules/webcam/webcam/webcam.component.html","../../src/app/modules/webcam/webcam.module.ts","../../src/app/modules/webcam/domain/webcam-init-error.ts","../../src/app/modules/webcam/domain/webcam-mirror-properties.ts","../../ngx-webcam.ts"],"sourcesContent":["/**\r\n * Container class for a captured webcam image\r\n * @author basst314, davidshen84\r\n */\r\nexport class WebcamImage {\r\n\r\n public constructor(imageAsDataUrl: string, mimeType: string, imageData: ImageData) {\r\n this._mimeType = mimeType;\r\n this._imageAsDataUrl = imageAsDataUrl;\r\n this._imageData = imageData;\r\n }\r\n\r\n private readonly _mimeType: string = null;\r\n private _imageAsBase64: string = null;\r\n private readonly _imageAsDataUrl: string = null;\r\n private readonly _imageData: ImageData = null;\r\n\r\n\r\n /**\r\n * Extracts the Base64 data out of the given dataUrl.\r\n * @param dataUrl the given dataUrl\r\n * @param mimeType the mimeType of the data\r\n */\r\n private static getDataFromDataUrl(dataUrl: string, mimeType: string) {\r\n return dataUrl.replace(`data:${mimeType};base64,`, '');\r\n }\r\n\r\n /**\r\n * Get the base64 encoded image data\r\n * @returns base64 data of the image\r\n */\r\n public get imageAsBase64(): string {\r\n return this._imageAsBase64 ? this._imageAsBase64\r\n : this._imageAsBase64 = WebcamImage.getDataFromDataUrl(this._imageAsDataUrl, this._mimeType);\r\n }\r\n\r\n /**\r\n * Get the encoded image as dataUrl\r\n * @returns the dataUrl of the image\r\n */\r\n public get imageAsDataUrl(): string {\r\n return this._imageAsDataUrl;\r\n }\r\n\r\n /**\r\n * Get the ImageData object associated with the canvas' 2d context.\r\n * @returns the ImageData of the canvas's 2d context.\r\n */\r\n public get imageData(): ImageData {\r\n return this._imageData;\r\n }\r\n\r\n}\r\n","export class WebcamUtil {\r\n\r\n /**\r\n * Lists available videoInput devices\r\n * @returns a list of media device info.\r\n */\r\n public static getAvailableVideoInputs(): Promise<MediaDeviceInfo[]> {\r\n if (!navigator.mediaDevices || !navigator.mediaDevices.enumerateDevices) {\r\n return Promise.reject('enumerateDevices() not supported.');\r\n }\r\n\r\n return new Promise((resolve, reject) => {\r\n navigator.mediaDevices.enumerateDevices()\r\n .then((devices: MediaDeviceInfo[]) => {\r\n resolve(devices.filter((device: MediaDeviceInfo) => device.kind === 'videoinput'));\r\n })\r\n .catch(err => {\r\n reject(err.message || err);\r\n });\r\n });\r\n }\r\n}\r\n","import {AfterViewInit, Component, EventEmitter, Input, OnDestroy, Output, ViewChild} from '@angular/core';\r\nimport {WebcamInitError} from '../domain/webcam-init-error';\r\nimport {WebcamImage} from '../domain/webcam-image';\r\nimport {Observable, Subscription} from 'rxjs';\r\nimport {WebcamUtil} from '../util/webcam.util';\r\nimport {WebcamMirrorProperties} from '../domain/webcam-mirror-properties';\r\n\r\n@Component({\r\n selector: 'webcam',\r\n templateUrl: './webcam.component.html',\r\n styleUrls: ['./webcam.component.scss']\r\n})\r\nexport class WebcamComponent implements AfterViewInit, OnDestroy {\r\n private static DEFAULT_VIDEO_OPTIONS: MediaTrackConstraints = {facingMode: 'environment'};\r\n private static DEFAULT_IMAGE_TYPE: string = 'image/jpeg';\r\n private static DEFAULT_IMAGE_QUALITY: number = 0.92;\r\n\r\n /** Defines the max width of the webcam area in px */\r\n @Input() public width: number = 640;\r\n /** Defines the max height of the webcam area in px */\r\n @Input() public height: number = 480;\r\n /** Defines base constraints to apply when requesting video track from UserMedia */\r\n @Input() public videoOptions: MediaTrackConstraints = WebcamComponent.DEFAULT_VIDEO_OPTIONS;\r\n /** Flag to enable/disable camera switch. If enabled, a switch icon will be displayed if multiple cameras were found */\r\n @Input() public allowCameraSwitch: boolean = true;\r\n /** Parameter to control image mirroring (i.e. for user-facing camera). [\"auto\", \"always\", \"never\"] */\r\n @Input() public mirrorImage: string | WebcamMirrorProperties;\r\n /** Flag to control whether an ImageData object is stored into the WebcamImage object. */\r\n @Input() public captureImageData: boolean = false;\r\n /** The image type to use when capturing snapshots */\r\n @Input() public imageType: string = WebcamComponent.DEFAULT_IMAGE_TYPE;\r\n /** The image quality to use when capturing snapshots (number between 0 and 1) */\r\n @Input() public imageQuality: number = WebcamComponent.DEFAULT_IMAGE_QUALITY;\r\n\r\n /** EventEmitter which fires when an image has been captured */\r\n @Output() public imageCapture: EventEmitter<WebcamImage> = new EventEmitter<WebcamImage>();\r\n /** Emits a mediaError if webcam cannot be initialized (e.g. missing user permissions) */\r\n @Output() public initError: EventEmitter<WebcamInitError> = new EventEmitter<WebcamInitError>();\r\n /** Emits when the webcam video was clicked */\r\n @Output() public imageClick: EventEmitter<void> = new EventEmitter<void>();\r\n /** Emits the active deviceId after the active video device was switched */\r\n @Output() public cameraSwitched: EventEmitter<string> = new EventEmitter<string>();\r\n\r\n /** available video devices */\r\n public availableVideoInputs: MediaDeviceInfo[] = [];\r\n\r\n /** Indicates whether the video device is ready to be switched */\r\n public videoInitialized: boolean = false;\r\n\r\n /** If the Observable represented by this subscription emits, an image will be captured and emitted through\r\n * the 'imageCapture' EventEmitter */\r\n private triggerSubscription: Subscription;\r\n /** Index of active video in availableVideoInputs */\r\n private activeVideoInputIndex: number = -1;\r\n /** Subscription to switchCamera events */\r\n private switchCameraSubscription: Subscription;\r\n /** MediaStream object in use for streaming UserMedia data */\r\n private mediaStream: MediaStream = null;\r\n @ViewChild('video', { static: true }) private video: any;\r\n /** Canvas for Video Snapshots */\r\n @ViewChild('canvas', { static: true }) private canvas: any;\r\n\r\n /** width and height of the active video stream */\r\n private activeVideoSettings: MediaTrackSettings = null;\r\n\r\n /**\r\n * If the given Observable emits, an image will be captured and emitted through 'imageCapture' EventEmitter\r\n */\r\n @Input()\r\n public set trigger(trigger: Observable<void>) {\r\n if (this.triggerSubscription) {\r\n this.triggerSubscription.unsubscribe();\r\n }\r\n\r\n // Subscribe to events from this Observable to take snapshots\r\n this.triggerSubscription = trigger.subscribe(() => {\r\n this.takeSnapshot();\r\n });\r\n }\r\n\r\n /**\r\n * If the given Observable emits, the active webcam will be switched to the one indicated by the emitted value.\r\n * @param switchCamera Indicates which webcam to switch to\r\n * true: cycle forwards through available webcams\r\n * false: cycle backwards through available webcams\r\n * string: activate the webcam with the given id\r\n */\r\n @Input()\r\n public set switchCamera(switchCamera: Observable<boolean | string>) {\r\n if (this.switchCameraSubscription) {\r\n this.switchCameraSubscription.unsubscribe();\r\n }\r\n\r\n // Subscribe to events from this Observable to switch video device\r\n this.switchCameraSubscription = switchCamera.subscribe((value: boolean | string) => {\r\n if (typeof value === 'string') {\r\n // deviceId was specified\r\n this.switchToVideoInput(value);\r\n } else {\r\n // direction was specified\r\n this.rotateVideoInput(value !== false);\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * Get MediaTrackConstraints to request streaming the given device\r\n * @param deviceId\r\n * @param baseMediaTrackConstraints base constraints to merge deviceId-constraint into\r\n * @returns\r\n */\r\n private static getMediaConstraintsForDevice(deviceId: string, baseMediaTrackConstraints: MediaTrackConstraints): MediaTrackConstraints {\r\n const result: MediaTrackConstraints = baseMediaTrackConstraints ? baseMediaTrackConstraints : this.DEFAULT_VIDEO_OPTIONS;\r\n if (deviceId) {\r\n result.deviceId = {exact: deviceId};\r\n }\r\n\r\n return result;\r\n }\r\n\r\n /**\r\n * Tries to harvest the deviceId from the given mediaStreamTrack object.\r\n * Browsers populate this object differently; this method tries some different approaches\r\n * to read the id.\r\n * @param mediaStreamTrack\r\n * @returns deviceId if found in the mediaStreamTrack\r\n */\r\n private static getDeviceIdFromMediaStreamTrack(mediaStreamTrack: MediaStreamTrack): string {\r\n if (mediaStreamTrack.getSettings && mediaStreamTrack.getSettings() && mediaStreamTrack.getSettings().deviceId) {\r\n return mediaStreamTrack.getSettings().deviceId;\r\n } else if (mediaStreamTrack.getConstraints && mediaStreamTrack.getConstraints() && mediaStreamTrack.getConstraints().deviceId) {\r\n const deviceIdObj: ConstrainDOMString = mediaStreamTrack.getConstraints().deviceId;\r\n return WebcamComponent.getValueFromConstrainDOMString(deviceIdObj);\r\n }\r\n }\r\n\r\n /**\r\n * Tries to harvest the facingMode from the given mediaStreamTrack object.\r\n * Browsers populate this object differently; this method tries some different approaches\r\n * to read the value.\r\n * @param mediaStreamTrack\r\n * @returns facingMode if found in the mediaStreamTrack\r\n */\r\n private static getFacingModeFromMediaStreamTrack(mediaStreamTrack: MediaStreamTrack): string {\r\n if (mediaStreamTrack) {\r\n if (mediaStreamTrack.getSettings && mediaStreamTrack.getSettings() && mediaStreamTrack.getSettings().facingMode) {\r\n return mediaStreamTrack.getSettings().facingMode;\r\n } else if (mediaStreamTrack.getConstraints && mediaStreamTrack.getConstraints() && mediaStreamTrack.getConstraints().facingMode) {\r\n const facingModeConstraint: ConstrainDOMString = mediaStreamTrack.getConstraints().facingMode;\r\n return WebcamComponent.getValueFromConstrainDOMString(facingModeConstraint);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Determines whether the given mediaStreamTrack claims itself as user facing\r\n * @param mediaStreamTrack\r\n */\r\n private static isUserFacing(mediaStreamTrack: MediaStreamTrack): boolean {\r\n const facingMode: string = WebcamComponent.getFacingModeFromMediaStreamTrack(mediaStreamTrack);\r\n return facingMode ? 'user' === facingMode.toLowerCase() : false;\r\n }\r\n\r\n /**\r\n * Extracts the value from the given ConstrainDOMString\r\n * @param constrainDOMString\r\n */\r\n private static getValueFromConstrainDOMString(constrainDOMString: ConstrainDOMString): string {\r\n if (constrainDOMString) {\r\n if (constrainDOMString instanceof String) {\r\n return String(constrainDOMString);\r\n } else if (Array.isArray(constrainDOMString) && Array(constrainDOMString).length > 0) {\r\n return String(constrainDOMString[0]);\r\n } else if (typeof constrainDOMString === 'object') {\r\n if (constrainDOMString['exact']) {\r\n return String(constrainDOMString['exact']);\r\n } else if (constrainDOMString['ideal']) {\r\n return String(constrainDOMString['ideal']);\r\n }\r\n }\r\n }\r\n\r\n return null;\r\n }\r\n\r\n public ngAfterViewInit(): void {\r\n this.detectAvailableDevices()\r\n .then(() => {\r\n // start video\r\n this.switchToVideoInput(null);\r\n })\r\n .catch((err: string) => {\r\n this.initError.next(<WebcamInitError>{message: err});\r\n // fallback: still try to load webcam, even if device enumeration failed\r\n this.switchToVideoInput(null);\r\n });\r\n }\r\n\r\n public ngOnDestroy(): void {\r\n this.stopMediaTracks();\r\n this.unsubscribeFromSubscriptions();\r\n }\r\n\r\n /**\r\n * Takes a snapshot of the current webcam's view and emits the image as an event\r\n */\r\n public takeSnapshot(): void {\r\n // set canvas size to actual video size\r\n const _video = this.nativeVideoElement;\r\n const dimensions = {width: this.width, height: this.height};\r\n if (_video.videoWidth) {\r\n dimensions.width = _video.videoWidth;\r\n dimensions.height = _video.videoHeight;\r\n }\r\n\r\n const _canvas = this.canvas.nativeElement;\r\n _canvas.width = dimensions.width;\r\n _canvas.height = dimensions.height;\r\n\r\n // paint snapshot image to canvas\r\n const context2d = _canvas.getContext('2d');\r\n context2d.drawImage(_video, 0, 0);\r\n\r\n // read canvas content as image\r\n const mimeType: string = this.imageType ? this.imageType : WebcamComponent.DEFAULT_IMAGE_TYPE;\r\n const quality: number = this.imageQuality ? this.imageQuality : WebcamComponent.DEFAULT_IMAGE_QUALITY;\r\n const dataUrl: string = _canvas.toDataURL(mimeType, quality);\r\n\r\n // get the ImageData object from the canvas' context.\r\n let imageData: ImageData = null;\r\n\r\n if (this.captureImageData) {\r\n imageData = context2d.getImageData(0, 0, _canvas.width, _canvas.height);\r\n }\r\n\r\n this.imageCapture.next(new WebcamImage(dataUrl, mimeType, imageData));\r\n }\r\n\r\n /**\r\n * Switches to the next/previous video device\r\n * @param forward\r\n */\r\n public rotateVideoInput(forward: boolean) {\r\n if (this.availableVideoInputs && this.availableVideoInputs.length > 1) {\r\n const increment: number = forward ? 1 : (this.availableVideoInputs.length - 1);\r\n const nextInputIndex = (this.activeVideoInputIndex + increment) % this.availableVideoInputs.length;\r\n this.switchToVideoInput(this.availableVideoInputs[nextInputIndex].deviceId);\r\n }\r\n }\r\n\r\n /**\r\n * Switches the camera-view to the specified video device\r\n */\r\n public switchToVideoInput(deviceId: string): void {\r\n this.videoInitialized = false;\r\n this.stopMediaTracks();\r\n this.initWebcam(deviceId, this.videoOptions);\r\n }\r\n\r\n\r\n /**\r\n * Event-handler for video resize event.\r\n * Triggers Angular change detection so that new video dimensions get applied\r\n */\r\n public videoResize(): void {\r\n // here to trigger Angular change detection\r\n }\r\n\r\n public get videoWidth() {\r\n const videoRatio = this.getVideoAspectRatio();\r\n return Math.min(this.width, this.height * videoRatio);\r\n }\r\n\r\n public get videoHeight() {\r\n const videoRatio = this.getVideoAspectRatio();\r\n return Math.min(this.height, this.width / videoRatio);\r\n }\r\n\r\n public get videoStyleClasses() {\r\n let classes: string = '';\r\n\r\n if (this.isMirrorImage()) {\r\n classes += 'mirrored ';\r\n }\r\n\r\n return classes.trim();\r\n }\r\n\r\n public get nativeVideoElement() {\r\n return this.video.nativeElement;\r\n }\r\n\r\n /**\r\n * Returns the video aspect ratio of the active video stream\r\n */\r\n private getVideoAspectRatio(): number {\r\n // calculate ratio from video element dimensions if present\r\n const videoElement = this.nativeVideoElement;\r\n if (videoElement.videoWidth && videoElement.videoWidth > 0 &&\r\n videoElement.videoHeight && videoElement.videoHeight > 0) {\r\n\r\n return videoElement.videoWidth / videoElement.videoHeight;\r\n }\r\n\r\n // nothing present - calculate ratio based on width/height params\r\n return this.width / this.height;\r\n }\r\n\r\n /**\r\n * Init webcam live view\r\n */\r\n private initWebcam(deviceId: string, userVideoTrackConstraints: MediaTrackConstraints) {\r\n const _video = this.nativeVideoElement;\r\n if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {\r\n\r\n // merge deviceId -> userVideoTrackConstraints\r\n const videoTrackConstraints = WebcamComponent.getMediaConstraintsForDevice(deviceId, userVideoTrackConstraints);\r\n\r\n navigator.mediaDevices.getUserMedia(<MediaStreamConstraints>{video: videoTrackConstraints})\r\n .then((stream: MediaStream) => {\r\n this.mediaStream = stream;\r\n _video.srcObject = stream;\r\n _video.play();\r\n\r\n this.activeVideoSettings = stream.getVideoTracks()[0].getSettings();\r\n const activeDeviceId: string = WebcamComponent.getDeviceIdFromMediaStreamTrack(stream.getVideoTracks()[0]);\r\n\r\n this.cameraSwitched.next(activeDeviceId);\r\n\r\n // Initial detect may run before user gave permissions, returning no deviceIds. This prevents later camera switches. (#47)\r\n // Run detect once again within getUserMedia callback, to make sure this time we have permissions and get deviceIds.\r\n this.detectAvailableDevices()\r\n .then(() => {\r\n this.activeVideoInputIndex = activeDeviceId ? this.availableVideoInputs\r\n .findIndex((mediaDeviceInfo: MediaDeviceInfo) => mediaDeviceInfo.deviceId === activeDeviceId) : -1;\r\n this.videoInitialized = true;\r\n })\r\n .catch(() => {\r\n this.activeVideoInputIndex = -1;\r\n this.videoInitialized = true;\r\n });\r\n })\r\n .catch((err: DOMException) => {\r\n this.initError.next(<WebcamInitError>{message: err.message, mediaStreamError: err});\r\n });\r\n } else {\r\n this.initError.next(<WebcamInitError>{message: 'Cannot read UserMedia from MediaDevices.'});\r\n }\r\n }\r\n\r\n private getActiveVideoTrack(): MediaStreamTrack {\r\n return this.mediaStream ? this.mediaStream.getVideoTracks()[0] : null;\r\n }\r\n\r\n private isMirrorImage(): boolean {\r\n if (!this.getActiveVideoTrack()) {\r\n return false;\r\n }\r\n\r\n // check for explicit mirror override parameter\r\n {\r\n let mirror: string = 'auto';\r\n if (this.mirrorImage) {\r\n if (typeof this.mirrorImage === 'string') {\r\n mirror = String(this.mirrorImage).toLowerCase();\r\n } else {\r\n // WebcamMirrorProperties\r\n if (this.mirrorImage.x) {\r\n mirror = this.mirrorImage.x.toLowerCase();\r\n }\r\n }\r\n }\r\n\r\n switch (mirror) {\r\n case 'always':\r\n return true;\r\n case 'never':\r\n return false;\r\n }\r\n }\r\n\r\n // default: enable mirroring if webcam is user facing\r\n return WebcamComponent.isUserFacing(this.getActiveVideoTrack());\r\n }\r\n\r\n /**\r\n * Stops all active media tracks.\r\n * This prevents the webcam from being indicated as active,\r\n * even if it is no longer used by this component.\r\n */\r\n private stopMediaTracks() {\r\n if (this.mediaStream && this.mediaStream.getTracks) {\r\n // pause video to prevent mobile browser freezes\r\n this.nativeVideoElement.pause();\r\n\r\n // getTracks() returns all media tracks (video+audio)\r\n this.mediaStream.getTracks()\r\n .forEach((track: MediaStreamTrack) => track.stop());\r\n }\r\n }\r\n\r\n /**\r\n * Unsubscribe from all open subscriptions\r\n */\r\n private unsubscribeFromSubscriptions() {\r\n if (this.triggerSubscription) {\r\n this.triggerSubscription.unsubscribe();\r\n }\r\n if (this.switchCameraSubscription) {\r\n this.switchCameraSubscription.unsubscribe();\r\n }\r\n }\r\n\r\n /**\r\n * Reads available input devices\r\n */\r\n private detectAvailableDevices(): Promise<MediaDeviceInfo[]> {\r\n return new Promise((resolve, reject) => {\r\n WebcamUtil.getAvailableVideoInputs()\r\n .then((devices: MediaDeviceInfo[]) => {\r\n this.availableVideoInputs = devices;\r\n resolve(devices);\r\n })\r\n .catch(err => {\r\n this.availableVideoInputs = [];\r\n reject(err);\r\n });\r\n });\r\n }\r\n\r\n}\r\n","<div class=\"webcam-wrapper\" (click)=\"imageClick.next();\">\r\n <video #video [width]=\"videoWidth\" [height]=\"videoHeight\" [class]=\"videoStyleClasses\" autoplay muted playsinline (resize)=\"videoResize()\"></video>\r\n <div class=\"camera-switch\" *ngIf=\"allowCameraSwitch && availableVideoInputs.length > 1 && videoInitialized\" (click)=\"rotateVideoInput(true)\"></div>\r\n <canvas #canvas [width]=\"width\" [height]=\"height\"></canvas>\r\n</div>\r\n","import {NgModule} from '@angular/core';\nimport {CommonModule} from '@angular/common';\nimport {WebcamComponent} from './webcam/webcam.component';\n\nconst COMPONENTS = [\n WebcamComponent\n];\n\n@NgModule({\n imports: [\n CommonModule\n ],\n declarations: [\n COMPONENTS\n ],\n exports: [\n COMPONENTS\n ]\n})\nexport class WebcamModule {\n}\n","export class WebcamInitError {\r\n public message: string = null;\r\n public mediaStreamError: DOMException = null;\r\n}\r\n","export class WebcamMirrorProperties {\r\n public x: string; // [\"auto\", \"always\", \"never\"]\r\n}\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public_api';\n"],"names":[],"mappings":"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"}