Post

[flutter_ffi_uvc] Flutter USB Camera

[flutter_ffi_uvc] Flutter USB Camera

This post was migrated from Tistory. You can find the original here.

Criteria for choosing a technology

When I need a package while developing in Flutter, I approach it like this:

  1. Search pub.dev for candidate packages.
  2. Do a first pass of screening based on supported platforms, dependencies, project maturity, etc.
  3. For packages that pass that screening, build the example directly and check whether it builds cleanly and whether the flow I have in mind is actually feasible.
  4. Then read through the code to figure out the author’s intent — whether it’s usable for my project and whether there are any hidden risks.

When reviewing a library, I’d rather keep the scope of any fixes limited than chase errors too deeply.

I also prefer wrapping the original source over modifying it directly.

If fixing one error leads to a chain of further errors, I treat that as a structural problem and hold off on using the library.

Even if I can patch the errors I can see, hidden issues can end up costing a lot more down the line.

At the same time, I also ask myself “would it be better to just implement this myself?”, weighing factors like:

  • The pros and cons compared to existing packages
  • How much would be covered by the dependency versus how much I’d have to build myself, and the effort that implies
  • Technical uncertainty — the general shape is clear, but there will be detail problems that surface once I actually get into it

Reviewing UVC libraries

For background on the UVC protocol, see the earlier post:

2026.04.10 - [Engineering/system (device, embedded)] - UVC(USB Video Class) Camera

libuvc - a C library that abstracts the UVC protocol and provides camera control and streaming functionality; internally it uses libusb to communicate with the device.

UVCCamera (saki4510t) - a library built on libuvc that supports UVC camera control and streaming on Android.

Last commit: October 2018

AndroidUSBCamera (jiangdongguo) - also a library built on libuvc that supports UVC camera control and streaming on Android.

Last commit: September 2024

For Flutter packages,

the common pattern is to wrap a native (Android/iOS) library and expose it through a MethodChannel.

The existing UVC Flutter packages are also built on top of either UVCCamera or AndroidUSBCamera.

After running the samples for UVCCamera and AndroidUSBCamera, the overall experience wasn’t smooth.

Considering building a Flutter UVC package myself

There are a few ways to implement a package that uses C/C++ from Flutter:

  1. Use libuvc on Android via JNI (MethodChannel)
  2. Wrap a library built with approach 1 (MethodChannel)
  3. Use libuvc directly from Flutter via Dart FFI (FFI)

Options 1 and 2 already turned out to have poor usability in the review above.

Looking at option 3:

  • libuvc is a small repository, roughly 1-2MB, with a manageable number of files.
  • The C libraries (.so) that need to be built alongside it are libusb and libjpeg-turbo, and
    both already have their build configurations well maintained (higher odds it will actually build).

I’m also already comfortable with the structure of integrating a C/C++ native layer via Dart FFI, having previously built the mediapipe_face_mesh package.

2026.01.01 - [MediaPipe Face Mesh] Building a Flutter package

Overall, this looked feasible.

flutter_ffi_uvc

https://pub.dev/packages/flutter_ffi_uvc

An FFI package that integrates directly with libuvc with no intermediate library, supporting UVC camera connection, control, streaming, and preview.

libuvc doesn’t support iOS, and neither does flutter_ffi_uvc.

libuvc does have functions for discovering and connecting to devices, such as uvc_get_device_list() and uvc_open(),

but device discovery at the libusb level is limited by Android’s device permission model and system constraints.

So device discovery and USB permission acquisition/connection are handled through the Android USB Host API,

while the actual USB communication and UVC control/streaming are done in the C native layer built on libusb + libuvc.

v0.1.0 example(1)

v0.1.0 example(2)

v0.2.0 example .gif


This post is licensed under CC BY-NC 4.0 by the author.