Skip to content

Commit

Permalink
Added a screenshot button (#56)
Browse files Browse the repository at this point in the history
Fixes #12
  • Loading branch information
Levi-Lesches authored Feb 22, 2023
1 parent ca4ecfe commit 5f47d4f
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 15 deletions.
8 changes: 8 additions & 0 deletions lib/src/models/data/video.dart
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,14 @@ class VideoModel extends Model {
notifyListeners();
}

/// Takes a screenshot of the current frame.
Future<void> saveFrame(CameraFeed feed) async {
final List<int>? cachedFrame = feed.frame;
if (cachedFrame == null) throw ArgumentError.notNull("Feed for ${feed.name}");
await services.files.writeImage(cachedFrame, feed.name);
models.home.setMessage(severity: Severity.info, text: "Screenshot saved");
}

/// Gets the camera feed with the given ID.
CameraFeed getCameraFeed(CameraName id) => allFeeds.firstWhere((feed) => feed.id == id);

Expand Down
8 changes: 8 additions & 0 deletions lib/src/services/files.dart
Original file line number Diff line number Diff line change
Expand Up @@ -54,4 +54,12 @@ class FilesService extends Service {
return settings;
}
}

/// Saves the current frame in the feed to the camera's output directory.
Future<void> writeImage(List<int> image, String cameraName) async {
final dir = Directory("${outputDir.path}/$cameraName");
if (!(await dir.exists())) await dir.create();
final timestamp = DateTime.now().toString();
await File("${dir.path}/$timestamp.jpg").writeAsBytes(image);
}
}
35 changes: 20 additions & 15 deletions lib/src/widgets/atomic/video_feed.dart
Original file line number Diff line number Diff line change
Expand Up @@ -83,21 +83,26 @@ class VideoFeedState extends State<VideoFeed> {
child: image == null ? Text(errorMessage)
: Row(children: [Expanded(child: RawImage(image: image, fit: BoxFit.fill))]),
),
Positioned(
top: 4,
right: 4,
child: PopupMenuButton<CameraFeed>(
tooltip: "Select a feed",
icon: const Icon(Icons.more_horiz),
onSelected: selectNewFeed,
itemBuilder: (_) => [
for (final other in VideoModel.allFeeds) PopupMenuItem(
value: other,
child: Text(other.name),
),
]
)
)
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
if (feed.isActive) IconButton(
icon: const Icon(Icons.camera_alt),
onPressed: () => models.video.saveFrame(feed),
),
PopupMenuButton<CameraFeed>(
tooltip: "Select a feed",
icon: const Icon(Icons.more_horiz),
onSelected: selectNewFeed,
itemBuilder: (_) => [
for (final other in VideoModel.allFeeds) PopupMenuItem(
value: other,
child: Text(other.name),
),
]
)
]
),
]
);

Expand Down

0 comments on commit 5f47d4f

Please sign in to comment.