Add permission methods to CameraServer

This commit is contained in:
Jason Kuo 2024-09-27 02:52:19 +08:00
parent 506d6e427a
commit fc5de1949f
5 changed files with 61 additions and 0 deletions

View File

@ -37,6 +37,12 @@
Returns the number of [CameraFeed]s registered.
</description>
</method>
<method name="permission_granted">
<return type="bool" />
<description>
Returns [code]true[/code] if camera permission is granted. Always returns [code]true[/code] if no permission is required to access cameras.
</description>
</method>
<method name="remove_feed">
<return type="void" />
<param index="0" name="feed" type="CameraFeed" />
@ -44,6 +50,12 @@
Removes the specified camera [param feed].
</description>
</method>
<method name="request_permission">
<return type="void" />
<description>
Requests camera permission. No-op if permission is already granted or no permission is required to access cameras.
</description>
</method>
</methods>
<signals>
<signal name="camera_feed_added">
@ -58,6 +70,12 @@
Emitted when a [CameraFeed] is removed (e.g. a webcam is unplugged).
</description>
</signal>
<signal name="request_permission_result">
<param index="0" name="granted" type="bool" />
<description>
Emitted when a user responds to a camera permission request.
</description>
</signal>
</signals>
<constants>
<constant name="FEED_RGBA_IMAGE" value="0" enum="FeedImage">

View File

@ -41,6 +41,9 @@ public:
CameraMacOS();
void update_feeds();
bool permission_granted() override;
void request_permission() override;
};
#endif // CAMERA_MACOS_H

View File

@ -196,6 +196,7 @@
class CameraFeedMacOS : public CameraFeed {
private:
CameraMacOS *camera_server;
AVCaptureDevice *device;
MyCaptureSession *capture_session;
@ -204,6 +205,8 @@ public:
CameraFeedMacOS();
void set_camera_server(CameraMacOS *p_camera_server);
void set_device(AVCaptureDevice *p_device);
bool activate_feed();
@ -215,10 +218,15 @@ AVCaptureDevice *CameraFeedMacOS::get_device() const {
};
CameraFeedMacOS::CameraFeedMacOS() {
camera_server = nullptr;
device = nullptr;
capture_session = nullptr;
};
void CameraFeedMacOS::set_camera_server(CameraMacOS *p_camera_server) {
camera_server = p_camera_server;
};
void CameraFeedMacOS::set_device(AVCaptureDevice *p_device) {
device = p_device;
@ -246,6 +254,9 @@ bool CameraFeedMacOS::activate_feed() {
// Request permission.
[AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo
completionHandler:^(BOOL granted) {
if (camera_server) {
camera_server->emit_signal(SNAME("request_permission_result"), granted);
}
if (granted) {
capture_session = [[MyCaptureSession alloc] initForFeed:this andDevice:device];
}
@ -342,6 +353,7 @@ void CameraMacOS::update_feeds() {
if (!found) {
Ref<CameraFeedMacOS> newfeed;
newfeed.instantiate();
newfeed->set_camera_server(this);
newfeed->set_device(device);
// assume display camera so inverse
@ -353,6 +365,26 @@ void CameraMacOS::update_feeds() {
};
};
bool CameraMacOS::permission_granted() {
if (@available(macOS 10.14, *)) {
AVAuthorizationStatus status = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
return status == AVAuthorizationStatusAuthorized;
}
return true;
};
void CameraMacOS::request_permission() {
if (@available(macOS 10.14, *)) {
if (permission_granted()) {
return;
}
[AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo
completionHandler:^(BOOL granted) {
emit_signal(SNAME("request_permission_result"), granted);
}];
}
};
CameraMacOS::CameraMacOS() {
// Find available cameras we have at this time
update_feeds();

View File

@ -39,6 +39,9 @@
CameraServer::CreateFunc CameraServer::create_func = nullptr;
void CameraServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("permission_granted"), &CameraServer::permission_granted);
ClassDB::bind_method(D_METHOD("request_permission"), &CameraServer::request_permission);
ClassDB::bind_method(D_METHOD("get_feed", "index"), &CameraServer::get_feed);
ClassDB::bind_method(D_METHOD("get_feed_count"), &CameraServer::get_feed_count);
ClassDB::bind_method(D_METHOD("feeds"), &CameraServer::get_feeds);
@ -48,6 +51,7 @@ void CameraServer::_bind_methods() {
ADD_SIGNAL(MethodInfo("camera_feed_added", PropertyInfo(Variant::INT, "id")));
ADD_SIGNAL(MethodInfo("camera_feed_removed", PropertyInfo(Variant::INT, "id")));
ADD_SIGNAL(MethodInfo("request_permission_result", PropertyInfo(Variant::BOOL, "granted")));
BIND_ENUM_CONSTANT(FEED_RGBA_IMAGE);
BIND_ENUM_CONSTANT(FEED_YCBCR_IMAGE);

View File

@ -89,6 +89,10 @@ public:
return server;
};
// Camera permission.
virtual bool permission_granted() { return true; }
virtual void request_permission() {}
// Right now we identify our feed by it's ID when it's used in the background.
// May see if we can change this to purely relying on CameraFeed objects or by name.
int get_free_id();