stera_recorder 0.0.1
stera_recorder: ^0.0.1 copied to clipboard
ARKit and ARCore capture for Flutter, recorded straight to an MCAP dataset: RGB video, depth, point cloud, mesh and IMU, with session state and settings ready to bind to your own UI.
stera_recorder #
The AR recording engine behind Stera: an ARKit (iOS) / ARCore (Android) capture session that writes an MCAP dataset — RGB video, depth, point cloud, mesh and IMU — plus the Dart API the app drives it with.
This is a Flutter plugin: the Swift and Kotlin implementations live here, and
register themselves through GeneratedPluginRegistrant. There is no manual
wiring in the host app's SceneDelegate / MainActivity.
Layout #
lib/src/
channels/ ar_recorder channel name + method enum (shipped native contract)
service/ ArRecorderService — the method-channel / FFI facade
ffi/ iOS interop: the ffigen output plus its typed wrapper
data/ RecordingConfig and the recorder/tracking/resolution enums
config/ RecorderPreferences + RecorderPermissions (host-supplied)
managers/ ArRecordingConfigManager — the settings and their persistence
providers/ ArRecorderProvider — the ChangeNotifier the UI binds to
services/ audio cues, voice commands, battery monitoring
ios/ Swift Package (stera_recorder/Sources/) plus the podspec that
compiles the same sources: session, frame pipeline, encoders,
MCAP writers
android/ Kotlin: the same triad, plus the ARCore dependency
ffi/ ARRecorderInterop.h — ffigen input only, not compiled into the pod
Using it #
The host app supplies persistence and permissions, then builds its own UI on top
of ArRecorderProvider:
ChangeNotifierProvider(
create: (_) => ArRecorderProvider(
preferences: const KvStoreRecorderPreferences(),
permissions: const AppRecorderPermissions(),
),
)
RecorderPrefKeys holds the persisted setting keys. They are shipped state —
never change a value, or every user's recording settings reset.
Example #
example/ is a one-screen app — permission, preview, record, stop — that runs
the plugin without the rest of Stera:
cd example && flutter run
It needs a physical ARKit or ARCore device; there is no AR session on a simulator or emulator.
Native contract #
The channel name (ar_recorder) and the method names in ArRecorderMethod must
stay in lockstep with ArRecorderMethodChannelHandler.swift / .kt.
On iOS the hot paths (startRecording, stopRecording, getRecordingState, …)
bypass the method channel and go through FFI. The generated bindings look
classes up by their Objective-C runtime name, which is why
ArRecorderInterop.swift pins them with explicit @objc(ARFRecordingConfig)
style annotations — without those the names would carry the Swift module prefix
and every FFI call would fail at class lookup.
Regenerate the bindings after changing ffi/ARRecorderInterop.h:
dart run tool/generate_ar_recorder_objc_bindings.dart
Known limitations #
Two forward-compatibility items Flutter warns about today and will eventually enforce:
- Swift Package Manager. iOS ships as a CocoaPods pod only. SwiftPM can't
express this target as-is — it mixes Swift with the Objective-C
ObjCTryBlockshim, which SwiftPM requires to be a separate target. - Built-in Kotlin.
android/build.gradlestill applies the Kotlin Gradle Plugin itself. Moving to AGP's built-in Kotlin needs AGP 9, above what the host app pins.