|
4 | 4 |
|
5 | 5 | #include "camera_plugin.h"
|
6 | 6 |
|
| 7 | +#include <flutter/event_channel.h> |
| 8 | +#include <flutter/event_stream_handler_functions.h> |
7 | 9 | #include <flutter/flutter_view.h>
|
8 | 10 | #include <flutter/method_channel.h>
|
9 | 11 | #include <flutter/plugin_registrar_windows.h>
|
@@ -32,6 +34,10 @@ namespace {
|
32 | 34 |
|
33 | 35 | const std::string kPictureCaptureExtension = "jpeg";
|
34 | 36 | const std::string kVideoCaptureExtension = "mp4";
|
| 37 | +constexpr char kFrameEventChannelName[] = |
| 38 | + "plugins.flutter.io/camera_android/imageStream"; |
| 39 | + |
| 40 | +std::unique_ptr<flutter::EventSink<flutter::EncodableValue>> event_sink; |
35 | 41 |
|
36 | 42 | // Builds CaptureDeviceInfo object from given device holding device name and id.
|
37 | 43 | std::unique_ptr<CaptureDeviceInfo> GetDeviceInfo(IMFActivate* device) {
|
@@ -116,12 +122,34 @@ std::optional<std::string> GetFilePathForVideo() {
|
116 | 122 | }
|
117 | 123 | } // namespace
|
118 | 124 |
|
| 125 | +// a setter for the event sink helpful for testing. |
| 126 | +void CameraPlugin::SetEventSink( |
| 127 | + std::unique_ptr<flutter::EventSink<flutter::EncodableValue>> events) { |
| 128 | + event_sink = std::move(events); |
| 129 | +} |
| 130 | + |
119 | 131 | // static
|
120 | 132 | void CameraPlugin::RegisterWithRegistrar(
|
121 | 133 | flutter::PluginRegistrarWindows* registrar) {
|
122 | 134 | std::unique_ptr<CameraPlugin> plugin = std::make_unique<CameraPlugin>(
|
123 | 135 | registrar->texture_registrar(), registrar->messenger());
|
124 | 136 |
|
| 137 | + auto frameEventchannel = std::make_unique<flutter::EventChannel<>>( |
| 138 | + registrar->messenger(), kFrameEventChannelName, |
| 139 | + &flutter::StandardMethodCodec::GetInstance()); |
| 140 | + |
| 141 | + auto event_channel_handler = |
| 142 | + std::make_unique<flutter::StreamHandlerFunctions<>>( |
| 143 | + [plugin = plugin.get()](auto arguments, auto events) { |
| 144 | + plugin->SetEventSink(std::move(events)); |
| 145 | + return nullptr; |
| 146 | + }, |
| 147 | + [](auto arguments) { |
| 148 | + event_sink.reset(); |
| 149 | + return nullptr; |
| 150 | + }); |
| 151 | + frameEventchannel->SetStreamHandler(std::move(event_channel_handler)); |
| 152 | + |
125 | 153 | CameraApi::SetUp(registrar->messenger(), plugin.get());
|
126 | 154 |
|
127 | 155 | registrar->AddPlugin(std::move(plugin));
|
@@ -341,6 +369,53 @@ void CameraPlugin::StopVideoRecording(
|
341 | 369 | }
|
342 | 370 | }
|
343 | 371 |
|
| 372 | +void CameraPlugin::StartImageStream( |
| 373 | + int64_t camera_id, |
| 374 | + std::function<void(std::optional<FlutterError> reply)> result) { |
| 375 | + // check if request already exists |
| 376 | + Camera* camera = GetCameraByCameraId(camera_id); |
| 377 | + if (!camera) { |
| 378 | + return result(FlutterError("camera_error", "Camera not created")); |
| 379 | + } |
| 380 | + if (camera->HasPendingResultByType(PendingResultType::kStartStream)) { |
| 381 | + return result( |
| 382 | + FlutterError("camera_error", "Pending start stream request exists")); |
| 383 | + } |
| 384 | + |
| 385 | + if (!event_sink) { |
| 386 | + return result(FlutterError("camera_error", |
| 387 | + "Unable to make event channel from windows")); |
| 388 | + } |
| 389 | + |
| 390 | + if (camera->AddPendingVoidResult(PendingResultType::kStartStream, |
| 391 | + std::move(result))) { |
| 392 | + CaptureController* cc = camera->GetCaptureController(); |
| 393 | + assert(cc); |
| 394 | + cc->StartImageStream(std::move(event_sink)); |
| 395 | + } |
| 396 | +} |
| 397 | + |
| 398 | +void CameraPlugin::StopImageStream( |
| 399 | + int64_t camera_id, |
| 400 | + std::function<void(std::optional<FlutterError> reply)> result) { |
| 401 | + // check if request already exists |
| 402 | + Camera* camera = GetCameraByCameraId(camera_id); |
| 403 | + if (!camera) { |
| 404 | + return result(FlutterError("camera_error", "Camera not created")); |
| 405 | + } |
| 406 | + if (camera->HasPendingResultByType(PendingResultType::kStopStream)) { |
| 407 | + return result( |
| 408 | + FlutterError("camera_error", "Pending stop stream request exists")); |
| 409 | + } |
| 410 | + |
| 411 | + if (camera->AddPendingVoidResult(PendingResultType::kStopStream, |
| 412 | + std::move(result))) { |
| 413 | + CaptureController* cc = camera->GetCaptureController(); |
| 414 | + assert(cc); |
| 415 | + cc->StopImageStream(); |
| 416 | + } |
| 417 | +} |
| 418 | + |
344 | 419 | void CameraPlugin::TakePicture(
|
345 | 420 | int64_t camera_id, std::function<void(ErrorOr<std::string> reply)> result) {
|
346 | 421 | auto camera = GetCameraByCameraId(camera_id);
|
|
0 commit comments