diff --git a/packages/expo-camera/build/CameraModule/CameraModule.d.ts b/packages/expo-camera/build/CameraModule/CameraModule.d.ts index d0a8d7615a4e9..617a326e8be5e 100644 --- a/packages/expo-camera/build/CameraModule/CameraModule.d.ts +++ b/packages/expo-camera/build/CameraModule/CameraModule.d.ts @@ -49,6 +49,6 @@ declare class CameraModule { takePicture(config: CameraPictureOptions): CapturedPicture; stopAsync(): void; getAvailablePictureSizes: (ratio: string) => Promise; - getAvailableCameraTypesAsync: () => Promise; + static getAvailableCameraTypesAsync(): Promise; } export default CameraModule; diff --git a/packages/expo-camera/build/CameraModule/CameraModule.js b/packages/expo-camera/build/CameraModule/CameraModule.js index 6945a9cabf47b..9c92b478525ca 100644 --- a/packages/expo-camera/build/CameraModule/CameraModule.js +++ b/packages/expo-camera/build/CameraModule/CameraModule.js @@ -3,7 +3,7 @@ import invariant from 'invariant'; import { CameraType, ImageType } from './CameraModule.types'; import * as Utils from './CameraUtils'; import * as CapabilityUtils from './CapabilityUtils'; -import { isBackCameraAvailableAsync, isFrontCameraAvailableAsync } from './UserMediaManager'; +import { isBackCameraAvailableAsync, isFrontCameraAvailableAsync, canGetUserMedia, } from './UserMediaManager'; import { FacingModeToCameraType, PictureSizes } from './constants'; export { ImageType, CameraType }; const VALID_SETTINGS_KEYS = [ @@ -39,17 +39,6 @@ class CameraModule { this.getAvailablePictureSizes = async (ratio) => { return PictureSizes; }; - this.getAvailableCameraTypesAsync = async () => { - if (!navigator.mediaDevices.enumerateDevices) { - return []; - } - const devices = await navigator.mediaDevices.enumerateDevices(); - const types = await Promise.all([ - (await isFrontCameraAvailableAsync(devices)) && CameraType.front, - (await isBackCameraAvailableAsync()) && CameraType.back, - ]); - return types.filter(Boolean); - }; if (this.videoElement) { this.videoElement.addEventListener('loadedmetadata', () => { this.syncTrackCapabilities(); @@ -212,6 +201,16 @@ class CameraModule { stopMediaStream(this.stream); this.setStream(null); } + static async getAvailableCameraTypesAsync() { + if (!canGetUserMedia() || !navigator.mediaDevices.enumerateDevices) + return []; + const devices = await navigator.mediaDevices.enumerateDevices(); + const types = await Promise.all([ + (await isFrontCameraAvailableAsync(devices)) && CameraType.front, + (await isBackCameraAvailableAsync()) && CameraType.back, + ]); + return types.filter(Boolean); + } } function stopMediaStream(stream) { if (!stream) diff --git a/packages/expo-camera/build/CameraModule/CameraModule.js.map b/packages/expo-camera/build/CameraModule/CameraModule.js.map index 92c067e680ef6..859c06f3743e3 100644 --- a/packages/expo-camera/build/CameraModule/CameraModule.js.map +++ b/packages/expo-camera/build/CameraModule/CameraModule.js.map @@ -1 +1 @@ -{"version":3,"file":"CameraModule.js","sourceRoot":"","sources":["../../src/CameraModule/CameraModule.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-env browser */\nimport invariant from 'invariant';\n\nimport { CameraPictureOptions } from '../Camera.types';\nimport { CameraType, CapturedPicture, CaptureOptions, ImageType } from './CameraModule.types';\nimport * as Utils from './CameraUtils';\nimport * as CapabilityUtils from './CapabilityUtils';\nimport { isBackCameraAvailableAsync, isFrontCameraAvailableAsync } from './UserMediaManager';\nimport { FacingModeToCameraType, PictureSizes } from './constants';\n\nexport { ImageType, CameraType, CaptureOptions };\n\ntype OnCameraReadyListener = () => void;\ntype OnMountErrorListener = (event: { nativeEvent: Error }) => void;\n\nexport type WebCameraSettings = Partial<{\n autoFocus: string;\n flashMode: string;\n whiteBalance: string;\n exposureCompensation: number;\n colorTemperature: number;\n iso: number;\n brightness: number;\n contrast: number;\n saturation: number;\n sharpness: number;\n focusDistance: number;\n zoom: number;\n}>;\n\nconst VALID_SETTINGS_KEYS = [\n 'autoFocus',\n 'flashMode',\n 'exposureCompensation',\n 'colorTemperature',\n 'iso',\n 'brightness',\n 'contrast',\n 'saturation',\n 'sharpness',\n 'focusDistance',\n 'whiteBalance',\n 'zoom',\n];\n\nclass CameraModule {\n public onCameraReady: OnCameraReadyListener = () => {};\n public onMountError: OnMountErrorListener = () => {};\n private stream: MediaStream | null = null;\n private settings: MediaTrackSettings | null = null;\n private pictureSize?: string;\n private isStartingCamera = false;\n private cameraType: CameraType = CameraType.front;\n private webCameraSettings: WebCameraSettings = {\n autoFocus: 'continuous',\n flashMode: 'off',\n whiteBalance: 'continuous',\n zoom: 1,\n };\n\n public get type(): CameraType {\n return this.cameraType;\n }\n\n constructor(private videoElement: HTMLVideoElement) {\n if (this.videoElement) {\n this.videoElement.addEventListener('loadedmetadata', () => {\n this.syncTrackCapabilities();\n });\n }\n }\n\n public async updateWebCameraSettingsAsync(nextSettings: {\n [key: string]: any;\n }): Promise {\n const changes: WebCameraSettings = {};\n\n for (const key of Object.keys(nextSettings)) {\n if (!VALID_SETTINGS_KEYS.includes(key)) continue;\n const nextValue = nextSettings[key];\n if (nextValue !== this.webCameraSettings[key]) {\n changes[key] = nextValue;\n }\n }\n\n // Only update the native camera if changes were found\n const hasChanges = !!Object.keys(changes).length;\n\n this.webCameraSettings = { ...this.webCameraSettings, ...changes };\n if (hasChanges) {\n await this.syncTrackCapabilities(changes);\n }\n\n return hasChanges;\n }\n\n public async setTypeAsync(value: CameraType) {\n if (value === this.cameraType) {\n return;\n }\n this.cameraType = value;\n\n await this.resumePreview();\n }\n\n public setPictureSize(value: string) {\n if (value === this.pictureSize) {\n return;\n }\n invariant(\n PictureSizes.includes(value),\n `expo-camera: CameraModule.setPictureSize(): invalid size supplied ${value}, expected one of: ${PictureSizes.join(\n ', '\n )}`\n );\n\n // TODO: Bacon: IMP\n // const [width, height] = value.split('x');\n // const aspectRatio = parseFloat(width) / parseFloat(height);\n\n this.pictureSize = value;\n }\n\n public isTorchAvailable(): boolean {\n return isCapabilityAvailable(this.videoElement, 'torch');\n }\n\n public isZoomAvailable(): boolean {\n return isCapabilityAvailable(this.videoElement, 'zoom');\n }\n\n // https://developer.mozilla.org/en-US/docs/Web/API/MediaTrackConstraints\n private async onCapabilitiesReady(\n track: MediaStreamTrack,\n settings: WebCameraSettings = {}\n ): Promise {\n const capabilities = track.getCapabilities();\n\n // Create an empty object because if you set a constraint that isn't available an error will be thrown.\n const constraints: MediaTrackConstraintSet = {};\n\n // TODO: Bacon: Add `pointsOfInterest` support\n const clampedValues = [\n 'exposureCompensation',\n 'colorTemperature',\n 'iso',\n 'brightness',\n 'contrast',\n 'saturation',\n 'sharpness',\n 'focusDistance',\n 'zoom',\n ];\n\n for (const property of clampedValues) {\n if (capabilities[property]) {\n constraints[property] = convertNormalizedSetting(\n capabilities[property],\n settings[property]\n );\n }\n }\n\n const _validatedConstrainedValue = (key, propName, converter) =>\n validatedConstrainedValue(\n key,\n propName,\n converter(settings[propName]),\n capabilities,\n settings,\n this.cameraType\n );\n\n if (capabilities.focusMode && settings.autoFocus !== undefined) {\n constraints.focusMode = _validatedConstrainedValue(\n 'focusMode',\n 'autoFocus',\n CapabilityUtils.convertAutoFocusJSONToNative\n );\n }\n\n if (capabilities.torch && settings.flashMode !== undefined) {\n constraints.torch = _validatedConstrainedValue(\n 'torch',\n 'flashMode',\n CapabilityUtils.convertFlashModeJSONToNative\n );\n }\n\n if (capabilities.whiteBalanceMode && settings.whiteBalance !== undefined) {\n constraints.whiteBalanceMode = _validatedConstrainedValue(\n 'whiteBalanceMode',\n 'whiteBalance',\n CapabilityUtils.convertWhiteBalanceJSONToNative\n );\n }\n\n await track.applyConstraints({ advanced: [constraints] as any });\n }\n\n private async applyVideoConstraints(constraints: { [key: string]: any }): Promise {\n if (!this.stream || !this.stream.getVideoTracks) {\n return false;\n }\n return await applyConstraints(this.stream.getVideoTracks(), constraints);\n }\n\n private async applyAudioConstraints(constraints: { [key: string]: any }): Promise {\n if (!this.stream || !this.stream.getAudioTracks) {\n return false;\n }\n return await applyConstraints(this.stream.getAudioTracks(), constraints);\n }\n\n private async syncTrackCapabilities(settings: WebCameraSettings = {}): Promise {\n if (this.stream && this.stream.getVideoTracks) {\n await Promise.all(\n this.stream.getVideoTracks().map(track => this.onCapabilitiesReady(track, settings))\n );\n }\n }\n\n private setStream(stream: MediaStream | null): void {\n this.stream = stream;\n this.settings = stream ? stream.getTracks()[0].getSettings() : null;\n setVideoSource(this.videoElement, stream);\n }\n\n public getActualCameraType(): CameraType | null {\n if (this.settings) {\n // On desktop no value will be returned, in this case we should assume the cameraType is 'front'\n const { facingMode = 'user' } = this.settings;\n return FacingModeToCameraType[facingMode];\n }\n return null;\n }\n\n public async ensureCameraIsRunningAsync(): Promise {\n if (!this.stream) {\n await this.resumePreview();\n }\n }\n\n public async resumePreview(): Promise {\n if (this.isStartingCamera) {\n return null;\n }\n this.isStartingCamera = true;\n try {\n this.stopAsync();\n const stream = await Utils.getStreamDevice(this.type);\n this.setStream(stream);\n this.isStartingCamera = false;\n this.onCameraReady();\n return stream;\n } catch (error) {\n this.isStartingCamera = false;\n this.onMountError({ nativeEvent: error });\n }\n return null;\n }\n\n public takePicture(config: CameraPictureOptions): CapturedPicture {\n const base64 = Utils.captureImage(this.videoElement, config);\n\n const capturedPicture: CapturedPicture = {\n uri: base64,\n base64,\n width: 0,\n height: 0,\n };\n\n if (this.settings) {\n const { width = 0, height = 0 } = this.settings;\n capturedPicture.width = width;\n capturedPicture.height = height;\n // TODO: Bacon: verify/enforce exif shape.\n capturedPicture.exif = this.settings;\n }\n\n if (config.onPictureSaved) {\n config.onPictureSaved({ nativeEvent: { data: capturedPicture, id: config.id } });\n }\n return capturedPicture;\n }\n\n public stopAsync(): void {\n stopMediaStream(this.stream);\n this.setStream(null);\n }\n\n // TODO: Bacon: we don't even use ratio in native...\n public getAvailablePictureSizes = async (ratio: string): Promise => {\n return PictureSizes;\n };\n\n public getAvailableCameraTypesAsync = async (): Promise => {\n if (!navigator.mediaDevices.enumerateDevices) {\n return [];\n }\n const devices = await navigator.mediaDevices.enumerateDevices();\n\n const types: (string | null)[] = await Promise.all([\n (await isFrontCameraAvailableAsync(devices)) && CameraType.front,\n (await isBackCameraAvailableAsync()) && CameraType.back,\n ]);\n\n return types.filter(Boolean) as string[];\n };\n}\n\nfunction stopMediaStream(stream: MediaStream | null) {\n if (!stream) return;\n if (stream.getAudioTracks) stream.getAudioTracks().forEach(track => track.stop());\n if (stream.getVideoTracks) stream.getVideoTracks().forEach(track => track.stop());\n if (isMediaStreamTrack(stream)) stream.stop();\n}\n\nfunction setVideoSource(\n video: HTMLVideoElement,\n stream: MediaStream | MediaSource | Blob | null\n): void {\n try {\n video.srcObject = stream;\n } catch (_) {\n if (stream) {\n video.src = window.URL.createObjectURL(stream);\n } else if (typeof video.src === 'string') {\n window.URL.revokeObjectURL(video.src);\n }\n }\n}\n\nasync function applyConstraints(\n tracks: MediaStreamTrack[],\n constraints: { [key: string]: any }\n): Promise {\n try {\n await Promise.all(\n tracks.map(async track => {\n await track.applyConstraints({ advanced: [constraints] as any });\n })\n );\n return true;\n } catch (_) {\n return false;\n }\n}\n\nfunction isCapabilityAvailable(video: HTMLVideoElement, keyName: string): boolean {\n const stream = video.srcObject;\n\n if (stream instanceof MediaStream) {\n const videoTrack = stream.getVideoTracks()[0];\n\n if (typeof videoTrack.getCapabilities === 'undefined') {\n return false;\n }\n\n const capabilities: any = videoTrack.getCapabilities();\n\n return !!capabilities[keyName];\n }\n\n return false;\n}\n\nfunction isMediaStreamTrack(input: any): input is MediaStreamTrack {\n return typeof input.stop === 'function';\n}\n\nfunction convertNormalizedSetting(range: MediaSettingsRange, value?: number): number | undefined {\n if (!value) return;\n // convert the normalized incoming setting to the native camera zoom range\n const converted = convertRange(value, [range.min, range.max]);\n // clamp value so we don't get an error\n return Math.min(range.max, Math.max(range.min, converted));\n}\n\nfunction convertRange(value: number, r2: number[], r1: number[] = [0, 1]): number {\n return ((value - r1[0]) * (r2[1] - r2[0])) / (r1[1] - r1[0]) + r2[0];\n}\n\nfunction validatedConstrainedValue(\n constraintKey: string,\n settingsKey: string,\n convertedSetting: any,\n capabilities: MediaTrackCapabilities,\n settings: any,\n cameraType: string\n): any {\n const setting = settings[settingsKey];\n if (\n Array.isArray(capabilities[constraintKey]) &&\n convertedSetting &&\n !capabilities[constraintKey].includes(convertedSetting)\n ) {\n console.warn(\n ` { ${settingsKey}: \"${setting}\" } (converted to \"${convertedSetting}\" in the browser) is not supported for camera type \"${cameraType}\" in your browser. Using the default value instead.`\n );\n return undefined;\n }\n return convertedSetting;\n}\n\nexport default CameraModule;\n"]} \ No newline at end of file +{"version":3,"file":"CameraModule.js","sourceRoot":"","sources":["../../src/CameraModule/CameraModule.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-env browser */\nimport invariant from 'invariant';\n\nimport { CameraPictureOptions } from '../Camera.types';\nimport { CameraType, CapturedPicture, CaptureOptions, ImageType } from './CameraModule.types';\nimport * as Utils from './CameraUtils';\nimport * as CapabilityUtils from './CapabilityUtils';\nimport {\n isBackCameraAvailableAsync,\n isFrontCameraAvailableAsync,\n canGetUserMedia,\n} from './UserMediaManager';\nimport { FacingModeToCameraType, PictureSizes } from './constants';\n\nexport { ImageType, CameraType, CaptureOptions };\n\ntype OnCameraReadyListener = () => void;\ntype OnMountErrorListener = (event: { nativeEvent: Error }) => void;\n\nexport type WebCameraSettings = Partial<{\n autoFocus: string;\n flashMode: string;\n whiteBalance: string;\n exposureCompensation: number;\n colorTemperature: number;\n iso: number;\n brightness: number;\n contrast: number;\n saturation: number;\n sharpness: number;\n focusDistance: number;\n zoom: number;\n}>;\n\nconst VALID_SETTINGS_KEYS = [\n 'autoFocus',\n 'flashMode',\n 'exposureCompensation',\n 'colorTemperature',\n 'iso',\n 'brightness',\n 'contrast',\n 'saturation',\n 'sharpness',\n 'focusDistance',\n 'whiteBalance',\n 'zoom',\n];\n\nclass CameraModule {\n public onCameraReady: OnCameraReadyListener = () => {};\n public onMountError: OnMountErrorListener = () => {};\n private stream: MediaStream | null = null;\n private settings: MediaTrackSettings | null = null;\n private pictureSize?: string;\n private isStartingCamera = false;\n private cameraType: CameraType = CameraType.front;\n private webCameraSettings: WebCameraSettings = {\n autoFocus: 'continuous',\n flashMode: 'off',\n whiteBalance: 'continuous',\n zoom: 1,\n };\n\n public get type(): CameraType {\n return this.cameraType;\n }\n\n constructor(private videoElement: HTMLVideoElement) {\n if (this.videoElement) {\n this.videoElement.addEventListener('loadedmetadata', () => {\n this.syncTrackCapabilities();\n });\n }\n }\n\n public async updateWebCameraSettingsAsync(nextSettings: {\n [key: string]: any;\n }): Promise {\n const changes: WebCameraSettings = {};\n\n for (const key of Object.keys(nextSettings)) {\n if (!VALID_SETTINGS_KEYS.includes(key)) continue;\n const nextValue = nextSettings[key];\n if (nextValue !== this.webCameraSettings[key]) {\n changes[key] = nextValue;\n }\n }\n\n // Only update the native camera if changes were found\n const hasChanges = !!Object.keys(changes).length;\n\n this.webCameraSettings = { ...this.webCameraSettings, ...changes };\n if (hasChanges) {\n await this.syncTrackCapabilities(changes);\n }\n\n return hasChanges;\n }\n\n public async setTypeAsync(value: CameraType) {\n if (value === this.cameraType) {\n return;\n }\n this.cameraType = value;\n\n await this.resumePreview();\n }\n\n public setPictureSize(value: string) {\n if (value === this.pictureSize) {\n return;\n }\n invariant(\n PictureSizes.includes(value),\n `expo-camera: CameraModule.setPictureSize(): invalid size supplied ${value}, expected one of: ${PictureSizes.join(\n ', '\n )}`\n );\n\n // TODO: Bacon: IMP\n // const [width, height] = value.split('x');\n // const aspectRatio = parseFloat(width) / parseFloat(height);\n\n this.pictureSize = value;\n }\n\n public isTorchAvailable(): boolean {\n return isCapabilityAvailable(this.videoElement, 'torch');\n }\n\n public isZoomAvailable(): boolean {\n return isCapabilityAvailable(this.videoElement, 'zoom');\n }\n\n // https://developer.mozilla.org/en-US/docs/Web/API/MediaTrackConstraints\n private async onCapabilitiesReady(\n track: MediaStreamTrack,\n settings: WebCameraSettings = {}\n ): Promise {\n const capabilities = track.getCapabilities();\n\n // Create an empty object because if you set a constraint that isn't available an error will be thrown.\n const constraints: MediaTrackConstraintSet = {};\n\n // TODO: Bacon: Add `pointsOfInterest` support\n const clampedValues = [\n 'exposureCompensation',\n 'colorTemperature',\n 'iso',\n 'brightness',\n 'contrast',\n 'saturation',\n 'sharpness',\n 'focusDistance',\n 'zoom',\n ];\n\n for (const property of clampedValues) {\n if (capabilities[property]) {\n constraints[property] = convertNormalizedSetting(\n capabilities[property],\n settings[property]\n );\n }\n }\n\n const _validatedConstrainedValue = (key, propName, converter) =>\n validatedConstrainedValue(\n key,\n propName,\n converter(settings[propName]),\n capabilities,\n settings,\n this.cameraType\n );\n\n if (capabilities.focusMode && settings.autoFocus !== undefined) {\n constraints.focusMode = _validatedConstrainedValue(\n 'focusMode',\n 'autoFocus',\n CapabilityUtils.convertAutoFocusJSONToNative\n );\n }\n\n if (capabilities.torch && settings.flashMode !== undefined) {\n constraints.torch = _validatedConstrainedValue(\n 'torch',\n 'flashMode',\n CapabilityUtils.convertFlashModeJSONToNative\n );\n }\n\n if (capabilities.whiteBalanceMode && settings.whiteBalance !== undefined) {\n constraints.whiteBalanceMode = _validatedConstrainedValue(\n 'whiteBalanceMode',\n 'whiteBalance',\n CapabilityUtils.convertWhiteBalanceJSONToNative\n );\n }\n\n await track.applyConstraints({ advanced: [constraints] as any });\n }\n\n private async applyVideoConstraints(constraints: { [key: string]: any }): Promise {\n if (!this.stream || !this.stream.getVideoTracks) {\n return false;\n }\n return await applyConstraints(this.stream.getVideoTracks(), constraints);\n }\n\n private async applyAudioConstraints(constraints: { [key: string]: any }): Promise {\n if (!this.stream || !this.stream.getAudioTracks) {\n return false;\n }\n return await applyConstraints(this.stream.getAudioTracks(), constraints);\n }\n\n private async syncTrackCapabilities(settings: WebCameraSettings = {}): Promise {\n if (this.stream && this.stream.getVideoTracks) {\n await Promise.all(\n this.stream.getVideoTracks().map(track => this.onCapabilitiesReady(track, settings))\n );\n }\n }\n\n private setStream(stream: MediaStream | null): void {\n this.stream = stream;\n this.settings = stream ? stream.getTracks()[0].getSettings() : null;\n setVideoSource(this.videoElement, stream);\n }\n\n public getActualCameraType(): CameraType | null {\n if (this.settings) {\n // On desktop no value will be returned, in this case we should assume the cameraType is 'front'\n const { facingMode = 'user' } = this.settings;\n return FacingModeToCameraType[facingMode];\n }\n return null;\n }\n\n public async ensureCameraIsRunningAsync(): Promise {\n if (!this.stream) {\n await this.resumePreview();\n }\n }\n\n public async resumePreview(): Promise {\n if (this.isStartingCamera) {\n return null;\n }\n this.isStartingCamera = true;\n try {\n this.stopAsync();\n const stream = await Utils.getStreamDevice(this.type);\n this.setStream(stream);\n this.isStartingCamera = false;\n this.onCameraReady();\n return stream;\n } catch (error) {\n this.isStartingCamera = false;\n this.onMountError({ nativeEvent: error });\n }\n return null;\n }\n\n public takePicture(config: CameraPictureOptions): CapturedPicture {\n const base64 = Utils.captureImage(this.videoElement, config);\n\n const capturedPicture: CapturedPicture = {\n uri: base64,\n base64,\n width: 0,\n height: 0,\n };\n\n if (this.settings) {\n const { width = 0, height = 0 } = this.settings;\n capturedPicture.width = width;\n capturedPicture.height = height;\n // TODO: Bacon: verify/enforce exif shape.\n capturedPicture.exif = this.settings;\n }\n\n if (config.onPictureSaved) {\n config.onPictureSaved({ nativeEvent: { data: capturedPicture, id: config.id } });\n }\n return capturedPicture;\n }\n\n public stopAsync(): void {\n stopMediaStream(this.stream);\n this.setStream(null);\n }\n\n // TODO: Bacon: we don't even use ratio in native...\n public getAvailablePictureSizes = async (ratio: string): Promise => {\n return PictureSizes;\n };\n\n static async getAvailableCameraTypesAsync(): Promise {\n if (!canGetUserMedia() || !navigator.mediaDevices.enumerateDevices) return [];\n\n const devices = await navigator.mediaDevices.enumerateDevices();\n\n const types: (string | null)[] = await Promise.all([\n (await isFrontCameraAvailableAsync(devices)) && CameraType.front,\n (await isBackCameraAvailableAsync()) && CameraType.back,\n ]);\n\n return types.filter(Boolean) as string[];\n }\n}\n\nfunction stopMediaStream(stream: MediaStream | null) {\n if (!stream) return;\n if (stream.getAudioTracks) stream.getAudioTracks().forEach(track => track.stop());\n if (stream.getVideoTracks) stream.getVideoTracks().forEach(track => track.stop());\n if (isMediaStreamTrack(stream)) stream.stop();\n}\n\nfunction setVideoSource(\n video: HTMLVideoElement,\n stream: MediaStream | MediaSource | Blob | null\n): void {\n try {\n video.srcObject = stream;\n } catch (_) {\n if (stream) {\n video.src = window.URL.createObjectURL(stream);\n } else if (typeof video.src === 'string') {\n window.URL.revokeObjectURL(video.src);\n }\n }\n}\n\nasync function applyConstraints(\n tracks: MediaStreamTrack[],\n constraints: { [key: string]: any }\n): Promise {\n try {\n await Promise.all(\n tracks.map(async track => {\n await track.applyConstraints({ advanced: [constraints] as any });\n })\n );\n return true;\n } catch (_) {\n return false;\n }\n}\n\nfunction isCapabilityAvailable(video: HTMLVideoElement, keyName: string): boolean {\n const stream = video.srcObject;\n\n if (stream instanceof MediaStream) {\n const videoTrack = stream.getVideoTracks()[0];\n\n if (typeof videoTrack.getCapabilities === 'undefined') {\n return false;\n }\n\n const capabilities: any = videoTrack.getCapabilities();\n\n return !!capabilities[keyName];\n }\n\n return false;\n}\n\nfunction isMediaStreamTrack(input: any): input is MediaStreamTrack {\n return typeof input.stop === 'function';\n}\n\nfunction convertNormalizedSetting(range: MediaSettingsRange, value?: number): number | undefined {\n if (!value) return;\n // convert the normalized incoming setting to the native camera zoom range\n const converted = convertRange(value, [range.min, range.max]);\n // clamp value so we don't get an error\n return Math.min(range.max, Math.max(range.min, converted));\n}\n\nfunction convertRange(value: number, r2: number[], r1: number[] = [0, 1]): number {\n return ((value - r1[0]) * (r2[1] - r2[0])) / (r1[1] - r1[0]) + r2[0];\n}\n\nfunction validatedConstrainedValue(\n constraintKey: string,\n settingsKey: string,\n convertedSetting: any,\n capabilities: MediaTrackCapabilities,\n settings: any,\n cameraType: string\n): any {\n const setting = settings[settingsKey];\n if (\n Array.isArray(capabilities[constraintKey]) &&\n convertedSetting &&\n !capabilities[constraintKey].includes(convertedSetting)\n ) {\n console.warn(\n ` { ${settingsKey}: \"${setting}\" } (converted to \"${convertedSetting}\" in the browser) is not supported for camera type \"${cameraType}\" in your browser. Using the default value instead.`\n );\n return undefined;\n }\n return convertedSetting;\n}\n\nexport default CameraModule;\n"]} \ No newline at end of file diff --git a/packages/expo-camera/build/CameraModule/UserMediaManager.js b/packages/expo-camera/build/CameraModule/UserMediaManager.js index fb636c6625536..0267a2a202220 100644 --- a/packages/expo-camera/build/CameraModule/UserMediaManager.js +++ b/packages/expo-camera/build/CameraModule/UserMediaManager.js @@ -88,7 +88,7 @@ export function canGetUserMedia() { navigator['msGetUserMedia'])); } export async function isFrontCameraAvailableAsync(devices) { - return await supportsCameraType(['front', 'user'], 'user', devices); + return await supportsCameraType(['front', 'user', 'facetime'], 'user', devices); } export async function isBackCameraAvailableAsync(devices) { return await supportsCameraType(['back', 'rear'], 'environment', devices); @@ -101,7 +101,7 @@ async function supportsCameraType(labels, type, devices) { devices = await navigator.mediaDevices.enumerateDevices(); } const cameras = devices.filter(t => t.kind === 'videoinput'); - const [hasCamera] = cameras.filter(camera => labels.includes(camera.label.toLowerCase())); + const [hasCamera] = cameras.filter(camera => labels.some(label => camera.label.toLowerCase().includes(label))); const [isCapable] = cameras.filter(camera => { if (!('getCapabilities' in camera)) { return null; @@ -112,6 +112,6 @@ async function supportsCameraType(labels, type, devices) { } return capabilities.facingMode.find((_) => type); }); - return isCapable.deviceId || hasCamera.deviceId || null; + return isCapable?.deviceId || hasCamera?.deviceId || null; } //# sourceMappingURL=UserMediaManager.js.map \ No newline at end of file diff --git a/packages/expo-camera/build/CameraModule/UserMediaManager.js.map b/packages/expo-camera/build/CameraModule/UserMediaManager.js.map index d181105abb795..a77715f9f7e37 100644 --- a/packages/expo-camera/build/CameraModule/UserMediaManager.js.map +++ b/packages/expo-camera/build/CameraModule/UserMediaManager.js.map @@ -1 +1 @@ -{"version":3,"file":"UserMediaManager.js","sourceRoot":"","sources":["../../src/CameraModule/UserMediaManager.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-env browser */\nimport { canUseDOM } from 'fbjs/lib/ExecutionEnvironment';\n\nexport const userMediaRequested: boolean = false;\nexport const mountedInstances: any[] = [];\n\nasync function requestLegacyUserMediaAsync(props): Promise {\n const optionalSource = id => ({ optional: [{ sourceId: id }] });\n\n const constraintToSourceId = constraint => {\n const { deviceId } = constraint;\n\n if (typeof deviceId === 'string') {\n return deviceId;\n }\n\n if (Array.isArray(deviceId) && deviceId.length > 0) {\n return deviceId[0];\n }\n\n if (typeof deviceId === 'object' && deviceId.ideal) {\n return deviceId.ideal;\n }\n\n return null;\n };\n\n const sources: any[] = await new Promise(resolve =>\n // @ts-ignore: https://caniuse.com/#search=getSources Chrome for Android (78) & Samsung Internet (10.1) use this\n MediaStreamTrack.getSources(sources => resolve(sources))\n );\n\n let audioSource = null;\n let videoSource = null;\n\n sources.forEach(source => {\n if (source.kind === 'audio') {\n audioSource = source.id;\n } else if (source.kind === 'video') {\n videoSource = source.id;\n }\n });\n\n const audioSourceId = constraintToSourceId(props.audioConstraints);\n if (audioSourceId) {\n audioSource = audioSourceId;\n }\n\n const videoSourceId = constraintToSourceId(props.videoConstraints);\n if (videoSourceId) {\n videoSource = videoSourceId;\n }\n\n return [optionalSource(audioSource), optionalSource(videoSource)];\n}\n\nasync function sourceSelectedAsync(\n isMuted: boolean,\n audioConstraints?: MediaTrackConstraints | boolean,\n videoConstraints?: MediaTrackConstraints | boolean\n): Promise {\n const constraints: MediaStreamConstraints = {\n video: typeof videoConstraints !== 'undefined' ? videoConstraints : true,\n };\n\n if (!isMuted) {\n constraints.audio = typeof audioConstraints !== 'undefined' ? audioConstraints : true;\n }\n\n return await getAnyUserMediaAsync(constraints);\n}\n\nexport async function requestUserMediaAsync(\n props: { audio?: any; video?: any },\n isMuted: boolean = true\n): Promise {\n if (canGetUserMedia()) {\n return await sourceSelectedAsync(isMuted, props.audio, props.video);\n }\n const [audio, video] = await requestLegacyUserMediaAsync(props);\n return await sourceSelectedAsync(isMuted, audio, video);\n}\n\nexport async function getAnyUserMediaAsync(\n constraints: MediaStreamConstraints,\n ignoreConstraints: boolean = false\n): Promise {\n try {\n return await getUserMediaAsync({\n ...constraints,\n video: ignoreConstraints || constraints.video,\n });\n } catch (error) {\n if (!ignoreConstraints && error.name === 'ConstraintNotSatisfiedError') {\n return await getAnyUserMediaAsync(constraints, true);\n }\n throw error;\n }\n}\n\nexport async function getUserMediaAsync(constraints: MediaStreamConstraints): Promise {\n if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {\n return navigator.mediaDevices.getUserMedia(constraints);\n }\n\n const _getUserMedia =\n navigator['mozGetUserMedia'] || navigator['webkitGetUserMedia'] || navigator['msGetUserMedia'];\n return new Promise((resolve, reject) =>\n _getUserMedia.call(navigator, constraints, resolve, reject)\n );\n}\n\nexport function canGetUserMedia(): boolean {\n return (\n // SSR\n canUseDOM &&\n // Has any form of media API\n !!(\n (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) ||\n navigator['mozGetUserMedia'] ||\n navigator['webkitGetUserMedia'] ||\n navigator['msGetUserMedia']\n )\n );\n}\n\nexport async function isFrontCameraAvailableAsync(\n devices?: MediaDeviceInfo[]\n): Promise {\n return await supportsCameraType(['front', 'user'], 'user', devices);\n}\n\nexport async function isBackCameraAvailableAsync(\n devices?: MediaDeviceInfo[]\n): Promise {\n return await supportsCameraType(['back', 'rear'], 'environment', devices);\n}\n\nasync function supportsCameraType(\n labels: string[],\n type: string,\n devices?: MediaDeviceInfo[]\n): Promise {\n if (!devices) {\n if (!navigator.mediaDevices.enumerateDevices) {\n return null;\n }\n devices = await navigator.mediaDevices.enumerateDevices();\n }\n const cameras = devices.filter(t => t.kind === 'videoinput');\n const [hasCamera] = cameras.filter(camera => labels.includes(camera.label.toLowerCase()));\n const [isCapable] = cameras.filter(camera => {\n if (!('getCapabilities' in camera)) {\n return null;\n }\n\n const capabilities = (camera as any).getCapabilities();\n if (!capabilities.facingMode) {\n return null;\n }\n\n return capabilities.facingMode.find((_: string) => type);\n });\n\n return isCapable.deviceId || hasCamera.deviceId || null;\n}\n"]} \ No newline at end of file +{"version":3,"file":"UserMediaManager.js","sourceRoot":"","sources":["../../src/CameraModule/UserMediaManager.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-env browser */\nimport { canUseDOM } from 'fbjs/lib/ExecutionEnvironment';\n\nexport const userMediaRequested: boolean = false;\nexport const mountedInstances: any[] = [];\n\nasync function requestLegacyUserMediaAsync(props): Promise {\n const optionalSource = id => ({ optional: [{ sourceId: id }] });\n\n const constraintToSourceId = constraint => {\n const { deviceId } = constraint;\n\n if (typeof deviceId === 'string') {\n return deviceId;\n }\n\n if (Array.isArray(deviceId) && deviceId.length > 0) {\n return deviceId[0];\n }\n\n if (typeof deviceId === 'object' && deviceId.ideal) {\n return deviceId.ideal;\n }\n\n return null;\n };\n\n const sources: any[] = await new Promise(resolve =>\n // @ts-ignore: https://caniuse.com/#search=getSources Chrome for Android (78) & Samsung Internet (10.1) use this\n MediaStreamTrack.getSources(sources => resolve(sources))\n );\n\n let audioSource = null;\n let videoSource = null;\n\n sources.forEach(source => {\n if (source.kind === 'audio') {\n audioSource = source.id;\n } else if (source.kind === 'video') {\n videoSource = source.id;\n }\n });\n\n const audioSourceId = constraintToSourceId(props.audioConstraints);\n if (audioSourceId) {\n audioSource = audioSourceId;\n }\n\n const videoSourceId = constraintToSourceId(props.videoConstraints);\n if (videoSourceId) {\n videoSource = videoSourceId;\n }\n\n return [optionalSource(audioSource), optionalSource(videoSource)];\n}\n\nasync function sourceSelectedAsync(\n isMuted: boolean,\n audioConstraints?: MediaTrackConstraints | boolean,\n videoConstraints?: MediaTrackConstraints | boolean\n): Promise {\n const constraints: MediaStreamConstraints = {\n video: typeof videoConstraints !== 'undefined' ? videoConstraints : true,\n };\n\n if (!isMuted) {\n constraints.audio = typeof audioConstraints !== 'undefined' ? audioConstraints : true;\n }\n\n return await getAnyUserMediaAsync(constraints);\n}\n\nexport async function requestUserMediaAsync(\n props: { audio?: any; video?: any },\n isMuted: boolean = true\n): Promise {\n if (canGetUserMedia()) {\n return await sourceSelectedAsync(isMuted, props.audio, props.video);\n }\n const [audio, video] = await requestLegacyUserMediaAsync(props);\n return await sourceSelectedAsync(isMuted, audio, video);\n}\n\nexport async function getAnyUserMediaAsync(\n constraints: MediaStreamConstraints,\n ignoreConstraints: boolean = false\n): Promise {\n try {\n return await getUserMediaAsync({\n ...constraints,\n video: ignoreConstraints || constraints.video,\n });\n } catch (error) {\n if (!ignoreConstraints && error.name === 'ConstraintNotSatisfiedError') {\n return await getAnyUserMediaAsync(constraints, true);\n }\n throw error;\n }\n}\n\nexport async function getUserMediaAsync(constraints: MediaStreamConstraints): Promise {\n if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {\n return navigator.mediaDevices.getUserMedia(constraints);\n }\n\n const _getUserMedia =\n navigator['mozGetUserMedia'] || navigator['webkitGetUserMedia'] || navigator['msGetUserMedia'];\n return new Promise((resolve, reject) =>\n _getUserMedia.call(navigator, constraints, resolve, reject)\n );\n}\n\nexport function canGetUserMedia(): boolean {\n return (\n // SSR\n canUseDOM &&\n // Has any form of media API\n !!(\n (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) ||\n navigator['mozGetUserMedia'] ||\n navigator['webkitGetUserMedia'] ||\n navigator['msGetUserMedia']\n )\n );\n}\n\nexport async function isFrontCameraAvailableAsync(\n devices?: MediaDeviceInfo[]\n): Promise {\n return await supportsCameraType(['front', 'user', 'facetime'], 'user', devices);\n}\n\nexport async function isBackCameraAvailableAsync(\n devices?: MediaDeviceInfo[]\n): Promise {\n return await supportsCameraType(['back', 'rear'], 'environment', devices);\n}\n\nasync function supportsCameraType(\n labels: string[],\n type: string,\n devices?: MediaDeviceInfo[]\n): Promise {\n if (!devices) {\n if (!navigator.mediaDevices.enumerateDevices) {\n return null;\n }\n devices = await navigator.mediaDevices.enumerateDevices();\n }\n const cameras = devices.filter(t => t.kind === 'videoinput');\n const [hasCamera] = cameras.filter(camera =>\n labels.some(label => camera.label.toLowerCase().includes(label))\n );\n const [isCapable] = cameras.filter(camera => {\n if (!('getCapabilities' in camera)) {\n return null;\n }\n\n const capabilities = (camera as any).getCapabilities();\n if (!capabilities.facingMode) {\n return null;\n }\n\n return capabilities.facingMode.find((_: string) => type);\n });\n\n return isCapable?.deviceId || hasCamera?.deviceId || null;\n}\n"]} \ No newline at end of file diff --git a/packages/expo-camera/build/ExponentCamera.web.d.ts b/packages/expo-camera/build/ExponentCamera.web.d.ts index fc486c866f6a5..6c8a0c62c5612 100644 --- a/packages/expo-camera/build/ExponentCamera.web.d.ts +++ b/packages/expo-camera/build/ExponentCamera.web.d.ts @@ -13,7 +13,6 @@ export default class ExponentCamera extends React.Component { getCamera: () => CameraModule; getAvailablePictureSizes: (ratio: string) => Promise; takePicture: (options: CameraPictureOptions) => Promise; - getAvailableCameraTypesAsync: () => Promise; resumePreview: () => Promise; pausePreview: () => Promise; onCameraReady: () => void; diff --git a/packages/expo-camera/build/ExponentCamera.web.js b/packages/expo-camera/build/ExponentCamera.web.js index 0be06e1b38951..73fc4e11127c5 100644 --- a/packages/expo-camera/build/ExponentCamera.web.js +++ b/packages/expo-camera/build/ExponentCamera.web.js @@ -38,10 +38,6 @@ export default class ExponentCamera extends React.Component { onPictureSaved: this.props.onPictureSaved, }); }; - this.getAvailableCameraTypesAsync = async () => { - const camera = this.getCamera(); - return await camera.getAvailableCameraTypesAsync(); - }; this.resumePreview = async () => { const camera = this.getCamera(); await camera.resumePreview(); diff --git a/packages/expo-camera/build/ExponentCamera.web.js.map b/packages/expo-camera/build/ExponentCamera.web.js.map index 9f9c5a902c2ed..44201e89ef560 100644 --- a/packages/expo-camera/build/ExponentCamera.web.js.map +++ b/packages/expo-camera/build/ExponentCamera.web.js.map @@ -1 +1 @@ -{"version":3,"file":"ExponentCamera.web.js","sourceRoot":"","sources":["../src/ExponentCamera.web.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, { forwardRef } from 'react';\nimport { createElement, findNodeHandle, StyleSheet, View } from 'react-native';\n\nimport {\n CameraCapturedPicture,\n CameraMountError,\n CameraNativeProps,\n CameraPictureOptions,\n} from './Camera.types';\nimport CameraModule, { CameraType } from './CameraModule/CameraModule';\nimport CameraManager from './ExponentCameraManager.web';\n\nexport default class ExponentCamera extends React.Component {\n video?: number | null;\n camera?: CameraModule;\n\n state = { type: null };\n\n componentWillUnmount() {\n if (this.camera) {\n this.camera.stopAsync();\n }\n }\n\n componentDidUpdate(nextProps) {\n this._updateCameraProps(nextProps);\n }\n\n _updateCameraProps = async ({ type, pictureSize, ...webCameraSettings }: CameraNativeProps) => {\n const { camera } = this;\n if (!camera) {\n return;\n }\n\n await camera.setTypeAsync(type as CameraType);\n\n await camera.updateWebCameraSettingsAsync(webCameraSettings);\n\n // await camera.setPictureSize(pictureSize as string);\n\n await camera.ensureCameraIsRunningAsync();\n\n const actualCameraType = camera.getActualCameraType();\n if (actualCameraType !== this.state.type) {\n this.setState({ type: actualCameraType });\n }\n };\n\n getCamera = (): CameraModule => {\n if (this.camera) {\n return this.camera;\n }\n throw new Error('Camera is not defined yet!');\n };\n\n getAvailablePictureSizes = async (ratio: string): Promise => {\n const camera = this.getCamera();\n return camera.getAvailablePictureSizes(ratio);\n };\n\n takePicture = async (options: CameraPictureOptions): Promise => {\n const camera = this.getCamera();\n return camera.takePicture({\n ...options,\n // This will always be defined, the option gets added to a queue in the upper-level. We should replace the original so it isn't called twice.\n onPictureSaved: this.props.onPictureSaved,\n });\n };\n\n getAvailableCameraTypesAsync = async (): Promise => {\n const camera = this.getCamera();\n return await camera.getAvailableCameraTypesAsync();\n };\n\n resumePreview = async (): Promise => {\n const camera = this.getCamera();\n await camera.resumePreview();\n };\n\n pausePreview = async (): Promise => {\n const camera = this.getCamera();\n await camera.stopAsync();\n };\n\n onCameraReady = () => {\n if (this.props.onCameraReady) {\n this.props.onCameraReady();\n }\n };\n\n onMountError = ({ nativeEvent }: { nativeEvent: CameraMountError }) => {\n if (this.props.onMountError) {\n this.props.onMountError({ nativeEvent });\n }\n };\n\n _setRef = ref => {\n if (!ref) {\n this.video = null;\n if (this.camera) {\n this.camera.stopAsync();\n this.camera = undefined;\n }\n return;\n }\n this.video = findNodeHandle(ref);\n\n (this.video as any).webkitPlaysinline = true;\n\n this.camera = new CameraModule(ref);\n this.camera.onCameraReady = this.onCameraReady;\n this.camera.onMountError = this.onMountError;\n this._updateCameraProps(this.props);\n };\n\n render() {\n const { pointerEvents } = this.props;\n\n // TODO: Bacon: Create a universal prop, on native the microphone is only used when recording videos.\n // Because we don't support recording video in the browser we don't need the user to give microphone permissions.\n const isMuted = true;\n\n const isFrontFacingCamera = this.state.type === CameraManager.Type.front;\n const style = {\n // Flip the camera\n transform: isFrontFacingCamera ? [{ scaleX: -1 }] : undefined,\n };\n\n return (\n \n \n {this.props.children}\n \n );\n }\n}\n\nconst Video: any = forwardRef((props, ref) => createElement('video', { ...props, ref }));\n\nconst styles = StyleSheet.create({\n videoWrapper: {\n flex: 1,\n alignItems: 'stretch',\n },\n video: {\n width: '100%',\n height: '100%',\n objectFit: 'cover',\n },\n});\n"]} \ No newline at end of file +{"version":3,"file":"ExponentCamera.web.js","sourceRoot":"","sources":["../src/ExponentCamera.web.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, { forwardRef } from 'react';\nimport { createElement, findNodeHandle, StyleSheet, View } from 'react-native';\n\nimport {\n CameraCapturedPicture,\n CameraMountError,\n CameraNativeProps,\n CameraPictureOptions,\n} from './Camera.types';\nimport CameraModule, { CameraType } from './CameraModule/CameraModule';\nimport CameraManager from './ExponentCameraManager.web';\n\nexport default class ExponentCamera extends React.Component {\n video?: number | null;\n camera?: CameraModule;\n\n state = { type: null };\n\n componentWillUnmount() {\n if (this.camera) {\n this.camera.stopAsync();\n }\n }\n\n componentDidUpdate(nextProps) {\n this._updateCameraProps(nextProps);\n }\n\n _updateCameraProps = async ({ type, pictureSize, ...webCameraSettings }: CameraNativeProps) => {\n const { camera } = this;\n if (!camera) {\n return;\n }\n\n await camera.setTypeAsync(type as CameraType);\n\n await camera.updateWebCameraSettingsAsync(webCameraSettings);\n\n // await camera.setPictureSize(pictureSize as string);\n\n await camera.ensureCameraIsRunningAsync();\n\n const actualCameraType = camera.getActualCameraType();\n if (actualCameraType !== this.state.type) {\n this.setState({ type: actualCameraType });\n }\n };\n\n getCamera = (): CameraModule => {\n if (this.camera) {\n return this.camera;\n }\n throw new Error('Camera is not defined yet!');\n };\n\n getAvailablePictureSizes = async (ratio: string): Promise => {\n const camera = this.getCamera();\n return camera.getAvailablePictureSizes(ratio);\n };\n\n takePicture = async (options: CameraPictureOptions): Promise => {\n const camera = this.getCamera();\n return camera.takePicture({\n ...options,\n // This will always be defined, the option gets added to a queue in the upper-level. We should replace the original so it isn't called twice.\n onPictureSaved: this.props.onPictureSaved,\n });\n };\n\n resumePreview = async (): Promise => {\n const camera = this.getCamera();\n await camera.resumePreview();\n };\n\n pausePreview = async (): Promise => {\n const camera = this.getCamera();\n await camera.stopAsync();\n };\n\n onCameraReady = () => {\n if (this.props.onCameraReady) {\n this.props.onCameraReady();\n }\n };\n\n onMountError = ({ nativeEvent }: { nativeEvent: CameraMountError }) => {\n if (this.props.onMountError) {\n this.props.onMountError({ nativeEvent });\n }\n };\n\n _setRef = ref => {\n if (!ref) {\n this.video = null;\n if (this.camera) {\n this.camera.stopAsync();\n this.camera = undefined;\n }\n return;\n }\n this.video = findNodeHandle(ref);\n\n (this.video as any).webkitPlaysinline = true;\n\n this.camera = new CameraModule(ref);\n this.camera.onCameraReady = this.onCameraReady;\n this.camera.onMountError = this.onMountError;\n this._updateCameraProps(this.props);\n };\n\n render() {\n const { pointerEvents } = this.props;\n\n // TODO: Bacon: Create a universal prop, on native the microphone is only used when recording videos.\n // Because we don't support recording video in the browser we don't need the user to give microphone permissions.\n const isMuted = true;\n\n const isFrontFacingCamera = this.state.type === CameraManager.Type.front;\n const style = {\n // Flip the camera\n transform: isFrontFacingCamera ? [{ scaleX: -1 }] : undefined,\n };\n\n return (\n \n \n {this.props.children}\n \n );\n }\n}\n\nconst Video: any = forwardRef((props, ref) => createElement('video', { ...props, ref }));\n\nconst styles = StyleSheet.create({\n videoWrapper: {\n flex: 1,\n alignItems: 'stretch',\n },\n video: {\n width: '100%',\n height: '100%',\n objectFit: 'cover',\n },\n});\n"]} \ No newline at end of file diff --git a/packages/expo-camera/build/ExponentCameraManager.web.d.ts b/packages/expo-camera/build/ExponentCameraManager.web.d.ts index 75fe1199c3135..802e4baaa96e6 100644 --- a/packages/expo-camera/build/ExponentCameraManager.web.d.ts +++ b/packages/expo-camera/build/ExponentCameraManager.web.d.ts @@ -28,7 +28,7 @@ declare const _default: { takePicture(options: CameraPictureOptions, camera: ExponentCamera): Promise; pausePreview(camera: ExponentCamera): Promise; resumePreview(camera: ExponentCamera): Promise; - getAvailableCameraTypesAsync(camera: ExponentCamera): Promise; + getAvailableCameraTypesAsync(): Promise; getAvailablePictureSizes(ratio: string, camera: ExponentCamera): Promise; }; export default _default; diff --git a/packages/expo-camera/build/ExponentCameraManager.web.js b/packages/expo-camera/build/ExponentCameraManager.web.js index f79e389ccf045..65a5c0df3e3e9 100644 --- a/packages/expo-camera/build/ExponentCameraManager.web.js +++ b/packages/expo-camera/build/ExponentCameraManager.web.js @@ -1,3 +1,4 @@ +import CameraModule from './CameraModule/CameraModule'; import { canGetUserMedia } from './CameraModule/UserMediaManager'; export default { get name() { @@ -50,10 +51,8 @@ export default { async resumePreview(camera) { return await camera.resumePreview(); }, - async getAvailableCameraTypesAsync(camera) { - if (!canGetUserMedia()) - return []; - return await camera.getAvailableCameraTypesAsync(); + async getAvailableCameraTypesAsync() { + return await CameraModule.getAvailableCameraTypesAsync(); }, async getAvailablePictureSizes(ratio, camera) { return await camera.getAvailablePictureSizes(ratio); diff --git a/packages/expo-camera/build/ExponentCameraManager.web.js.map b/packages/expo-camera/build/ExponentCameraManager.web.js.map index 746e206906853..2a3a386d8835c 100644 --- a/packages/expo-camera/build/ExponentCameraManager.web.js.map +++ b/packages/expo-camera/build/ExponentCameraManager.web.js.map @@ -1 +1 @@ -{"version":3,"file":"ExponentCameraManager.web.js","sourceRoot":"","sources":["../src/ExponentCameraManager.web.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAGlE,eAAe;IACb,IAAI,IAAI;QACN,OAAO,uBAAuB,CAAC;IACjC,CAAC;IACD,IAAI,IAAI;QACN,OAAO;YACL,IAAI,EAAE,MAAM;YACZ,KAAK,EAAE,OAAO;SACf,CAAC;IACJ,CAAC;IACD,IAAI,SAAS;QACX,OAAO;YACL,EAAE,EAAE,IAAI;YACR,GAAG,EAAE,KAAK;YACV,IAAI,EAAE,MAAM;YACZ,KAAK,EAAE,OAAO;SACf,CAAC;IACJ,CAAC;IACD,IAAI,SAAS;QACX,OAAO;YACL,EAAE,EAAE,IAAI;YACR,GAAG,EAAE,KAAK;YACV,IAAI,EAAE,MAAM;YACZ,UAAU,EAAE,YAAY;SACzB,CAAC;IACJ,CAAC;IACD,IAAI,YAAY;QACd,OAAO;YACL,IAAI,EAAE,MAAM;YACZ,UAAU,EAAE,YAAY;YACxB,MAAM,EAAE,QAAQ;SACjB,CAAC;IACJ,CAAC;IACD,IAAI,YAAY;QACd,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,KAAK,CAAC,gBAAgB;QACpB,OAAO,eAAe,EAAE,CAAC;IAC3B,CAAC;IAED,kCAAkC;IAClC,2BAA2B;IAC3B,iCAAiC;IACjC,KAAK,CAAC,WAAW,CACf,OAA6B,EAC7B,MAAsB;QAEtB,OAAO,MAAM,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;IAC3C,CAAC;IACD,KAAK,CAAC,YAAY,CAAC,MAAsB;QACvC,MAAM,MAAM,CAAC,YAAY,EAAE,CAAC;IAC9B,CAAC;IACD,KAAK,CAAC,aAAa,CAAC,MAAsB;QACxC,OAAO,MAAM,MAAM,CAAC,aAAa,EAAE,CAAC;IACtC,CAAC;IACD,KAAK,CAAC,4BAA4B,CAAC,MAAsB;QACvD,IAAI,CAAC,eAAe,EAAE;YAAE,OAAO,EAAE,CAAC;QAClC,OAAO,MAAM,MAAM,CAAC,4BAA4B,EAAE,CAAC;IACrD,CAAC;IACD,KAAK,CAAC,wBAAwB,CAAC,KAAa,EAAE,MAAsB;QAClE,OAAO,MAAM,MAAM,CAAC,wBAAwB,CAAC,KAAK,CAAC,CAAC;IACtD,CAAC;CACF,CAAC","sourcesContent":["import { CameraCapturedPicture, CameraPictureOptions } from './Camera.types';\nimport { canGetUserMedia } from './CameraModule/UserMediaManager';\nimport ExponentCamera from './ExponentCamera.web';\n\nexport default {\n get name(): string {\n return 'ExponentCameraManager';\n },\n get Type() {\n return {\n back: 'back',\n front: 'front',\n };\n },\n get FlashMode() {\n return {\n on: 'on',\n off: 'off',\n auto: 'auto',\n torch: 'torch',\n };\n },\n get AutoFocus() {\n return {\n on: 'on',\n off: 'off',\n auto: 'auto',\n singleShot: 'singleShot',\n };\n },\n get WhiteBalance() {\n return {\n auto: 'auto',\n continuous: 'continuous',\n manual: 'manual',\n };\n },\n get VideoQuality() {\n return {};\n },\n async isAvailableAsync(): Promise {\n return canGetUserMedia();\n },\n\n // TODO: Bacon: Is video possible?\n // record(options): Promise\n // stopRecording(): Promise\n async takePicture(\n options: CameraPictureOptions,\n camera: ExponentCamera\n ): Promise {\n return await camera.takePicture(options);\n },\n async pausePreview(camera: ExponentCamera): Promise {\n await camera.pausePreview();\n },\n async resumePreview(camera: ExponentCamera): Promise {\n return await camera.resumePreview();\n },\n async getAvailableCameraTypesAsync(camera: ExponentCamera): Promise {\n if (!canGetUserMedia()) return [];\n return await camera.getAvailableCameraTypesAsync();\n },\n async getAvailablePictureSizes(ratio: string, camera: ExponentCamera): Promise {\n return await camera.getAvailablePictureSizes(ratio);\n },\n};\n"]} \ No newline at end of file +{"version":3,"file":"ExponentCameraManager.web.js","sourceRoot":"","sources":["../src/ExponentCameraManager.web.ts"],"names":[],"mappings":"AACA,OAAO,YAAY,MAAM,6BAA6B,CAAC;AACvD,OAAO,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAGlE,eAAe;IACb,IAAI,IAAI;QACN,OAAO,uBAAuB,CAAC;IACjC,CAAC;IACD,IAAI,IAAI;QACN,OAAO;YACL,IAAI,EAAE,MAAM;YACZ,KAAK,EAAE,OAAO;SACf,CAAC;IACJ,CAAC;IACD,IAAI,SAAS;QACX,OAAO;YACL,EAAE,EAAE,IAAI;YACR,GAAG,EAAE,KAAK;YACV,IAAI,EAAE,MAAM;YACZ,KAAK,EAAE,OAAO;SACf,CAAC;IACJ,CAAC;IACD,IAAI,SAAS;QACX,OAAO;YACL,EAAE,EAAE,IAAI;YACR,GAAG,EAAE,KAAK;YACV,IAAI,EAAE,MAAM;YACZ,UAAU,EAAE,YAAY;SACzB,CAAC;IACJ,CAAC;IACD,IAAI,YAAY;QACd,OAAO;YACL,IAAI,EAAE,MAAM;YACZ,UAAU,EAAE,YAAY;YACxB,MAAM,EAAE,QAAQ;SACjB,CAAC;IACJ,CAAC;IACD,IAAI,YAAY;QACd,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,KAAK,CAAC,gBAAgB;QACpB,OAAO,eAAe,EAAE,CAAC;IAC3B,CAAC;IAED,kCAAkC;IAClC,2BAA2B;IAC3B,iCAAiC;IACjC,KAAK,CAAC,WAAW,CACf,OAA6B,EAC7B,MAAsB;QAEtB,OAAO,MAAM,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;IAC3C,CAAC;IACD,KAAK,CAAC,YAAY,CAAC,MAAsB;QACvC,MAAM,MAAM,CAAC,YAAY,EAAE,CAAC;IAC9B,CAAC;IACD,KAAK,CAAC,aAAa,CAAC,MAAsB;QACxC,OAAO,MAAM,MAAM,CAAC,aAAa,EAAE,CAAC;IACtC,CAAC;IACD,KAAK,CAAC,4BAA4B;QAChC,OAAO,MAAM,YAAY,CAAC,4BAA4B,EAAE,CAAC;IAC3D,CAAC;IACD,KAAK,CAAC,wBAAwB,CAAC,KAAa,EAAE,MAAsB;QAClE,OAAO,MAAM,MAAM,CAAC,wBAAwB,CAAC,KAAK,CAAC,CAAC;IACtD,CAAC;CACF,CAAC","sourcesContent":["import { CameraCapturedPicture, CameraPictureOptions } from './Camera.types';\nimport CameraModule from './CameraModule/CameraModule';\nimport { canGetUserMedia } from './CameraModule/UserMediaManager';\nimport ExponentCamera from './ExponentCamera.web';\n\nexport default {\n get name(): string {\n return 'ExponentCameraManager';\n },\n get Type() {\n return {\n back: 'back',\n front: 'front',\n };\n },\n get FlashMode() {\n return {\n on: 'on',\n off: 'off',\n auto: 'auto',\n torch: 'torch',\n };\n },\n get AutoFocus() {\n return {\n on: 'on',\n off: 'off',\n auto: 'auto',\n singleShot: 'singleShot',\n };\n },\n get WhiteBalance() {\n return {\n auto: 'auto',\n continuous: 'continuous',\n manual: 'manual',\n };\n },\n get VideoQuality() {\n return {};\n },\n async isAvailableAsync(): Promise {\n return canGetUserMedia();\n },\n\n // TODO: Bacon: Is video possible?\n // record(options): Promise\n // stopRecording(): Promise\n async takePicture(\n options: CameraPictureOptions,\n camera: ExponentCamera\n ): Promise {\n return await camera.takePicture(options);\n },\n async pausePreview(camera: ExponentCamera): Promise {\n await camera.pausePreview();\n },\n async resumePreview(camera: ExponentCamera): Promise {\n return await camera.resumePreview();\n },\n async getAvailableCameraTypesAsync(): Promise {\n return await CameraModule.getAvailableCameraTypesAsync();\n },\n async getAvailablePictureSizes(ratio: string, camera: ExponentCamera): Promise {\n return await camera.getAvailablePictureSizes(ratio);\n },\n};\n"]} \ No newline at end of file diff --git a/packages/expo-camera/src/CameraModule/CameraModule.ts b/packages/expo-camera/src/CameraModule/CameraModule.ts index 250af1292c217..ccc2bb3dfa0ec 100644 --- a/packages/expo-camera/src/CameraModule/CameraModule.ts +++ b/packages/expo-camera/src/CameraModule/CameraModule.ts @@ -5,7 +5,11 @@ import { CameraPictureOptions } from '../Camera.types'; import { CameraType, CapturedPicture, CaptureOptions, ImageType } from './CameraModule.types'; import * as Utils from './CameraUtils'; import * as CapabilityUtils from './CapabilityUtils'; -import { isBackCameraAvailableAsync, isFrontCameraAvailableAsync } from './UserMediaManager'; +import { + isBackCameraAvailableAsync, + isFrontCameraAvailableAsync, + canGetUserMedia, +} from './UserMediaManager'; import { FacingModeToCameraType, PictureSizes } from './constants'; export { ImageType, CameraType, CaptureOptions }; @@ -294,10 +298,9 @@ class CameraModule { return PictureSizes; }; - public getAvailableCameraTypesAsync = async (): Promise => { - if (!navigator.mediaDevices.enumerateDevices) { - return []; - } + static async getAvailableCameraTypesAsync(): Promise { + if (!canGetUserMedia() || !navigator.mediaDevices.enumerateDevices) return []; + const devices = await navigator.mediaDevices.enumerateDevices(); const types: (string | null)[] = await Promise.all([ @@ -306,7 +309,7 @@ class CameraModule { ]); return types.filter(Boolean) as string[]; - }; + } } function stopMediaStream(stream: MediaStream | null) { diff --git a/packages/expo-camera/src/CameraModule/UserMediaManager.ts b/packages/expo-camera/src/CameraModule/UserMediaManager.ts index 0676f8e3e7415..407ab78803e6a 100644 --- a/packages/expo-camera/src/CameraModule/UserMediaManager.ts +++ b/packages/expo-camera/src/CameraModule/UserMediaManager.ts @@ -127,7 +127,7 @@ export function canGetUserMedia(): boolean { export async function isFrontCameraAvailableAsync( devices?: MediaDeviceInfo[] ): Promise { - return await supportsCameraType(['front', 'user'], 'user', devices); + return await supportsCameraType(['front', 'user', 'facetime'], 'user', devices); } export async function isBackCameraAvailableAsync( @@ -148,7 +148,9 @@ async function supportsCameraType( devices = await navigator.mediaDevices.enumerateDevices(); } const cameras = devices.filter(t => t.kind === 'videoinput'); - const [hasCamera] = cameras.filter(camera => labels.includes(camera.label.toLowerCase())); + const [hasCamera] = cameras.filter(camera => + labels.some(label => camera.label.toLowerCase().includes(label)) + ); const [isCapable] = cameras.filter(camera => { if (!('getCapabilities' in camera)) { return null; @@ -162,5 +164,5 @@ async function supportsCameraType( return capabilities.facingMode.find((_: string) => type); }); - return isCapable.deviceId || hasCamera.deviceId || null; + return isCapable?.deviceId || hasCamera?.deviceId || null; } diff --git a/packages/expo-camera/src/ExponentCamera.web.tsx b/packages/expo-camera/src/ExponentCamera.web.tsx index 0c316d39587c4..bd5fb98bdee12 100644 --- a/packages/expo-camera/src/ExponentCamera.web.tsx +++ b/packages/expo-camera/src/ExponentCamera.web.tsx @@ -67,11 +67,6 @@ export default class ExponentCamera extends React.Component { }); }; - getAvailableCameraTypesAsync = async (): Promise => { - const camera = this.getCamera(); - return await camera.getAvailableCameraTypesAsync(); - }; - resumePreview = async (): Promise => { const camera = this.getCamera(); await camera.resumePreview(); diff --git a/packages/expo-camera/src/ExponentCameraManager.web.ts b/packages/expo-camera/src/ExponentCameraManager.web.ts index f4f8d3dc99fc5..fcca5892d77ea 100644 --- a/packages/expo-camera/src/ExponentCameraManager.web.ts +++ b/packages/expo-camera/src/ExponentCameraManager.web.ts @@ -1,4 +1,5 @@ import { CameraCapturedPicture, CameraPictureOptions } from './Camera.types'; +import CameraModule from './CameraModule/CameraModule'; import { canGetUserMedia } from './CameraModule/UserMediaManager'; import ExponentCamera from './ExponentCamera.web'; @@ -57,9 +58,8 @@ export default { async resumePreview(camera: ExponentCamera): Promise { return await camera.resumePreview(); }, - async getAvailableCameraTypesAsync(camera: ExponentCamera): Promise { - if (!canGetUserMedia()) return []; - return await camera.getAvailableCameraTypesAsync(); + async getAvailableCameraTypesAsync(): Promise { + return await CameraModule.getAvailableCameraTypesAsync(); }, async getAvailablePictureSizes(ratio: string, camera: ExponentCamera): Promise { return await camera.getAvailablePictureSizes(ratio);