# camera_desktop
**Repository Path**: imboy-tripartite-deps/camera_desktop
## Basic Information
- **Project Name**: camera_desktop
- **Description**: 镜像 https://github.com/hugocornellier/camera_desktop.git
- **Primary Language**: Dart
- **License**: MIT
- **Default Branch**: main
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2026-10-08
- **Last Updated**: 2026-10-08
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
camera_desktop
A Flutter camera plugin for desktop platforms. Implements
[`camera_platform_interface`](https://pub.dev/packages/camera_platform_interface)
so it works seamlessly with the standard
[`camera`](https://pub.dev/packages/camera) package and `CameraController`.
## Platform Support
| Platform | Backend | Status |
|----------|---------|--------|
| **Linux** | GStreamer + V4L2 | Included |
| **macOS** | AVFoundation | Included |
| **Windows** | Media Foundation | Included |
## Installation
Add `camera_desktop` alongside `camera` in your `pubspec.yaml`:
```yaml
dependencies:
camera: ^0.11.0
camera_desktop: ^2.0.0
```
That's it. All three desktop platforms are covered, no additional packages needed.
## Usage
Use the standard `camera` package API:
```dart
import 'package:camera/camera.dart';
final cameras = await availableCameras();
final controller = CameraController(cameras.first, ResolutionPreset.high);
await controller.initialize();
// Preview
CameraPreview(controller);
// Capture
final file = await controller.takePicture();
// Record
await controller.startVideoRecording();
final video = await controller.stopVideoRecording();
```
### Advanced Settings
`CameraController` (camera 0.11.x+) accepts optional `fps`, `videoBitrate`, and
`audioBitrate` parameters at construction time:
```dart
final controller = CameraController(
cameras.first,
ResolutionPreset.veryHigh,
enableAudio: true,
fps: 30,
videoBitrate: 5000000, // 5 Mbps
audioBitrate: 128000, // 128 kbps
);
```
These settings are applied during `initialize()`. To change them you must
`dispose()` the controller and create a new one, see [Limitations](#limitations).
## Platform-Specific Setup
### Linux
Install GStreamer development libraries:
```bash
# Ubuntu/Debian
sudo apt install libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev gstreamer1.0-plugins-good
# Fedora
sudo dnf install gstreamer1-devel gstreamer1-plugins-base-devel gstreamer1-plugins-good
# Arch
sudo pacman -S gstreamer gst-plugins-base gst-plugins-good
```
### macOS
Add camera and microphone usage descriptions to your `Info.plist`:
```xml
NSCameraUsageDescription
This app needs camera access.
NSMicrophoneUsageDescription
This app needs microphone access for video recording.
```
For sandboxed apps, add to your entitlements:
```xml
com.apple.security.device.camera
com.apple.security.device.audio-input
```
### Windows
No additional setup required.
## Features
| Feature | Linux | macOS | Windows |
|---------|-------|-------|---------|
| Camera enumeration | Yes | Yes | Yes |
| Live preview | Yes | Yes | Yes |
| Photo capture | Yes | Yes | Yes |
| Video recording | Yes | Yes | Yes |
| Image streaming | Yes | Yes | Yes |
| Audio recording | Yes | Yes | Yes |
| Resolution presets | Yes | Yes | Yes |
| Custom FPS | Yes | Yes | Yes |
| Video bitrate control | Yes | Yes | Yes |
| Audio bitrate control | Yes | Yes | Yes |
| Mirror control | Yes | Yes | No (handled in Flutter) |
## Mirror / Flip Behavior
On **macOS** and **Linux**, the preview frames are mirrored at the native capture
level (like a webcam selfie view), so `buildPreview()` returns the texture as-is.
The mirror state can be toggled at runtime via `setMirror()`:
```dart
import 'package:camera_desktop/camera_desktop.dart';
// Toggle mirror at runtime (macOS & Linux only)
final plugin = CameraDesktopPlugin();
await plugin.setMirror(cameraId, false); // disable mirror
await plugin.setMirror(cameraId, true); // re-enable mirror
```
On **Windows**, the native backend does not mirror, so `buildPreview()` wraps the
preview in a horizontal `Transform` in Flutter:
```dart
if (Platform.isWindows) {
return Transform(
alignment: Alignment.center,
transform: Matrix4.diagonal3Values(-1, 1, 1),
child: Texture(textureId: textureId),
);
}
```
The same applies to video playback. Recorded files from macOS/Linux are already
mirrored, while Windows recordings need a Flutter-side flip if you want a
mirror-style playback.
Image stream frames on macOS and Linux come from the same mirrored capture as
the preview and follow `setMirror()`. On Windows the mirroring is applied only
to the preview widget, so stream frames are **not** mirrored: flip any overlay
you draw from stream coordinates on top of the Windows preview.
## Image Stream Format
Frames from `startImageStream` use the same format on every desktop platform,
matching `camera` on iOS and macOS:
- `image.format.group` is `ImageFormatGroup.bgra8888` and `image.format.raw` is
`'BGRA'`.
- There is a single plane with 4 bytes per pixel in **B, G, R, A** order.
- Rows can be padded (macOS in particular), so always use
`planes[0].bytesPerRow` as the row stride rather than `width * 4`.
- The requested `imageFormatGroup` on `CameraController` is ignored; desktop
streams are always BGRA.
With [`package:image`](https://pub.dev/packages/image):
```dart
final plane = image.planes[0];
final decoded = img.Image.fromBytes(
width: image.width,
height: image.height,
bytes: plane.bytes.buffer,
bytesOffset: plane.bytes.offsetInBytes,
rowStride: plane.bytesPerRow,
numChannels: 4,
order: img.ChannelOrder.bgra,
);
```
## Platform Capabilities
Query what the current platform supports at runtime:
```dart
import 'package:camera_desktop/camera_desktop.dart';
final caps = await CameraDesktopPlugin().getPlatformCapabilities();
// caps['supportsMirrorControl'] == true (macOS & Linux)
// caps['supportsVideoFpsControl'] == true
// caps['supportsVideoBitrateControl'] == true
// caps['supportsAudioBitrateControl'] == true
```
This is useful when building UIs that conditionally expose controls based on the
running platform.
## Limitations
Desktop cameras generally do not support mobile-oriented features:
- Flash/torch control
- Exposure/focus point selection
- Zoom (beyond 1.0x)
- Device orientation changes
- Pause/resume video recording
These methods either no-op or throw `CameraException` as appropriate.
`fps`, `videoBitrate`, and `audioBitrate` are applied at initialization and cannot
be changed on a running controller. To update them, `dispose()` the controller and
create a new one with the desired settings.