diff options
Diffstat (limited to 'src/Overlay.cpp')
-rw-r--r-- | src/Overlay.cpp | 259 |
1 files changed, 194 insertions, 65 deletions
diff --git a/src/Overlay.cpp b/src/Overlay.cpp index 4d8790b..a6f8a69 100644 --- a/src/Overlay.cpp +++ b/src/Overlay.cpp @@ -47,7 +47,7 @@ namespace gsr { static const double force_window_on_top_timeout_seconds = 1.0; static const double replay_status_update_check_timeout_seconds = 1.5; static const double replay_saving_notification_timeout_seconds = 0.5; - static const double notification_timeout_seconds = 2.0; + static const double notification_timeout_seconds = 2.5; static const double notification_error_timeout_seconds = 5.0; static const double cursor_tracker_update_timeout_sec = 0.1; @@ -326,6 +326,20 @@ namespace gsr { }); global_hotkeys->bind_key_press( + config_hotkey_to_hotkey(overlay->get_config().replay_config.save_1_min_hotkey), + "replay_save_1_min", [overlay](const std::string &id) { + fprintf(stderr, "pressed %s\n", id.c_str()); + overlay->save_replay_1_min(); + }); + + global_hotkeys->bind_key_press( + config_hotkey_to_hotkey(overlay->get_config().replay_config.save_10_min_hotkey), + "replay_save_10_min", [overlay](const std::string &id) { + fprintf(stderr, "pressed %s\n", id.c_str()); + overlay->save_replay_10_min(); + }); + + global_hotkeys->bind_key_press( config_hotkey_to_hotkey(overlay->get_config().screenshot_config.take_screenshot_hotkey), "take_screenshot", [overlay](const std::string &id) { fprintf(stderr, "pressed %s\n", id.c_str()); @@ -688,7 +702,7 @@ namespace gsr { remove_widgets_to_be_removed(); update_notification_process_status(); - update_gsr_replay_save(); + process_gsr_output(); update_gsr_process_status(); update_gsr_screenshot_process_status(); replay_status_update_status(); @@ -697,7 +711,7 @@ namespace gsr { start_region_capture = false; hide(); if(!region_selector.start(get_color_theme().tint_color)) { - show_notification("Failed to start region capture", notification_error_timeout_seconds, mgl::Color(255, 0, 0, 0), mgl::Color(255, 0, 0, 0), NotificationType::NONE); + show_notification("Failed to start region capture", notification_error_timeout_seconds, mgl::Color(255, 0, 0), mgl::Color(255, 0, 0), NotificationType::NONE); on_region_selected = nullptr; } } @@ -1051,9 +1065,15 @@ namespace gsr { replay_dropdown_button_ptr = button.get(); button->add_item("Turn on", "start", config.replay_config.start_stop_hotkey.to_string(false, false)); button->add_item("Save", "save", config.replay_config.save_hotkey.to_string(false, false)); + if(gsr_info.system_info.gsr_version >= GsrVersion{5, 4, 0}) { + button->add_item("Save 1 min", "save_1_min", config.replay_config.save_1_min_hotkey.to_string(false, false)); + button->add_item("Save 10 min", "save_10_min", config.replay_config.save_10_min_hotkey.to_string(false, false)); + } button->add_item("Settings", "settings"); button->set_item_icon("start", &get_theme().play_texture); button->set_item_icon("save", &get_theme().save_texture); + button->set_item_icon("save_1_min", &get_theme().save_texture); + button->set_item_icon("save_10_min", &get_theme().save_texture); button->set_item_icon("settings", &get_theme().settings_small_texture); button->on_click = [this](const std::string &id) { if(id == "settings") { @@ -1066,11 +1086,17 @@ namespace gsr { page_stack.push(std::move(replay_settings_page)); } else if(id == "save") { on_press_save_replay(); + } else if(id == "save_1_min") { + on_press_save_replay_1_min_replay(); + } else if(id == "save_10_min") { + on_press_save_replay_10_min_replay(); } else if(id == "start") { on_press_start_replay(false, false); } }; button->set_item_enabled("save", false); + button->set_item_enabled("save_1_min", false); + button->set_item_enabled("save_10_min", false); main_buttons_list->add_widget(std::move(button)); } { @@ -1370,6 +1396,14 @@ namespace gsr { on_press_save_replay(); } + void Overlay::save_replay_1_min() { + on_press_save_replay_1_min_replay(); + } + + void Overlay::save_replay_10_min() { + on_press_save_replay_10_min_replay(); + } + void Overlay::take_screenshot() { on_press_take_screenshot(false, false); } @@ -1596,12 +1630,12 @@ namespace gsr { if(!config.replay_config.show_replay_saved_notifications) return; - if(is_capture_target_monitor(replay_capture_target.c_str())) + if(is_capture_target_monitor(recording_capture_target.c_str())) snprintf(msg, sizeof(msg), "Saved a replay of this monitor to '%s'", filename.c_str()); else - snprintf(msg, sizeof(msg), "Saved a replay of %s to '%s'", replay_capture_target.c_str(), filename.c_str()); + snprintf(msg, sizeof(msg), "Saved a replay of %s to '%s'", recording_capture_target.c_str(), filename.c_str()); - capture_target = replay_capture_target.c_str(); + capture_target = recording_capture_target.c_str(); break; } case NotificationType::SCREENSHOT: { @@ -1623,6 +1657,16 @@ namespace gsr { show_notification(msg, notification_timeout_seconds, mgl::Color(255, 255, 255), get_color_theme().tint_color, notification_type, capture_target); } + static NotificationType recording_status_to_notification_type(RecordingStatus recording_status) { + switch(recording_status) { + case RecordingStatus::NONE: return NotificationType::NONE; + case RecordingStatus::REPLAY: return NotificationType::REPLAY; + case RecordingStatus::RECORD: return NotificationType::RECORD; + case RecordingStatus::STREAM: return NotificationType::STREAM; + } + return NotificationType::NONE; + } + void Overlay::on_replay_saved(const char *replay_saved_filepath) { replay_save_show_notification = false; if(config.replay_config.save_video_in_game_folder) { @@ -1630,15 +1674,15 @@ namespace gsr { } else { const std::string filename = filepath_get_filename(replay_saved_filepath); char msg[512]; - if(is_capture_target_monitor(replay_capture_target.c_str())) + if(is_capture_target_monitor(recording_capture_target.c_str())) snprintf(msg, sizeof(msg), "Saved a replay of this monitor to '%s'", filename.c_str()); else - snprintf(msg, sizeof(msg), "Saved a replay of %s to '%s'", replay_capture_target.c_str(), filename.c_str()); - show_notification(msg, notification_timeout_seconds, mgl::Color(255, 255, 255), get_color_theme().tint_color, NotificationType::REPLAY, replay_capture_target.c_str()); + snprintf(msg, sizeof(msg), "Saved a replay of %s to '%s'", recording_capture_target.c_str(), filename.c_str()); + show_notification(msg, notification_timeout_seconds, mgl::Color(255, 255, 255), get_color_theme().tint_color, NotificationType::REPLAY, recording_capture_target.c_str()); } } - void Overlay::update_gsr_replay_save() { + void Overlay::process_gsr_output() { if(replay_save_show_notification && replay_save_clock.get_elapsed_time_seconds() >= replay_saving_notification_timeout_seconds) { replay_save_show_notification = false; show_notification("Saving replay, this might take some time", notification_timeout_seconds, mgl::Color(255, 255, 255), get_color_theme().tint_color, NotificationType::REPLAY); @@ -1646,15 +1690,36 @@ namespace gsr { if(gpu_screen_recorder_process_output_file) { char buffer[1024]; - char *replay_saved_filepath = fgets(buffer, sizeof(buffer), gpu_screen_recorder_process_output_file); - if(!replay_saved_filepath || replay_saved_filepath[0] == '\0') + char *line = fgets(buffer, sizeof(buffer), gpu_screen_recorder_process_output_file); + if(!line || line[0] == '\0') return; - const int line_len = strlen(replay_saved_filepath); - if(replay_saved_filepath[line_len - 1] == '\n') - replay_saved_filepath[line_len - 1] = '\0'; + const int line_len = strlen(line); + if(line[line_len - 1] == '\n') + line[line_len - 1] = '\0'; + + if(starts_with({line, (size_t)line_len}, "Error: ")) { + show_notification(line + 7, notification_error_timeout_seconds, mgl::Color(255, 0, 0), mgl::Color(255, 0, 0), recording_status_to_notification_type(recording_status)); + return; + } - on_replay_saved(replay_saved_filepath); + const std::string video_filepath = filepath_get_filename(line); + if(starts_with(video_filepath, "Video_")) { + on_stop_recording(0, video_filepath); + return; + } + + switch(recording_status) { + case RecordingStatus::NONE: + break; + case RecordingStatus::REPLAY: + on_replay_saved(line); + break; + case RecordingStatus::RECORD: + break; + case RecordingStatus::STREAM: + break; + } } else if(gpu_screen_recorder_process_output_fd > 0) { char buffer[1024]; read(gpu_screen_recorder_process_output_fd, buffer, sizeof(buffer)); @@ -1693,7 +1758,7 @@ namespace gsr { } case RecordingStatus::RECORD: { update_ui_recording_stopped(); - on_stop_recording(exit_code); + on_stop_recording(exit_code, record_filepath); break; } case RecordingStatus::STREAM: { @@ -1829,12 +1894,12 @@ namespace gsr { on_press_start_replay(true, false); } - void Overlay::on_stop_recording(int exit_code) { + void Overlay::on_stop_recording(int exit_code, const std::string &video_filepath) { if(exit_code == 0) { if(config.record_config.save_video_in_game_folder) { - save_video_in_current_game_directory(record_filepath.c_str(), NotificationType::RECORD); + save_video_in_current_game_directory(video_filepath.c_str(), NotificationType::RECORD); } else { - const std::string filename = filepath_get_filename(record_filepath.c_str()); + const std::string filename = filepath_get_filename(video_filepath.c_str()); char msg[512]; if(is_capture_target_monitor(recording_capture_target.c_str())) snprintf(msg, sizeof(msg), "Saved a recording of this monitor to '%s'", filename.c_str()); @@ -1846,6 +1911,7 @@ namespace gsr { fprintf(stderr, "Warning: gpu-screen-recorder (%d) exited with exit status %d\n", (int)gpu_screen_recorder_process, exit_code); show_notification("Failed to start/save recording. Verify if settings are correct", notification_timeout_seconds, mgl::Color(255, 0, 0), mgl::Color(255, 0, 0), NotificationType::RECORD); } + update_ui_recording_stopped(); } void Overlay::update_ui_recording_paused() { @@ -1874,7 +1940,7 @@ namespace gsr { record_dropdown_button_ptr->set_activated(true); record_dropdown_button_ptr->set_description("Recording"); record_dropdown_button_ptr->set_item_icon("start", &get_theme().stop_texture); - record_dropdown_button_ptr->set_item_enabled("pause", true); + record_dropdown_button_ptr->set_item_enabled("pause", recording_status == RecordingStatus::RECORD); } void Overlay::update_ui_recording_stopped() { @@ -1910,6 +1976,7 @@ namespace gsr { stream_dropdown_button_ptr->set_activated(false); stream_dropdown_button_ptr->set_description("Not streaming"); stream_dropdown_button_ptr->set_item_icon("start", &get_theme().play_texture); + update_ui_recording_stopped(); } void Overlay::update_ui_replay_started() { @@ -1921,6 +1988,8 @@ namespace gsr { replay_dropdown_button_ptr->set_description("On"); replay_dropdown_button_ptr->set_item_icon("start", &get_theme().stop_texture); replay_dropdown_button_ptr->set_item_enabled("save", true); + replay_dropdown_button_ptr->set_item_enabled("save_1_min", true); + replay_dropdown_button_ptr->set_item_enabled("save_10_min", true); } void Overlay::update_ui_replay_stopped() { @@ -1932,6 +2001,9 @@ namespace gsr { replay_dropdown_button_ptr->set_description("Off"); replay_dropdown_button_ptr->set_item_icon("start", &get_theme().play_texture); replay_dropdown_button_ptr->set_item_enabled("save", false); + replay_dropdown_button_ptr->set_item_enabled("save_1_min", false); + replay_dropdown_button_ptr->set_item_enabled("save_10_min", false); + update_ui_recording_stopped(); } static std::string get_date_str() { @@ -2060,6 +2132,17 @@ namespace gsr { } } + void Overlay::prepare_gsr_output_for_reading() { + if(gpu_screen_recorder_process_output_fd <= 0) + return; + + const int fdl = fcntl(gpu_screen_recorder_process_output_fd, F_GETFL); + fcntl(gpu_screen_recorder_process_output_fd, F_SETFL, fdl | O_NONBLOCK); + gpu_screen_recorder_process_output_file = fdopen(gpu_screen_recorder_process_output_fd, "r"); + if(gpu_screen_recorder_process_output_file) + gpu_screen_recorder_process_output_fd = -1; + } + void Overlay::on_press_save_replay() { if(recording_status != RecordingStatus::REPLAY || gpu_screen_recorder_process <= 0) return; @@ -2069,6 +2152,24 @@ namespace gsr { kill(gpu_screen_recorder_process, SIGUSR1); } + void Overlay::on_press_save_replay_1_min_replay() { + if(recording_status != RecordingStatus::REPLAY || gpu_screen_recorder_process <= 0) + return; + + replay_save_show_notification = true; + replay_save_clock.restart(); + kill(gpu_screen_recorder_process, SIGRTMIN+3); + } + + void Overlay::on_press_save_replay_10_min_replay() { + if(recording_status != RecordingStatus::REPLAY || gpu_screen_recorder_process <= 0) + return; + + replay_save_show_notification = true; + replay_save_clock.restart(); + kill(gpu_screen_recorder_process, SIGRTMIN+5); + } + bool Overlay::on_press_start_replay(bool disable_notification, bool finished_region_selection) { if(region_selector.is_started()) return false; @@ -2078,10 +2179,10 @@ namespace gsr { case RecordingStatus::REPLAY: break; case RecordingStatus::RECORD: - show_notification("Unable to start replay when recording.\nStop recording before starting replay.", notification_error_timeout_seconds, mgl::Color(255, 255, 255), get_color_theme().tint_color, NotificationType::RECORD); + show_notification("Unable to start replay when recording.\nStop recording before starting replay.", notification_error_timeout_seconds, mgl::Color(255, 0, 0), mgl::Color(255, 0, 0), NotificationType::RECORD); return false; case RecordingStatus::STREAM: - show_notification("Unable to start replay when streaming.\nStop streaming before starting replay.", notification_error_timeout_seconds, mgl::Color(255, 255, 255), get_color_theme().tint_color, NotificationType::STREAM); + show_notification("Unable to start replay when streaming.\nStop streaming before starting replay.", notification_error_timeout_seconds, mgl::Color(255, 0, 0), mgl::Color(255, 0, 0), NotificationType::STREAM); return false; } @@ -2089,9 +2190,6 @@ namespace gsr { replay_save_show_notification = false; try_replay_startup = false; - // window->close(); - // usleep(1000 * 50); // 50 milliseconds - close_gpu_screen_recorder_output(); if(gpu_screen_recorder_process > 0) { @@ -2114,11 +2212,11 @@ namespace gsr { } const SupportedCaptureOptions capture_options = get_supported_capture_options(gsr_info); - replay_capture_target = get_capture_target(config.replay_config.record_options.record_area_option, capture_options); - if(!validate_capture_target(replay_capture_target, capture_options)) { + recording_capture_target = get_capture_target(config.replay_config.record_options.record_area_option, capture_options); + if(!validate_capture_target(recording_capture_target, capture_options)) { char err_msg[256]; - snprintf(err_msg, sizeof(err_msg), "Failed to start replay, capture target \"%s\" is invalid. Please change capture target in settings", replay_capture_target.c_str()); - show_notification(err_msg, notification_error_timeout_seconds, mgl::Color(255, 0, 0, 0), mgl::Color(255, 0, 0, 0), NotificationType::REPLAY); + snprintf(err_msg, sizeof(err_msg), "Failed to start replay, capture target \"%s\" is invalid. Please change capture target in settings", recording_capture_target.c_str()); + show_notification(err_msg, notification_error_timeout_seconds, mgl::Color(255, 0, 0), mgl::Color(255, 0, 0), NotificationType::REPLAY); return false; } @@ -2153,7 +2251,7 @@ namespace gsr { snprintf(size, sizeof(size), "%dx%d", (int)config.replay_config.record_options.video_width, (int)config.replay_config.record_options.video_height); std::vector<const char*> args = { - "gpu-screen-recorder", "-w", replay_capture_target.c_str(), + "gpu-screen-recorder", "-w", recording_capture_target.c_str(), "-c", config.replay_config.container.c_str(), "-ac", config.replay_config.record_options.audio_codec.c_str(), "-cursor", config.replay_config.record_options.record_cursor ? "yes" : "no", @@ -2175,21 +2273,23 @@ namespace gsr { char region_str[128]; add_common_gpu_screen_recorder_args(args, config.replay_config.record_options, audio_tracks, video_bitrate, size, region_str, sizeof(region_str), region_selector); + if(gsr_info.system_info.gsr_version >= GsrVersion{5, 4, 0}) { + args.push_back("-ro"); + args.push_back(config.record_config.save_directory.c_str()); + } + args.push_back(nullptr); gpu_screen_recorder_process = exec_program(args.data(), &gpu_screen_recorder_process_output_fd); if(gpu_screen_recorder_process == -1) { - // TODO: Show notification failed to start + show_notification("Failed to launch gpu-screen-recorder to start replay", notification_error_timeout_seconds, mgl::Color(255, 0, 0), mgl::Color(255, 0, 0), NotificationType::REPLAY); + return false; } else { recording_status = RecordingStatus::REPLAY; update_ui_replay_started(); } - const int fdl = fcntl(gpu_screen_recorder_process_output_fd, F_GETFL); - fcntl(gpu_screen_recorder_process_output_fd, F_SETFL, fdl | O_NONBLOCK); - gpu_screen_recorder_process_output_file = fdopen(gpu_screen_recorder_process_output_fd, "r"); - if(gpu_screen_recorder_process_output_file) - gpu_screen_recorder_process_output_fd = -1; + prepare_gsr_output_for_reading(); // TODO: Start recording after this notification has disappeared to make sure it doesn't show up in the video. // Make clear to the user that the recording starts after the notification is gone. @@ -2202,11 +2302,11 @@ namespace gsr { // to see when the program has exit. if(!disable_notification && config.replay_config.show_replay_started_notifications) { char msg[256]; - if(is_capture_target_monitor(replay_capture_target.c_str())) + if(is_capture_target_monitor(recording_capture_target.c_str())) snprintf(msg, sizeof(msg), "Started replaying this monitor"); else - snprintf(msg, sizeof(msg), "Started replaying %s", replay_capture_target.c_str()); - show_notification(msg, notification_timeout_seconds, get_color_theme().tint_color, get_color_theme().tint_color, NotificationType::REPLAY, replay_capture_target.c_str()); + snprintf(msg, sizeof(msg), "Started replaying %s", recording_capture_target.c_str()); + show_notification(msg, notification_timeout_seconds, get_color_theme().tint_color, get_color_theme().tint_color, NotificationType::REPLAY, recording_capture_target.c_str()); } return true; @@ -2220,18 +2320,37 @@ namespace gsr { case RecordingStatus::NONE: case RecordingStatus::RECORD: break; - case RecordingStatus::REPLAY: - show_notification("Unable to start recording when replay is turned on.\nTurn off replay before starting recording.", notification_error_timeout_seconds, mgl::Color(255, 255, 255), get_color_theme().tint_color, NotificationType::REPLAY); + case RecordingStatus::REPLAY: { + if(gsr_info.system_info.gsr_version >= GsrVersion{5, 4, 0}) { + if(gpu_screen_recorder_process > 0) { + if(config.record_config.show_recording_started_notifications) + show_notification("Started recording in the replay session", notification_timeout_seconds, get_color_theme().tint_color, get_color_theme().tint_color, NotificationType::RECORD); + update_ui_recording_started(); + kill(gpu_screen_recorder_process, SIGRTMIN); + } + } else { + show_notification("Unable to start recording when replay is turned on.\nTurn off replay before starting recording.", notification_error_timeout_seconds, mgl::Color(255, 0, 0), get_color_theme().tint_color, NotificationType::REPLAY); + } return; - case RecordingStatus::STREAM: - show_notification("Unable to start recording when streaming.\nStop streaming before starting recording.", notification_error_timeout_seconds, mgl::Color(255, 255, 255), get_color_theme().tint_color, NotificationType::STREAM); + } + case RecordingStatus::STREAM: { + if(gsr_info.system_info.gsr_version >= GsrVersion{5, 4, 0}) { + if(gpu_screen_recorder_process > 0) { + if(config.record_config.show_recording_started_notifications) + show_notification("Started recording in the streaming session", notification_timeout_seconds, get_color_theme().tint_color, get_color_theme().tint_color, NotificationType::RECORD); + update_ui_recording_started(); + kill(gpu_screen_recorder_process, SIGRTMIN); + } + } else { + show_notification("Unable to start recording when streaming.\nStop streaming before starting recording.", notification_error_timeout_seconds, mgl::Color(255, 0, 0), get_color_theme().tint_color, NotificationType::STREAM); + } return; + } } paused = false; - // window->close(); - // usleep(1000 * 50); // 50 milliseconds + close_gpu_screen_recorder_output(); if(gpu_screen_recorder_process > 0) { kill(gpu_screen_recorder_process, SIGINT); @@ -2243,7 +2362,7 @@ namespace gsr { int exit_code = -1; if(WIFEXITED(status)) exit_code = WEXITSTATUS(status); - on_stop_recording(exit_code); + on_stop_recording(exit_code, record_filepath); } gpu_screen_recorder_process = -1; @@ -2258,7 +2377,7 @@ namespace gsr { if(!validate_capture_target(config.record_config.record_options.record_area_option, capture_options)) { char err_msg[256]; snprintf(err_msg, sizeof(err_msg), "Failed to start recording, capture target \"%s\" is invalid. Please change capture target in settings", recording_capture_target.c_str()); - show_notification(err_msg, notification_error_timeout_seconds, mgl::Color(255, 0, 0, 0), mgl::Color(255, 0, 0, 0), NotificationType::RECORD); + show_notification(err_msg, notification_error_timeout_seconds, mgl::Color(255, 0, 0), mgl::Color(255, 0, 0), NotificationType::RECORD); return; } @@ -2313,14 +2432,17 @@ namespace gsr { args.push_back(nullptr); record_filepath = output_file; - gpu_screen_recorder_process = exec_program(args.data(), nullptr); + gpu_screen_recorder_process = exec_program(args.data(), &gpu_screen_recorder_process_output_fd); if(gpu_screen_recorder_process == -1) { - // TODO: Show notification failed to start + show_notification("Failed to launch gpu-screen-recorder to start recording", notification_error_timeout_seconds, mgl::Color(255, 0, 0), mgl::Color(255, 0, 0), NotificationType::RECORD); + return; } else { recording_status = RecordingStatus::RECORD; update_ui_recording_started(); } + prepare_gsr_output_for_reading(); + // TODO: Start recording after this notification has disappeared to make sure it doesn't show up in the video. // Make clear to the user that the recording starts after the notification is gone. // Maybe have the option in notification to show timer until its getting hidden, then the notification can say: @@ -2378,17 +2500,16 @@ namespace gsr { case RecordingStatus::STREAM: break; case RecordingStatus::REPLAY: - show_notification("Unable to start streaming when replay is turned on.\nTurn off replay before starting streaming.", notification_error_timeout_seconds, mgl::Color(255, 255, 255), get_color_theme().tint_color, NotificationType::REPLAY); + show_notification("Unable to start streaming when replay is turned on.\nTurn off replay before starting streaming.", notification_error_timeout_seconds, mgl::Color(255, 0, 0), mgl::Color(255, 0, 0), NotificationType::REPLAY); return; case RecordingStatus::RECORD: - show_notification("Unable to start streaming when recording.\nStop recording before starting streaming.", notification_error_timeout_seconds, mgl::Color(255, 255, 255), get_color_theme().tint_color, NotificationType::RECORD); + show_notification("Unable to start streaming when recording.\nStop recording before starting streaming.", notification_error_timeout_seconds, mgl::Color(255, 0, 0), mgl::Color(255, 0, 0), NotificationType::RECORD); return; } paused = false; - // window->close(); - // usleep(1000 * 50); // 50 milliseconds + close_gpu_screen_recorder_output(); if(gpu_screen_recorder_process > 0) { kill(gpu_screen_recorder_process, SIGINT); @@ -2409,11 +2530,11 @@ namespace gsr { } const SupportedCaptureOptions capture_options = get_supported_capture_options(gsr_info); - const std::string capture_target = get_capture_target(config.streaming_config.record_options.record_area_option, capture_options); + recording_capture_target = get_capture_target(config.streaming_config.record_options.record_area_option, capture_options); if(!validate_capture_target(config.streaming_config.record_options.record_area_option, capture_options)) { char err_msg[256]; - snprintf(err_msg, sizeof(err_msg), "Failed to start streaming, capture target \"%s\" is invalid. Please change capture target in settings", capture_target.c_str()); - show_notification(err_msg, notification_error_timeout_seconds, mgl::Color(255, 0, 0, 0), mgl::Color(255, 0, 0, 0), NotificationType::STREAM); + snprintf(err_msg, sizeof(err_msg), "Failed to start streaming, capture target \"%s\" is invalid. Please change capture target in settings", recording_capture_target.c_str()); + show_notification(err_msg, notification_error_timeout_seconds, mgl::Color(255, 0, 0), mgl::Color(255, 0, 0), NotificationType::STREAM); return; } @@ -2456,7 +2577,7 @@ namespace gsr { snprintf(size, sizeof(size), "%dx%d", (int)config.streaming_config.record_options.video_width, (int)config.streaming_config.record_options.video_height); std::vector<const char*> args = { - "gpu-screen-recorder", "-w", capture_target.c_str(), + "gpu-screen-recorder", "-w", recording_capture_target.c_str(), "-c", container.c_str(), "-ac", config.streaming_config.record_options.audio_codec.c_str(), "-cursor", config.streaming_config.record_options.record_cursor ? "yes" : "no", @@ -2471,16 +2592,24 @@ namespace gsr { char region_str[128]; add_common_gpu_screen_recorder_args(args, config.streaming_config.record_options, audio_tracks, video_bitrate, size, region_str, sizeof(region_str), region_selector); + if(gsr_info.system_info.gsr_version >= GsrVersion{5, 4, 0}) { + args.push_back("-ro"); + args.push_back(config.record_config.save_directory.c_str()); + } + args.push_back(nullptr); - gpu_screen_recorder_process = exec_program(args.data(), nullptr); + gpu_screen_recorder_process = exec_program(args.data(), &gpu_screen_recorder_process_output_fd); if(gpu_screen_recorder_process == -1) { - // TODO: Show notification failed to start + show_notification("Failed to launch gpu-screen-recorder to start streaming", notification_error_timeout_seconds, mgl::Color(255, 0, 0), mgl::Color(255, 0, 0), NotificationType::STREAM); + return; } else { recording_status = RecordingStatus::STREAM; update_ui_streaming_started(); } + prepare_gsr_output_for_reading(); + // TODO: Start recording after this notification has disappeared to make sure it doesn't show up in the video. // Make clear to the user that the recording starts after the notification is gone. // Maybe have the option in notification to show timer until its getting hidden, then the notification can say: @@ -2492,11 +2621,11 @@ namespace gsr { // to see when the program has exit. if(config.streaming_config.show_streaming_started_notifications) { char msg[256]; - if(is_capture_target_monitor(capture_target.c_str())) + if(is_capture_target_monitor(recording_capture_target.c_str())) snprintf(msg, sizeof(msg), "Started streaming this monitor"); else - snprintf(msg, sizeof(msg), "Started streaming %s", capture_target.c_str()); - show_notification(msg, notification_timeout_seconds, get_color_theme().tint_color, get_color_theme().tint_color, NotificationType::STREAM, capture_target.c_str()); + snprintf(msg, sizeof(msg), "Started streaming %s", recording_capture_target.c_str()); + show_notification(msg, notification_timeout_seconds, get_color_theme().tint_color, get_color_theme().tint_color, NotificationType::STREAM, recording_capture_target.c_str()); } } @@ -2516,7 +2645,7 @@ namespace gsr { if(!validate_capture_target(record_area_option, capture_options)) { char err_msg[256]; snprintf(err_msg, sizeof(err_msg), "Failed to take a screenshot, capture target \"%s\" is invalid. Please change capture target in settings", screenshot_capture_target.c_str()); - show_notification(err_msg, notification_error_timeout_seconds, mgl::Color(255, 0, 0, 0), mgl::Color(255, 0, 0, 0), NotificationType::SCREENSHOT); + show_notification(err_msg, notification_error_timeout_seconds, mgl::Color(255, 0, 0), mgl::Color(255, 0, 0), NotificationType::SCREENSHOT); return; } @@ -2562,7 +2691,7 @@ namespace gsr { screenshot_filepath = output_file; gpu_screen_recorder_screenshot_process = exec_program(args.data(), nullptr); if(gpu_screen_recorder_screenshot_process == -1) { - // TODO: Show notification failed to start + show_notification("Failed to launch gpu-screen-recorder to take a screenshot", notification_error_timeout_seconds, mgl::Color(255, 0, 0), mgl::Color(255, 0, 0), NotificationType::SCREENSHOT); } } |