Flutter macOS摄像头访问插件gsmlg_camera_macos的使用

Flutter macOS摄像头访问插件gsmlg_camera_macos的使用

Camera macOS

AVKit 摄像头实现用于 macOS。可以拍照或录制视频,甚至支持外接摄像头。


开始使用

获取开始

  • 设置
  • 基本用法
    • 拍照
    • 录制视频
  • 限制与注意事项
  • 未来开发计划
  • 许可证

设置

在您的项目中,将以下两行添加到 macos/Runner/Info.plist 文件中:

<key>NSCameraUsageDescription</key>
<string>your usage description here</string>
<key>NSMicrophoneUsageDescription</key>
<string>your usage description here</string>

并在 Debug.EntitlementsRelease.Entitlements 文件中添加以下内容:

<key>com.apple.security.device.audio-input</key>
<true/>
<key>com.apple.security.device.camera</key>
<true/>

基本用法

在您的小部件树中集成 CameraMacOSView。您可以选择 BoxFit 方法和 CameraMacOSModephotovideo)。当相机初始化时,会创建一个 CameraMacOSController 对象,可用于执行基本操作,例如拍照和录制视频。

示例代码:

final GlobalKey cameraKey = GlobalKey("cameraKey");
late CameraMacOSController macOSController;

// 构建方法
CameraMacOSView(
    key: cameraKey,
    fit: BoxFit.fill,
    cameraMode: CameraMacOSMode.photo,
    onCameraInizialized: (CameraMacOSController controller) {
        setState(() {
            this.macOSController = controller;
        });
    },
),

外接摄像头

该插件支持外接摄像头,而不仅仅是主 Mac 摄像头。您可以通过可选参数 deviceId 指定摄像头 ID,通过 audioDeviceId 指定麦克风 ID。这两个 ID 都与 AVCaptureDeviceuniqueID 属性相关,并且可以通过 listDevices 方法获取。

示例代码:

String? deviceId;
String? audioDeviceId;

// 列出设备
List<CameraMacOSDevice> videoDevices = await CameraMacOS.instance.listDevices({ deviceType: CameraMacOSMode.video });
List<CameraMacOSDevice> audioDevices = await CameraMacOS.instance.listDevices({ deviceType: CameraMacOSMode.audio });

// 设置设备
deviceId = videoDevices.first.deviceId;
audioDeviceId = audioDevices.first.deviceId;

// 构建方法
CameraMacOSView(
    deviceId: deviceId, // 可选参数,指定摄像头,默认为主摄像头
    audioDeviceId: audioDeviceId, // 可选参数,指定麦克风,默认为主麦克风
    cameraMode: CameraMacOSMode.video,
    onCameraInizialized: (CameraMacOSController controller) {
        // 初始化完成后的逻辑
    },
),

CameraMacOSDevice 对象包含以下属性(映射自原始 AVCaptureDevice 类):

  • deviceId
  • localizedName
  • manufacturer
  • deviceType(视频或音频)

创建 CameraMacOSView 小部件后,您将获得一个 CameraMacOSController 对象,这是您进行主要功能(拍照和录像)的桥梁。您还可以通过控制器中的 CameraMacOSArguments 属性了解刚刚创建的相机对象的信息。


设置摄像头焦点

可以通过 setFocusPoint 方法设置摄像头的焦点。

示例代码:

macOSController.setFocusPoint(Offset(0.5, 0.5));

CameraMacOSView 小部件默认启用此功能。

注意:偏移量需要在 01 之间。


打开/关闭闪光灯

可以通过 toggleTorch 方法打开、关闭或自动调节闪光灯。

示例代码:

macOSController.toggleTorch(Torch.on);

CameraMacOSView 小部件默认禁用此功能。


设置方向

可以通过 setOrientation 方法将方向设置为 0°、90°、180° 或 270°。

注意:此功能仅适用于 macOS < 14.0 和 Swift < 15。

示例代码:

macOSController.setOrientation(CameraOrientation.orientation0deg);

CameraMacOSView 小部件默认方向为 0°。


设置缩放

警告:此功能目前仅适用于 imageStream

可以通过 setZoomLevel 方法从 1 到无穷大设置缩放级别。

示例代码:

macOSController.setZoomLevel(1.0);

CameraMacOSView 小部件默认缩放级别为 1。


拍照

可以通过 takePicture 方法拍照。

注意:目前无法更改缩放或应用效果。

示例代码:

CameraMacOSFile? file = await macOSController.takePicture();
if(file != null) {
    Uint8List? bytes = file.bytes;
    // 处理文件...
}

流式传输图像

可以通过 startImageStream 方法流式传输图像,并通过 stopImageStream 方法停止流式传输。

示例代码:

macOSController.startImageStream((CameraImageData imageData){
    // 在这里放置您的代码
});

macOSController.stopImageStream();

注意:流式数据以 argb8888 格式返回。


录制视频

可以通过 recordVideo 方法录制视频,并通过 stopVideoRecording 方法停止录制。

示例代码:

macOSController.recordVideo(
    url: // 从路径提供者等包中获取 URL,
    maxVideoDuration: 30, // 持续时间(秒),
    onVideoRecordingFinished: (CameraMacOSFile? file, CameraMacOSException? exception) {
        // 当达到最大录制时间时调用
        // 处理文件或捕获异常
    }
);

CameraMacOSFile? file = await macOSController.stopVideoRecording();

if(file != null) {
    Uint8List? bytes = file.bytes;
    // 处理文件...
}

视频设置

您可以启用或禁用音频录制,通过 enableAudio 标志。

默认视频设置包括:

  • 最高可用分辨率 - 可通过设置 resolution 属性更改
  • 最高可用音频质量 - 可通过设置 audioQuality 属性更改
  • 默认麦克风编码器 (apple lossless) - 可通过设置 audioFormat 属性更改
  • 默认视频格式 (mp4) - 可通过设置 videoFormat 属性更改
  • 默认视频输出镜像翻转 - 可通过设置 isVideoMirrored 属性更改

您可以设置录制视频的最大持续时间(以秒为单位),并在时间到达后触发原生计时器,调用 onVideoRecordingFinished 方法。

您还可以设置保存视频文件的位置,默认位于应用程序的 Library/Cache 目录中。

音频录制可以通过 enableAudio 标志在摄像机初始化阶段或在 recordVideo 方法中启用或禁用(默认为 true)。


输出

拍摄照片或视频后,将生成一个 CameraMacOSFile 对象,其中包含内容的 bytes。如果指定了视频的 url 存储位置,则还会返回文件路径。


小部件刷新

  • 如果更改小部件的 KeydeviceIdCameraMacOsMode,小部件将重新初始化。

限制与注意事项

  • 插件支持 macOS 10.11 及更高版本。
  • 此插件只是官方 Flutter 团队 camera 包的临时替代品,仅适用于 macOS
  • 方向仅适用于 macOS < 14.0 和 Swift < 15。
  • 当前不支持缩放。

未来开发计划

  • 支持视频和纹理的缩放。

许可证

MIT


完整示例代码

以下是完整的示例代码,展示如何使用 gsmlg_camera_macos 插件进行拍照和录像:

import 'package:flutter/material.dart';
import 'package:gsmlg_camera_macos/camera_macos.dart';
import 'package:path_provider/path_provider.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      home: CameraExample(),
    );
  }
}

class CameraExample extends StatefulWidget {
  [@override](/user/override)
  _CameraExampleState createState() => _CameraExampleState();
}

class _CameraExampleState extends State<CameraExample> {
  late CameraMacOSController controller;

  Future<void> initializeCamera() async {
    final devices = await CameraMacOS.instance.listDevices();
    String? deviceId = devices.firstWhere((d) => d.deviceType == CameraMacOSMode.video).deviceId;

    controller = CameraMacOSController(
      deviceId: deviceId,
      cameraMode: CameraMacOSMode.video,
      onCameraInizialized: (c) {
        setState(() {
          controller = c;
        });
      },
    );
  }

  Future<void> takePicture() async {
    final file = await controller.takePicture();
    if (file != null) {
      print('Picture saved at ${file.path}');
    }
  }

  Future<void> startRecording() async {
    final directory = await getTemporaryDirectory();
    final videoPath = '${directory.path}/video.mp4';

    await controller.recordVideo(
      url: videoPath,
      maxVideoDuration: 10,
      onVideoRecordingFinished: (file, error) {
        if (file != null) {
          print('Video saved at ${file.path}');
        } else {
          print('Error: $error');
        }
      },
    );
  }

  [@override](/user/override)
  void initState() {
    super.initState();
    initializeCamera();
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Camera Example')),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            ElevatedButton(
              onPressed: takePicture,
              child: Text('Take Picture'),
            ),
            ElevatedButton(
              onPressed: startRecording,
              child: Text('Start Recording'),
            ),
          ],
        ),
      ),
    );
  }
}

更多关于Flutter macOS摄像头访问插件gsmlg_camera_macos的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter macOS摄像头访问插件gsmlg_camera_macos的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


gsmlg_camera_macos 是一个用于在 Flutter macOS 应用中访问摄像头的插件。以下是如何使用这个插件的详细步骤:

1. 添加依赖

首先,你需要在 pubspec.yaml 文件中添加 gsmlg_camera_macos 插件的依赖。

dependencies:
  flutter:
    sdk: flutter
  gsmlg_camera_macos: ^0.0.1  # 请使用最新版本

然后运行 flutter pub get 来获取依赖。

2. 配置 macOS 权限

在 macOS 应用中访问摄像头需要配置相应的权限。你需要在 macos/Runner/DebugProfile.entitlementsmacos/Runner/Release.entitlements 文件中添加以下内容:

<key>com.apple.security.device.camera</key>
<true/>

3. 使用插件

在你的 Flutter 代码中,你可以使用 gsmlg_camera_macos 插件来访问摄像头。以下是一个简单的示例:

import 'package:flutter/material.dart';
import 'package:gsmlg_camera_macos/gsmlg_camera_macos.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      home: CameraScreen(),
    );
  }
}

class CameraScreen extends StatefulWidget {
  [@override](/user/override)
  _CameraScreenState createState() => _CameraScreenState();
}

class _CameraScreenState extends State<CameraScreen> {
  CameraController? _cameraController;

  [@override](/user/override)
  void initState() {
    super.initState();
    _initializeCamera();
  }

  Future<void> _initializeCamera() async {
    final cameras = await GsmlgCameraMacos.availableCameras();
    if (cameras.isNotEmpty) {
      _cameraController = CameraController(
        cameras.first,
        ResolutionPreset.high,
      );
      await _cameraController!.initialize();
      if (!mounted) return;
      setState(() {});
    }
  }

  [@override](/user/override)
  void dispose() {
    _cameraController?.dispose();
    super.dispose();
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    if (_cameraController == null || !_cameraController!.value.isInitialized) {
      return Center(child: CircularProgressIndicator());
    }
    return Scaffold(
      appBar: AppBar(title: Text('Camera Example')),
      body: Center(
        child: CameraPreview(_cameraController!),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () async {
          if (_cameraController != null) {
            final image = await _cameraController!.takePicture();
            // 处理拍摄的照片
            print('Image saved to ${image.path}');
          }
        },
        child: Icon(Icons.camera),
      ),
    );
  }
}
回到顶部