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