scrcpy_video_view 0.0.1 copy "scrcpy_video_view: ^0.0.1" to clipboard
scrcpy_video_view: ^0.0.1 copied to clipboard

PlatformmacOS

Low-latency Android screen streaming into Flutter textures using scrcpy and VideoToolbox on macOS.

scrcpy_video_view #

CI License: BSD-3-Clause

A Flutter plugin that renders a low-latency Android screen stream inside a macOS app. It reads H.264 packets directly from the scrcpy server, decodes them with VideoToolbox, and publishes the latest frame through a Flutter texture.

Android MediaCodec
      │ H.264 over a scrcpy socket forwarded by adb
      ▼
Dart packet reader
      │ Annex-B H.264 access units
      ▼
macOS VideoToolbox
      │ CVPixelBuffer
      ▼
Flutter Texture

Demo #

https://github.com/user-attachments/assets/d54d2d16-a5a7-448f-9a86-d61e0487e3f2

Platform support #

Platform Status
macOS 10.15+ Supported
Windows, Linux, iOS, Android, web Not implemented

Video is currently H.264-only and view-only. Audio and device control are not implemented.

Requirements #

  • Flutter with macOS desktop support
  • adb available on PATH, or supplied with adbPath
  • scrcpy available on PATH, or supplied with scrcpyPath
  • An Android device with USB debugging enabled and authorized
  • The macOS App Sandbox disabled in the host application

Verify the local setup before running the example:

adb devices -l
scrcpy --version

The plugin uses the installed scrcpy version and matching server binary. It does not enforce a version allowlist. Because scrcpy's client/server protocol is internal, a future release may require a compatibility update.

Installation #

dependencies::
...
    scrcpy_video_view: ^0.0.1

macOS entitlements #

Set com.apple.security.app-sandbox to false in both macos/Runner/DebugProfile.entitlements and macos/Runner/Release.entitlements:

<key>com.apple.security.app-sandbox</key>
<false/>

This is required because the plugin launches local adb processes, pushes the scrcpy server to the device, and connects to an adb-forwarded localhost socket.

Usage #

Create one controller for the lifetime of the video view:

final controller = ScrcpyVideoController();

final devices = await controller.discoverDevices();
if (devices.isNotEmpty) {
  await controller.start(devices.first.serial);
}

Render its texture:

ScrcpyVideo(
  controller: controller,
  fit: BoxFit.contain,
  placeholder: const Center(child: Text('No video')),
)

Observe state, dimensions, errors, and diagnostic logs through the controller:

controller.addListener(() {
  debugPrint('state: ${controller.state}');
  debugPrint('size: ${controller.videoWidth} x ${controller.videoHeight}');
  debugPrint('error: ${controller.error}');
});

Stop explicitly when appropriate and dispose the controller with its owning widget:

await controller.stop();
controller.dispose();

The native macOS implementation also records the active adb forward and server process so it can remove them if the application terminates before Dart cleanup runs.

Configuration #

Executable paths and encoding parameters can be customized:

final controller = ScrcpyVideoController(
  configuration: const ScrcpyVideoConfiguration(
    adbPath: '/path/to/adb',
    scrcpyPath: '/path/to/scrcpy',
    serverPath: '/path/to/scrcpy-server',
    maxSize: 1920,
    maxFps: 60,
    videoBitRate: 8 * 1000 * 1000,
  ),
);

If serverPath is omitted, the plugin checks SCRCPY_SERVER_PATH and common Homebrew installation locations.

Handling errors #

Failures use ScrcpyVideoException with a machine-readable ScrcpyVideoErrorCode, so applications can present targeted recovery steps:

try {
  await controller.start(serial);
} on ScrcpyVideoException catch (error) {
  switch (error.code) {
    case ScrcpyVideoErrorCode.adbNotFound:
      showSetupMessage('Install Android platform tools.');
    case ScrcpyVideoErrorCode.scrcpyNotFound:
      showSetupMessage('Install scrcpy or configure scrcpyPath.');
    case ScrcpyVideoErrorCode.noAuthorizedDevices:
      showSetupMessage('Connect and authorize an Android device.');
    case ScrcpyVideoErrorCode.unsupportedScrcpyProtocol:
      showSetupMessage('Report your scrcpy version and controller logs.');
    default:
      showSetupMessage(error.message);
  }
}

Available codes also distinguish adb command failures, missing server binaries, connection failures, decoder failures, unexpected stream closure, unsupported platforms, and uncategorized failures. The original low-level failure is available through error.cause when one exists.

Example #

The example includes device discovery, start/stop controls, logs, and the reusable video widget:

cd example
flutter run -d macos

Reporting compatibility problems #

Open a bug report with the following information:

  • scrcpy version
  • Flutter version
  • macOS and Android versions
  • Device model
  • Complete controller.logs output

Please remove device serial numbers or other sensitive values before posting logs publicly.

Contributing #

Contributions are welcome. Read CONTRIBUTING.md and the Code of Conduct before opening a pull request. For vulnerabilities, follow SECURITY.md instead of opening a public issue.

License and attribution #

scrcpy_video_view is available under the BSD 3-Clause License.

This project is an independent integration built around Genymobile/scrcpy. It is not affiliated with or endorsed by the scrcpy project. scrcpy and its server are not bundled in this package.

0
likes
150
points
90
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

Low-latency Android screen streaming into Flutter textures using scrcpy and VideoToolbox on macOS.

Repository (GitHub)
View/report issues
Contributing

Topics

#scrcpy #android #video #streaming #macos

License

BSD-3-Clause (license)

Dependencies

flutter, plugin_platform_interface

More

Packages that depend on scrcpy_video_view

Packages that implement scrcpy_video_view