filmopen_recorder
Generated by scripts/package_digest.py; regenerate, never edit.
The issue recorder (Software Specification §6.8). While Recorder.instance records, every tap, drag, scroll, key, typed text, draft change, navigation, tab, route, setting and log event goes into tape.jsonl, with a JPEG of the whole view after each action, into a report folder beside the app’s logs (reportsDirectory(): on Windows %LOCALAPPDATA%\FilmOpen\reports\<YYMMDDHHMMSS>\). The folder also holds environment.json, the project’s text files as they were at the start (project/) and at the stop (project-after/), the library’s (library/) and the app log of this run and the one before, whole (log.jsonl, copyLogRuns, the runs named in environment.json’s logRuns). While it records the log is verbose (AppLog.forceVerbose), the setting untouched. On the web the tape is kept in memory and nothing is written.
Flutter. 8 files, 1,468 lines under lib/; 45 tests in 7 files. Barrel: lib/filmopen_recorder.dart.
Depends on
Section titled “Depends on”- filmopen_format — uses
Entity - filmopen_store — uses
AppLog,LogEntry,LogSink - filmopen_platform — uses
reportsDirectory - filmopen_state — uses
AutomationHost,BrowserState,DraftObserver,DraftObservers,FieldRegistry,LifecycleHook,NavIndex,OpenDrafts,RouteChange,RouteEvent,RouteEvents,RouteListener,SemanticsHit,Settings,browserProvider,builtMoment,currentTab,describeControl,findById,focusedTextIdentifier,isDictationCaption,isLiveDictationControl,localizationsProvider,navIndexProvider,projectProvider,selectionToJson,semanticsNodeAt,semanticsOwnerOf,settingsProvider,settleFramesand 2 more - filmopen_test_support (dev) — uses nothing by name the digest could see
Third-party: flutter_riverpod, image.
Used by
Section titled “Used by”filmopen_app, filmopen_automation, filmopen_support
Public API
Section titled “Public API”What the barrel exports, file by file. A name is class, enum, mixin, extension, typedef, a top-level function, getter, setter or variable; under a class, its public constructors, fields, getters, setters and methods.
lib/src/recorder.dart
Section titled “lib/src/recorder.dart”- typedef
typedef ShotCapture— Paints the whole view and answers it as JPEG bytes, or null when nothing can be painted. - class
Recorder— The issue recorder (§6.8): while it records, every action goes into a tape, with a picture of the whole view after each, into a report folder beside the app’s logs.Recorder({ Future<ReportFolder> Function()? openFolder, bool? writesFiles, this._capture, Future<void> Function()? settle, this.valueDelay = const…static Recorder instance— The recorder the app’s rail and the agent layer’s ops share.final ValueNotifier<bool> recording— Whether a recording runs; the rail’s button listens to it.final ValueNotifier<bool> busy— Whether a recording is starting or stopping — the open drafts, the folder, the snapshot — so a button can wait rather than be pressed twice.ValueListenable<int> get shots— How many pictures this recording has written: zero at [start], raised once a picture’s bytes and itsshotline are written, so that whoever listens acts after the capture — the flash that tells the person a picture…final Duration valueDelay— How long after the last key the boxes are read for what was typed.final double dragDistance— How far, in logical pixels, a pointer moves before a click is a drag.final Duration draftsLimit— The longest [start] and [stop] wait for the open drafts to be written.PictureSize get pictures— How this recording’s pictures are made.bool get isRecordingString? get folder— The report folder’s path while recording, or of the last recording; null for one kept in memory.ReportFolder? get lastFolder— The last recording’s folder, kept after [stop] (null in memory).int get events— How many events the tape holds.int get elapsedMilliseconds— The tape’s clock while a recording runs — what a line’stsays, so that a commentary’s lines and the tape’s share one clock — and zero while nothing records.bool get lastStopFailed— Whether the last [stop] failed after giving the doors back (its folder may lackproject-after/orlog.jsonl);recorder.failedsays why.Future<bool> start(ProviderContainer container, { String? appVersion, String? build, String? commit, String? builtAt, PictureSize pictures = const…— Starts a recording of the app [container] runs.Future<String?> stop({String reason = 'stopped'})— Ends the recording: reads the boxes a last time, waits for the last picture and the open drafts, gives back every door, writesstop, the project’s files as they are now and the log’s tail.Future<void> get idle— Waits for the picture and the state after the last action.
- function
Future<List<int>?> captureWindowJpeg({double? pixelRatio, int quality = 90})— The whole view ([AutomationHost.windowKey]) painted at [pixelRatio] — the view’s own where null — as JPEG of [quality] (§3.2).
lib/src/report_facts.dart
Section titled “lib/src/report_facts.dart”- class
PictureSize— How a recording’s pictures are made: how many pixels each logical pixel of the view gets, and the JPEG’s quality.const PictureSize({this.pixelRatio, this.quality = 90})final double? pixelRatio— Pixels per logical pixel; null for the view’s own ratio, which is the screen’s pixels.final int quality— The JPEG’s quality, 1 to 100.static const PictureSize person— A person’s recording: the view’s logical size at quality 80, so that a long recording travels light, far under the 300 MB a support server takes.
- function
String reportWord(String value, {required String fallback, int max = 64})— [value] where it is a word a report and a support ticket carry as it is, else [fallback].
lib/src/report_folder.dart
Section titled “lib/src/report_folder.dart”- class
ReportFolder— The files of one recording.String? get path— The folder’s path on disk; null for a recording kept in memory.void appendLine(String relativePath, String line)— Appends [line] and a newline to the file at [relativePath].void writeText(String relativePath, String text)— Writes [text] as the whole file at [relativePath].void writeBytes(String relativePath, List<int> bytes)— Writes [bytes] as the whole file at [relativePath].void appendBytes(String relativePath, List<int> bytes)— Appends [bytes] to the file at [relativePath]: the log, copied a chunk at a time.
- class
LogRuns— What a report’slog.jsonlholds of the app log (§6.8): the starts it begins at, what was copied, and where this run’s own lines begin in it.const LogRuns({ required this.starts, required this.lines, required this.bytes, required this.files, required this.thisRunFrom, required this.incom…static const LogRuns none— Nothing copied: no log file.final List<Map<String, Object?>> starts— Eachapp.startedthe copy holds, oldest first: its time and the app’s version.final int lines— How many lines were copied.final int bytes— How many bytes were copied.final int files— From how many of the log’s files.final int thisRunFrom— The byte oflog.jsonlwhere this run’s ownapp.startedbegins; 0 where it holds this run alone.final bool incomplete— Whether fewer runs than asked were found: the start before this one rotated away, or there was none.Map<String, Object?> toJson()— Asenvironment.jsonnames it, underlogRuns.
- class
MemoryReportFolder— A recording kept in memory: the web build’s, where nothing is written, and the tests’.final Map<String, String> texts— Every text file, by its path.final Map<String, List<int>> binaries— Every binary file, by its path.List<Map<String, Object?>> get tape— The tape’s lines as JSON objects.
- function
bool isReportPath(String relativePath)— Whether [relativePath] stays inside a report folder: not absolute, no drive, no backslash, no colon, no empty segment,.or... - function
void checkReportPath(String relativePath)— Refuses a path that could leave the report folder ([isReportPath]). - function
String reportStamp(DateTime at)— A recording’s folder name for the moment [at],YYMMDDHHMMSSin local time (§3.3);openReportFolderInadds-2,-3for a second recording in the same second. - function
bool isReportStamp(String stamp)— Whether [stamp] is a report folder’s name ([reportStamp]). - function
DateTime? stampTime(String stamp)— When a folder was made, from its [stamp], or null where it is not one. - function
String reportFolderName(String path)— The last segment of a report folder’s [path], its stamp: what the log and a receipt name it by, never the path, which holds the person’s user name on Windows (§6.8).
lib/src/report_folder_stub.dart
Section titled “lib/src/report_folder_stub.dart”- class
DirectoryReportFolder— A folder on disk: not here, where nothing is written.DirectoryReportFolder(this.path)
- variable
const bool hasReportFolders— Whether recordings are written to disk here: not on the web. - function
Future<ReportFolder> openReportFolder({DateTime? now})— Not available: a recording here is kept in memory. - function
String operatingSystemVersion() - function
String? userHomeDirectory()— No home here: the web has no paths of the person’s. - function
Future<LogRuns> copyLogRuns(String? path, void Function(List<int> bytes) append, {int runs = 2})— No log file here. - function
Future<List<int>?> encodeJpeg(int width, int height, Uint8List rgba, {int quality = 90})— No JPEG here: the web build writes no screenshot. - function
ReportFolder openReportFolderIn(String parent, {DateTime? now})— Not available: a recording here is kept in memory.
lib/src/snapshot.dart
Section titled “lib/src/snapshot.dart”- variable
const Set<String> kSnapshotExtensions— The extensions of the text files a snapshot copies (§3.3): the project’s JSON and the text beside it, never media. - function
bool isSnapshotPath(String path)— Whether [path] names a text file a snapshot copies. - function
Future<int> snapshotSource(ProjectSource source, ReportFolder folder, String prefix)— Copies every text file of [source] into [folder] under [prefix] (project,project-after,library), as it is, and answers how many were copied.
lib/src/tape.dart
Section titled “lib/src/tape.dart”- variable
const String kTapeFile— The tape’s file in a report folder. - class
TapeWriter— Appends one JSON object per tape event, leaving completed lines readable after a crash (§6.8).TapeWriter(this.folder, {DateTime Function()? clock, Stopwatch? watch})final ReportFolder folderint get elapsedMilliseconds— The tape’s clock: milliseconds since its first line, what every line’stsays.int get events— How many lines are written.int? write(String kind, [Map<String, Object?> fields = const {}])— Writes an event of [kind] with [fields]; answers itsseq, or null when the event was refused.
- function
bool isValueIdentifier(Object? id)— Whether [id] is an identifier under which a typed value travels into the tape. - variable
const String kDictationIdentifiers— Shared dictation’s identifiers, whose text never travels as taped text (Software Specification §9.6). - function
String utcMillis(DateTime time)— [time] in UTC as RFC 3339 with milliseconds:2026-09-15T10:04:05.123Z.
Internal
Section titled “Internal”Files under lib/ the barrel does not reach; nothing outside the package may import them.
lib/src/report_folder_io.dart:hasReportFolders,DirectoryReportFolder,openReportFolder,openReportFolderIn,operatingSystemVersion,userHomeDirectory,copyLogRuns,_eachChunk,_startLine,_startBytes,_mentionsStart,encodeJpeg