Browse Source

mac-capture: Add button to reactivate stopped capture

gxalpha 2 years ago
parent
commit
e8602897d7

+ 1 - 0
plugins/mac-capture/data/locale/en-US.ini

@@ -30,3 +30,4 @@ SCK.Audio.Name="macOS Audio Capture"
 SCK.AudioUnavailable="Audio capture requires macOS 13 or newer."
 SCK.CaptureTypeUnavailable="Selected capture type requires macOS 13 or newer."
 SCK.Method="Method"
+SCK.Restart="Restart capture"

+ 23 - 1
plugins/mac-capture/mac-sck-audio-capture.m

@@ -7,7 +7,7 @@ const char *sck_audio_capture_getname(void *unused __unused)
 
 static void destroy_audio_screen_stream(struct screen_capture *sc)
 {
-    if (sc->disp) {
+    if (sc->disp && !sc->capture_failed) {
         [sc->disp stopCaptureWithCompletionHandler:^(NSError *_Nullable error) {
             if (error && error.code != 3808) {
                 MACCAP_ERR("destroy_audio_screen_stream: Failed to stop stream with error %s\n",
@@ -60,6 +60,10 @@ static void sck_audio_capture_destroy(void *data)
 static bool init_audio_screen_stream(struct screen_capture *sc)
 {
     SCContentFilter *content_filter;
+    if (sc->capture_failed) {
+        sc->capture_failed = false;
+        obs_source_update_properties(sc->source);
+    }
 
     sc->stream_properties = [[SCStreamConfiguration alloc] init];
     os_sem_wait(sc->shareable_content_available);
@@ -256,6 +260,21 @@ static bool audio_capture_method_changed(void *data, obs_properties_t *props, ob
     return true;
 }
 
+static bool reactivate_capture(obs_properties_t *props __unused, obs_property_t *property, void *data)
+{
+    struct screen_capture *sc = data;
+    if (!sc->capture_failed) {
+        MACCAP_LOG(LOG_WARNING, "Tried to reactivate capture that hadn't failed.");
+        return false;
+    }
+
+    destroy_audio_screen_stream(sc);
+    sc->capture_failed = false;
+    init_audio_screen_stream(sc);
+    obs_property_set_enabled(property, false);
+    return true;
+}
+
 static obs_properties_t *sck_audio_capture_properties(void *data)
 {
     struct screen_capture *sc = data;
@@ -272,6 +291,9 @@ static obs_properties_t *sck_audio_capture_properties(void *data)
 
     obs_property_t *app_list = obs_properties_add_list(props, "application", obs_module_text("Application"),
                                                        OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_STRING);
+    obs_property_t *reactivate =
+        obs_properties_add_button2(props, "reactivate_capture", obs_module_text("SCK.Restart"), reactivate_capture, sc);
+    obs_property_set_enabled(reactivate, sc->capture_failed);
 
     if (sc) {
         switch (sc->audio_capture_type) {

+ 1 - 0
plugins/mac-capture/mac-sck-common.h

@@ -57,6 +57,7 @@ struct screen_capture {
     os_event_t *stream_start_completed;
     os_sem_t *shareable_content_available;
     IOSurfaceRef current, prev;
+    bool capture_failed;
 
     pthread_mutex_t mutex;
 

+ 3 - 0
plugins/mac-capture/mac-sck-common.m

@@ -48,6 +48,9 @@ bool is_screen_capture_available(void)
     }
 
     MACCAP_LOG(LOG_WARNING, "%s", errorMessage.UTF8String);
+
+    self.sc->capture_failed = true;
+    obs_source_update_properties(self.sc->source);
 }
 
 @end

+ 25 - 1
plugins/mac-capture/mac-sck-video-capture.m

@@ -2,7 +2,7 @@
 
 static void destroy_screen_stream(struct screen_capture *sc)
 {
-    if (sc->disp) {
+    if (sc->disp && !sc->capture_failed) {
         [sc->disp stopCaptureWithCompletionHandler:^(NSError *_Nullable error) {
             if (error && error.code != 3808) {
                 MACCAP_ERR("destroy_screen_stream: Failed to stop stream with error %s\n",
@@ -76,6 +76,10 @@ static void sck_video_capture_destroy(void *data)
 static bool init_screen_stream(struct screen_capture *sc)
 {
     SCContentFilter *content_filter;
+    if (sc->capture_failed) {
+        sc->capture_failed = false;
+        obs_source_update_properties(sc->source);
+    }
 
     sc->frame = CGRectZero;
     sc->stream_properties = [[SCStreamConfiguration alloc] init];
@@ -542,6 +546,23 @@ static bool content_settings_changed(void *data, obs_properties_t *props, obs_pr
     return true;
 }
 
+static bool reactivate_capture(obs_properties_t *props __unused, obs_property_t *property, void *data)
+{
+    struct screen_capture *sc = data;
+    if (!sc->capture_failed) {
+        MACCAP_LOG(LOG_WARNING, "Tried to reactivate capture that hadn't failed.");
+        return false;
+    }
+
+    obs_enter_graphics();
+    destroy_screen_stream(sc);
+    sc->capture_failed = false;
+    init_screen_stream(sc);
+    obs_leave_graphics();
+    obs_property_set_enabled(property, false);
+    return true;
+}
+
 static obs_properties_t *sck_video_capture_properties(void *data)
 {
     struct screen_capture *sc = data;
@@ -573,6 +594,9 @@ static obs_properties_t *sck_video_capture_properties(void *data)
     obs_properties_add_bool(props, "show_cursor", obs_module_text("DisplayCapture.ShowCursor"));
 
     obs_property_t *hide_obs = obs_properties_add_bool(props, "hide_obs", obs_module_text("DisplayCapture.HideOBS"));
+    obs_property_t *reactivate =
+        obs_properties_add_button2(props, "reactivate_capture", obs_module_text("SCK.Restart"), reactivate_capture, sc);
+    obs_property_set_enabled(reactivate, sc->capture_failed);
 
     if (sc) {
         obs_property_set_modified_callback2(capture_type, content_settings_changed, sc);