| // Copyright 2013 The Flutter Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| import 'dart:html' as html; |
| import 'dart:ui'; |
| |
| import 'package:camera_platform_interface/camera_platform_interface.dart'; |
| import 'package:camera_web/src/types/types.dart'; |
| import 'package:flutter/foundation.dart'; |
| |
| /// A utility to fetch and map camera settings. |
| class CameraSettings { |
| // A facing mode constraint name. |
| static const _facingModeKey = "facingMode"; |
| |
| /// The current browser window used to access media devices. |
| @visibleForTesting |
| html.Window? window = html.window; |
| |
| /// Returns a facing mode of the [videoTrack] |
| /// (null if the facing mode is not available). |
| String? getFacingModeForVideoTrack(html.MediaStreamTrack videoTrack) { |
| final mediaDevices = window?.navigator.mediaDevices; |
| |
| // Throw a not supported exception if the current browser window |
| // does not support any media devices. |
| if (mediaDevices == null) { |
| throw CameraException( |
| CameraErrorCodes.notSupported, |
| 'The camera is not supported on this device.', |
| ); |
| } |
| |
| // Check if the camera facing mode is supported by the current browser. |
| final supportedConstraints = mediaDevices.getSupportedConstraints(); |
| final facingModeSupported = supportedConstraints[_facingModeKey] ?? false; |
| |
| // Return null if the facing mode is not supported. |
| if (!facingModeSupported) { |
| return null; |
| } |
| |
| // Extract the facing mode from the video track settings. |
| // The property may not be available if it's not supported |
| // by the browser or not available due to context. |
| // |
| // MediaTrackSettings: |
| // https://developer.mozilla.org/en-US/docs/Web/API/MediaTrackSettings |
| final videoTrackSettings = videoTrack.getSettings(); |
| final facingMode = videoTrackSettings[_facingModeKey]; |
| |
| if (facingMode == null) { |
| try { |
| // If the facing mode does not exist in the video track settings, |
| // check for the facing mode in the video track capabilities. |
| // |
| // MediaTrackCapabilities: |
| // https://www.w3.org/TR/mediacapture-streams/#dom-mediatrackcapabilities |
| // |
| // This may throw a not supported error on Firefox. |
| final videoTrackCapabilities = videoTrack.getCapabilities(); |
| |
| // A list of facing mode capabilities as |
| // the camera may support multiple facing modes. |
| final facingModeCapabilities = |
| List<String>.from(videoTrackCapabilities[_facingModeKey] ?? []); |
| |
| if (facingModeCapabilities.isNotEmpty) { |
| final facingModeCapability = facingModeCapabilities.first; |
| return facingModeCapability; |
| } else { |
| // Return null if there are no facing mode capabilities. |
| return null; |
| } |
| } catch (e) { |
| switch (e.runtimeType.toString()) { |
| case 'JSNoSuchMethodError': |
| // Return null if getting capabilities is currently not supported. |
| return null; |
| default: |
| throw CameraException( |
| CameraErrorCodes.unknown, |
| 'An unknown error occured when getting the video track capabilities.', |
| ); |
| } |
| } |
| } |
| |
| return facingMode; |
| } |
| |
| /// Maps the given [facingMode] to [CameraLensDirection]. |
| /// |
| /// The following values for the facing mode are supported: |
| /// https://developer.mozilla.org/en-US/docs/Web/API/MediaTrackSettings/facingMode |
| CameraLensDirection mapFacingModeToLensDirection(String facingMode) { |
| switch (facingMode) { |
| case 'user': |
| return CameraLensDirection.front; |
| case 'environment': |
| return CameraLensDirection.back; |
| case 'left': |
| case 'right': |
| default: |
| return CameraLensDirection.external; |
| } |
| } |
| |
| /// Maps the given [facingMode] to [CameraType]. |
| /// |
| /// See [CameraMetadata.facingMode] for more details. |
| CameraType mapFacingModeToCameraType(String facingMode) { |
| switch (facingMode) { |
| case 'user': |
| return CameraType.user; |
| case 'environment': |
| return CameraType.environment; |
| case 'left': |
| case 'right': |
| default: |
| return CameraType.user; |
| } |
| } |
| |
| /// Maps the given [resolutionPreset] to [Size]. |
| Size mapResolutionPresetToSize(ResolutionPreset resolutionPreset) { |
| switch (resolutionPreset) { |
| case ResolutionPreset.max: |
| case ResolutionPreset.ultraHigh: |
| return Size(3840, 2160); |
| case ResolutionPreset.veryHigh: |
| return Size(1920, 1080); |
| case ResolutionPreset.high: |
| return Size(1280, 720); |
| case ResolutionPreset.medium: |
| return Size(720, 480); |
| case ResolutionPreset.low: |
| default: |
| return Size(320, 240); |
| } |
| } |
| } |