mirror of
https://repo.dec05eba.com/gpu-screen-recorder-ui
synced 2026-03-31 09:17:04 +09:00
Add application audio option
This commit is contained in:
@@ -34,3 +34,8 @@ This software is licensed under GPL3.0-only. Files under `fonts/` directory are
|
||||
# Screenshots
|
||||

|
||||

|
||||
|
||||
# Donations
|
||||
If you want to donate you can donate via bitcoin or monero.
|
||||
* Bitcoin: bc1qqvuqnwrdyppf707ge27fqz2n9y9gu7lf5ypyuf
|
||||
* Monero: 4An9kp2qW1C9Gah7ewv4JzcNFQ5TAX7ineGCqXWK6vQnhsGGcRpNgcn8r9EC3tMcgY7vqCKs3nSRXhejMHBaGvFdN2egYet
|
||||
27
TODO
27
TODO
@@ -52,3 +52,30 @@ Add profiles and hotkey to switch between profiles (show notification when switc
|
||||
Fix first frame being black.
|
||||
|
||||
Add support for systray.
|
||||
|
||||
Add option to take screenshot.
|
||||
|
||||
Move event callbacks to a global list instead of std::function object in each widget. This reduces the size of widgets,
|
||||
since most widgets wont have the event callback set.
|
||||
This event callback would pass the widget as an argument.
|
||||
This could be done transparently by having a function in the widget to set a callback function
|
||||
and that could add a wrapper that checks if the callback received _this_, and that would call the callback set by the user.
|
||||
|
||||
Make save-video-in-game-folder.sh and notify-saved-name.sh run ~/.config/gpu-screen-recorder/on-save.sh if it exists.
|
||||
This could for example be used to automatically convert the video to a different format or to upload it to a server.
|
||||
Before this script is called gsr-ui should define an environment variable GSR_PROFILE that specifies the name of the profile.
|
||||
This profile name can be used to decide which action the users script should do, for example to convert the video to a 4chan friendly webm file
|
||||
if the profile is called 4chan.
|
||||
Create a directory of such example scripts, including 4chan webm one.
|
||||
|
||||
On nvidia check if suspend fix is applied. If not, show a popup asking the user to apply it (and apply it automatically).
|
||||
|
||||
Show warning when using steam deck or when trying to capture hevc/av1 on amd (the same warnings as gpu screen recorder gtk).
|
||||
|
||||
Add option to capture application audio. This should show a popup where you can use one of the available applications or a custom one and choose to record that application or all applications except that one.
|
||||
|
||||
Add profile option. Convert view to profile, add an option at the bottom that says "Edit profiles..." which should show a popup where you can create/remove profiles. New profiles should always be in advanced view.
|
||||
|
||||
Verify monitor/audio when starting recording. Give an error if the options are no longer valid.
|
||||
|
||||
Add option to record focused monitor. This is less error prone when plugging in monitors, etc.
|
||||
Submodule depends/mglpp updated: 23b75905a5...84a6eb51b0
@@ -23,8 +23,11 @@ namespace gsr {
|
||||
int32_t fps = 60;
|
||||
int32_t video_bitrate = 15000;
|
||||
bool merge_audio_tracks = true;
|
||||
bool application_audio_invert = false;
|
||||
bool change_video_resolution = false;
|
||||
std::string audio_type_view = "audio_devices";
|
||||
std::vector<std::string> audio_tracks;
|
||||
std::vector<std::string> application_audio;
|
||||
std::string color_range = "limited";
|
||||
std::string video_quality = "very_high";
|
||||
std::string video_codec = "auto";
|
||||
|
||||
@@ -76,4 +76,5 @@ namespace gsr {
|
||||
GsrInfoExitStatus get_gpu_screen_recorder_info(GsrInfo *gsr_info);
|
||||
|
||||
std::vector<AudioDevice> get_audio_devices();
|
||||
std::vector<std::string> get_application_audio();
|
||||
}
|
||||
@@ -90,14 +90,13 @@ namespace gsr {
|
||||
std::string resources_path;
|
||||
GsrInfo gsr_info;
|
||||
egl_functions egl_funcs;
|
||||
std::vector<gsr::AudioDevice> audio_devices;
|
||||
mgl::Texture window_texture_texture;
|
||||
mgl::Sprite window_texture_sprite;
|
||||
mgl::Texture screenshot_texture;
|
||||
mgl::Sprite screenshot_sprite;
|
||||
mgl::Rectangle bg_screenshot_overlay;
|
||||
WindowTexture window_texture;
|
||||
gsr::PageStack page_stack;
|
||||
PageStack page_stack;
|
||||
mgl::Rectangle top_bar_background;
|
||||
mgl::Text top_bar_text;
|
||||
mgl::Sprite logo_sprite;
|
||||
|
||||
@@ -19,6 +19,7 @@ namespace gsr {
|
||||
mgl::vec2f get_size() override;
|
||||
|
||||
void set_text(std::string str);
|
||||
const std::string& get_text() const;
|
||||
private:
|
||||
mgl::Text text;
|
||||
};
|
||||
|
||||
24
include/gui/LineSeparator.hpp
Normal file
24
include/gui/LineSeparator.hpp
Normal file
@@ -0,0 +1,24 @@
|
||||
#pragma once
|
||||
|
||||
#include "Widget.hpp"
|
||||
|
||||
namespace gsr {
|
||||
class LineSeparator : public Widget {
|
||||
public:
|
||||
enum class Type {
|
||||
HORIZONTAL
|
||||
};
|
||||
|
||||
LineSeparator(Type type, float width);
|
||||
LineSeparator(const LineSeparator&) = delete;
|
||||
LineSeparator& operator=(const LineSeparator&) = delete;
|
||||
|
||||
bool on_event(mgl::Event &event, mgl::Window &window, mgl::vec2f offset) override;
|
||||
void draw(mgl::Window &window, mgl::vec2f offset) override;
|
||||
|
||||
mgl::vec2f get_size() override;
|
||||
private:
|
||||
Type type;
|
||||
float width;
|
||||
};
|
||||
}
|
||||
@@ -24,7 +24,7 @@ namespace gsr {
|
||||
STREAM
|
||||
};
|
||||
|
||||
SettingsPage(Type type, const GsrInfo &gsr_info, std::vector<AudioDevice> audio_devices, Config &config, PageStack *page_stack);
|
||||
SettingsPage(Type type, const GsrInfo &gsr_info, Config &config, PageStack *page_stack);
|
||||
SettingsPage(const SettingsPage&) = delete;
|
||||
SettingsPage& operator=(const SettingsPage&) = delete;
|
||||
|
||||
@@ -48,13 +48,23 @@ namespace gsr {
|
||||
std::unique_ptr<List> create_restore_portal_session_section();
|
||||
std::unique_ptr<Widget> create_change_video_resolution_section();
|
||||
std::unique_ptr<Widget> create_capture_target(const GsrInfo &gsr_info);
|
||||
std::unique_ptr<ComboBox> create_audio_track_selection_checkbox();
|
||||
std::unique_ptr<Button> create_remove_audio_track_button(List *audio_device_list_ptr);
|
||||
std::unique_ptr<List> create_audio_track();
|
||||
std::unique_ptr<Button> create_add_audio_track_button();
|
||||
std::unique_ptr<List> create_audio_track_section();
|
||||
std::unique_ptr<ComboBox> create_audio_device_selection_combobox();
|
||||
std::unique_ptr<Button> create_remove_audio_device_button(List *audio_device_list_ptr);
|
||||
std::unique_ptr<List> create_audio_device();
|
||||
std::unique_ptr<Button> create_add_audio_device_button();
|
||||
std::unique_ptr<List> create_audio_device_track_section();
|
||||
std::unique_ptr<CheckBox> create_merge_audio_tracks_checkbox();
|
||||
std::unique_ptr<RadioButton> create_audio_type_button();
|
||||
std::unique_ptr<Widget> create_audio_device_section();
|
||||
std::unique_ptr<List> create_application_audio_track_section();
|
||||
std::unique_ptr<CheckBox> create_application_audio_invert_checkbox();
|
||||
std::unique_ptr<List> create_application_audio_section();
|
||||
std::unique_ptr<ComboBox> create_application_audio_selection_combobox();
|
||||
std::unique_ptr<Button> create_remove_application_audio_button(List *app_audio_item);
|
||||
std::unique_ptr<List> create_application_audio();
|
||||
std::unique_ptr<List> create_custom_application_audio();
|
||||
std::unique_ptr<List> create_add_application_audio_buttons();
|
||||
std::unique_ptr<Widget> create_audio_section();
|
||||
std::unique_ptr<List> create_video_quality_box();
|
||||
std::unique_ptr<Entry> create_video_bitrate_entry();
|
||||
std::unique_ptr<List> create_video_bitrate();
|
||||
@@ -98,7 +108,8 @@ namespace gsr {
|
||||
std::unique_ptr<List> create_stream_container_section();
|
||||
void add_stream_widgets();
|
||||
|
||||
void load_audio_tracks(RecordOptions &record_options);
|
||||
void load_audio_device_tracks(RecordOptions &record_options);
|
||||
void load_application_audio_tracks(RecordOptions &record_options);
|
||||
void load_common(RecordOptions &record_options);
|
||||
void load_replay();
|
||||
void load_record();
|
||||
@@ -112,6 +123,7 @@ namespace gsr {
|
||||
Type type;
|
||||
Config &config;
|
||||
std::vector<AudioDevice> audio_devices;
|
||||
std::vector<std::string> application_audio;
|
||||
|
||||
GsrPage *content_page_ptr = nullptr;
|
||||
ScrollablePage *settings_scrollable_page_ptr = nullptr;
|
||||
@@ -133,7 +145,12 @@ namespace gsr {
|
||||
Entry *video_bitrate_entry_ptr = nullptr;
|
||||
List *video_bitrate_list_ptr = nullptr;
|
||||
List *audio_devices_list_ptr = nullptr;
|
||||
List *audio_devices_section_list_ptr = nullptr;
|
||||
List *application_audio_section_list_ptr = nullptr;
|
||||
CheckBox *merge_audio_tracks_checkbox_ptr = nullptr;
|
||||
RadioButton *audio_type_radio_button_ptr = nullptr;
|
||||
List *application_audio_list_ptr = nullptr;
|
||||
CheckBox *application_audio_invert_checkbox_ptr = nullptr;
|
||||
CheckBox *change_video_resolution_checkbox_ptr = nullptr;
|
||||
ComboBox *color_range_box_ptr = nullptr;
|
||||
ComboBox *video_quality_box_ptr = nullptr;
|
||||
|
||||
@@ -16,6 +16,7 @@ namespace gsr {
|
||||
void draw(mgl::Window &window, mgl::vec2f offset) override;
|
||||
|
||||
mgl::vec2f get_size() override;
|
||||
mgl::vec2f get_inner_size() override;
|
||||
private:
|
||||
Label label;
|
||||
std::unique_ptr<Widget> inner_widget;
|
||||
|
||||
@@ -23,6 +23,7 @@ src = [
|
||||
'src/gui/Utils.cpp',
|
||||
'src/gui/DropdownButton.cpp',
|
||||
'src/gui/Label.cpp',
|
||||
'src/gui/LineSeparator.cpp',
|
||||
'src/gui/CustomRendererWidget.cpp',
|
||||
'src/gui/FileChooser.cpp',
|
||||
'src/gui/SettingsPage.cpp',
|
||||
|
||||
@@ -6,7 +6,6 @@ filepath="$1"
|
||||
type="$2"
|
||||
|
||||
file_name="$(basename "$filepath")"
|
||||
file_dir="$(dirname "$filepath")"
|
||||
|
||||
case "$type" in
|
||||
"regular")
|
||||
|
||||
@@ -57,8 +57,11 @@ namespace gsr {
|
||||
{"streaming.record_options.fps", &config.streaming_config.record_options.fps},
|
||||
{"streaming.record_options.video_bitrate", &config.streaming_config.record_options.video_bitrate},
|
||||
{"streaming.record_options.merge_audio_tracks", &config.streaming_config.record_options.merge_audio_tracks},
|
||||
{"streaming.record_options.application_audio_invert", &config.streaming_config.record_options.application_audio_invert},
|
||||
{"streaming.record_options.change_video_resolution", &config.streaming_config.record_options.change_video_resolution},
|
||||
{"streaming.record_options.audio_type_view", &config.streaming_config.record_options.audio_type_view},
|
||||
{"streaming.record_options.audio_track", &config.streaming_config.record_options.audio_tracks},
|
||||
{"streaming.record_options.application_audio", &config.streaming_config.record_options.application_audio},
|
||||
{"streaming.record_options.color_range", &config.streaming_config.record_options.color_range},
|
||||
{"streaming.record_options.video_quality", &config.streaming_config.record_options.video_quality},
|
||||
{"streaming.record_options.codec", &config.streaming_config.record_options.video_codec},
|
||||
@@ -85,8 +88,11 @@ namespace gsr {
|
||||
{"record.record_options.fps", &config.record_config.record_options.fps},
|
||||
{"record.record_options.video_bitrate", &config.record_config.record_options.video_bitrate},
|
||||
{"record.record_options.merge_audio_tracks", &config.record_config.record_options.merge_audio_tracks},
|
||||
{"record.record_options.application_audio_invert", &config.record_config.record_options.application_audio_invert},
|
||||
{"record.record_options.change_video_resolution", &config.record_config.record_options.change_video_resolution},
|
||||
{"record.record_options.audio_type_view", &config.record_config.record_options.audio_type_view},
|
||||
{"record.record_options.audio_track", &config.record_config.record_options.audio_tracks},
|
||||
{"record.record_options.application_audio", &config.record_config.record_options.application_audio},
|
||||
{"record.record_options.color_range", &config.record_config.record_options.color_range},
|
||||
{"record.record_options.video_quality", &config.record_config.record_options.video_quality},
|
||||
{"record.record_options.codec", &config.record_config.record_options.video_codec},
|
||||
@@ -112,8 +118,11 @@ namespace gsr {
|
||||
{"replay.record_options.fps", &config.replay_config.record_options.fps},
|
||||
{"replay.record_options.video_bitrate", &config.replay_config.record_options.video_bitrate},
|
||||
{"replay.record_options.merge_audio_tracks", &config.replay_config.record_options.merge_audio_tracks},
|
||||
{"replay.record_options.application_audio_invert", &config.replay_config.record_options.application_audio_invert},
|
||||
{"replay.record_options.change_video_resolution", &config.replay_config.record_options.change_video_resolution},
|
||||
{"replay.record_options.audio_type_view", &config.replay_config.record_options.audio_type_view},
|
||||
{"replay.record_options.audio_track", &config.replay_config.record_options.audio_tracks},
|
||||
{"replay.record_options.application_audio", &config.replay_config.record_options.application_audio},
|
||||
{"replay.record_options.color_range", &config.replay_config.record_options.color_range},
|
||||
{"replay.record_options.video_quality", &config.replay_config.record_options.video_quality},
|
||||
{"replay.record_options.codec", &config.replay_config.record_options.video_codec},
|
||||
|
||||
@@ -218,4 +218,30 @@ namespace gsr {
|
||||
|
||||
return audio_devices;
|
||||
}
|
||||
|
||||
std::vector<std::string> get_application_audio() {
|
||||
std::vector<std::string> application_audio;
|
||||
|
||||
FILE *f = popen("gpu-screen-recorder --list-application-audio", "r");
|
||||
if(!f) {
|
||||
fprintf(stderr, "error: 'gpu-screen-recorder --list-application-audio' failed\n");
|
||||
return application_audio;
|
||||
}
|
||||
|
||||
char output[16384];
|
||||
ssize_t bytes_read = fread(output, 1, sizeof(output) - 1, f);
|
||||
if(bytes_read < 0 || ferror(f)) {
|
||||
fprintf(stderr, "error: failed to read 'gpu-screen-recorder --list-application-audio' output\n");
|
||||
pclose(f);
|
||||
return application_audio;
|
||||
}
|
||||
output[bytes_read] = '\0';
|
||||
|
||||
string_split_char({output, (size_t)bytes_read}, '\n', [&](std::string_view line) {
|
||||
application_audio.emplace_back(line);
|
||||
return true;
|
||||
});
|
||||
|
||||
return application_audio;
|
||||
}
|
||||
}
|
||||
|
||||
149
src/Overlay.cpp
149
src/Overlay.cpp
@@ -130,6 +130,15 @@ namespace gsr {
|
||||
&& diff_int(geometry.width, monitor->size.x, margin) && diff_int(geometry.height, monitor->size.y, margin);
|
||||
}
|
||||
|
||||
static void set_focused_window(Display *dpy, Window window) {
|
||||
XSetInputFocus(dpy, window, RevertToParent, CurrentTime);
|
||||
|
||||
const Atom net_active_window_atom = XInternAtom(dpy, "_NET_ACTIVE_WINDOW", False);
|
||||
XChangeProperty(dpy, DefaultRootWindow(dpy), net_active_window_atom, XA_WINDOW, 32, PropModeReplace, (const unsigned char*)&window, 1);
|
||||
|
||||
XFlush(dpy);
|
||||
}
|
||||
|
||||
#define _NET_WM_STATE_REMOVE 0
|
||||
#define _NET_WM_STATE_ADD 1
|
||||
#define _NET_WM_STATE_TOGGLE 2
|
||||
@@ -370,8 +379,6 @@ namespace gsr {
|
||||
|
||||
update_compositor_texture(focused_monitor);
|
||||
|
||||
audio_devices = get_audio_devices();
|
||||
|
||||
top_bar_text = mgl::Text("GPU Screen Recorder", get_theme().top_bar_font);
|
||||
logo_sprite = mgl::Sprite(&get_theme().logo_texture);
|
||||
|
||||
@@ -418,7 +425,7 @@ namespace gsr {
|
||||
button->set_item_icon("save", &get_theme().save_texture);
|
||||
button->on_click = [this](const std::string &id) {
|
||||
if(id == "settings") {
|
||||
auto replay_settings_page = std::make_unique<SettingsPage>(SettingsPage::Type::REPLAY, gsr_info, audio_devices, config, &page_stack);
|
||||
auto replay_settings_page = std::make_unique<SettingsPage>(SettingsPage::Type::REPLAY, gsr_info, config, &page_stack);
|
||||
page_stack.push(std::move(replay_settings_page));
|
||||
} else if(id == "save") {
|
||||
on_press_save_replay();
|
||||
@@ -439,7 +446,7 @@ namespace gsr {
|
||||
button->set_item_icon("pause", &get_theme().pause_texture);
|
||||
button->on_click = [this](const std::string &id) {
|
||||
if(id == "settings") {
|
||||
auto record_settings_page = std::make_unique<SettingsPage>(SettingsPage::Type::RECORD, gsr_info, audio_devices, config, &page_stack);
|
||||
auto record_settings_page = std::make_unique<SettingsPage>(SettingsPage::Type::RECORD, gsr_info, config, &page_stack);
|
||||
page_stack.push(std::move(record_settings_page));
|
||||
} else if(id == "pause") {
|
||||
toggle_pause();
|
||||
@@ -458,7 +465,7 @@ namespace gsr {
|
||||
button->set_item_icon("start", &get_theme().play_texture);
|
||||
button->on_click = [this](const std::string &id) {
|
||||
if(id == "settings") {
|
||||
auto stream_settings_page = std::make_unique<SettingsPage>(SettingsPage::Type::STREAM, gsr_info, audio_devices, config, &page_stack);
|
||||
auto stream_settings_page = std::make_unique<SettingsPage>(SettingsPage::Type::STREAM, gsr_info, config, &page_stack);
|
||||
page_stack.push(std::move(stream_settings_page));
|
||||
} else if(id == "start") {
|
||||
on_press_start_stream();
|
||||
@@ -521,7 +528,7 @@ namespace gsr {
|
||||
// TODO: This breaks global hotkeys
|
||||
//XGrabKeyboard(display, window->get_system_handle(), True, GrabModeAsync, GrabModeAsync, CurrentTime);
|
||||
|
||||
XSetInputFocus(display, window->get_system_handle(), RevertToPointerRoot, CurrentTime);
|
||||
set_focused_window(display, window->get_system_handle());
|
||||
XFlush(display);
|
||||
|
||||
//window->set_fullscreen(true);
|
||||
@@ -864,6 +871,46 @@ namespace gsr {
|
||||
kill(gpu_screen_recorder_process, SIGUSR1);
|
||||
}
|
||||
|
||||
static void add_common_gpu_screen_recorder_args(RecordOptions &record_options, std::vector<const char*> &args, const std::string &video_bitrate, const char *region, const std::string &audio_devices_merged, const std::string &application_audio_merged) {
|
||||
if(record_options.video_quality == "custom") {
|
||||
args.push_back("-bm");
|
||||
args.push_back("cbr");
|
||||
args.push_back("-q");
|
||||
args.push_back(video_bitrate.c_str());
|
||||
} else {
|
||||
args.push_back("-q");
|
||||
args.push_back(record_options.video_quality.c_str());
|
||||
}
|
||||
|
||||
if(record_options.record_area_option == "focused" || record_options.change_video_resolution) {
|
||||
args.push_back("-s");
|
||||
args.push_back(region);
|
||||
}
|
||||
|
||||
if(record_options.audio_type_view == "audio_devices") {
|
||||
if(record_options.merge_audio_tracks) {
|
||||
args.push_back("-a");
|
||||
args.push_back(audio_devices_merged.c_str());
|
||||
} else {
|
||||
for(const std::string &audio_track : record_options.audio_tracks) {
|
||||
args.push_back("-a");
|
||||
args.push_back(audio_track.c_str());
|
||||
}
|
||||
}
|
||||
} else if(record_options.audio_type_view == "app_audio") {
|
||||
const char *app_audio_option = record_options.application_audio_invert ? "-aai" : "-aa";
|
||||
if(record_options.merge_audio_tracks) {
|
||||
args.push_back(app_audio_option);
|
||||
args.push_back(application_audio_merged.c_str());
|
||||
} else {
|
||||
for(const std::string &app_audio : record_options.application_audio) {
|
||||
args.push_back(app_audio_option);
|
||||
args.push_back(app_audio.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Overlay::on_press_start_replay(bool disable_notification) {
|
||||
switch(recording_status) {
|
||||
case RecordingStatus::NONE:
|
||||
@@ -900,13 +947,12 @@ namespace gsr {
|
||||
return;
|
||||
}
|
||||
|
||||
audio_devices = get_audio_devices();
|
||||
|
||||
// TODO: Validate input, fallback to valid values
|
||||
const std::string fps = std::to_string(config.replay_config.record_options.fps);
|
||||
const std::string video_bitrate = std::to_string(config.replay_config.record_options.video_bitrate);
|
||||
const std::string output_directory = config.replay_config.save_directory;
|
||||
const std::string audio_tracks_merged = merge_audio_tracks(config.replay_config.record_options.audio_tracks);
|
||||
const std::string audio_devices_merged = merge_audio_tracks(config.replay_config.record_options.audio_tracks);
|
||||
const std::string application_audio_merged = merge_audio_tracks(config.replay_config.record_options.application_audio);
|
||||
const std::string framerate_mode = config.replay_config.record_options.framerate_mode == "auto" ? "vfr" : config.replay_config.record_options.framerate_mode;
|
||||
const std::string replay_time = std::to_string(config.replay_config.replay_time);
|
||||
const char *video_codec = config.replay_config.record_options.video_codec.c_str();
|
||||
@@ -937,30 +983,7 @@ namespace gsr {
|
||||
"-o", output_directory.c_str()
|
||||
};
|
||||
|
||||
if(config.replay_config.record_options.video_quality == "custom") {
|
||||
args.push_back("-bm");
|
||||
args.push_back("cbr");
|
||||
args.push_back("-q");
|
||||
args.push_back(video_bitrate.c_str());
|
||||
} else {
|
||||
args.push_back("-q");
|
||||
args.push_back(config.replay_config.record_options.video_quality.c_str());
|
||||
}
|
||||
|
||||
if(config.replay_config.record_options.record_area_option == "focused" || config.replay_config.record_options.change_video_resolution) {
|
||||
args.push_back("-s");
|
||||
args.push_back(region);
|
||||
}
|
||||
|
||||
if(config.replay_config.record_options.merge_audio_tracks) {
|
||||
args.push_back("-a");
|
||||
args.push_back(audio_tracks_merged.c_str());
|
||||
} else {
|
||||
for(const std::string &audio_track : config.replay_config.record_options.audio_tracks) {
|
||||
args.push_back("-a");
|
||||
args.push_back(audio_track.c_str());
|
||||
}
|
||||
}
|
||||
add_common_gpu_screen_recorder_args(config.replay_config.record_options, args, video_bitrate, region, audio_devices_merged, application_audio_merged);
|
||||
|
||||
setenv("GSR_SHOW_SAVED_NOTIFICATION", config.replay_config.show_replay_saved_notifications ? "1" : "0", true);
|
||||
const std::string script_to_run_on_save = resources_path + (config.replay_config.save_video_in_game_folder ? "scripts/save-video-in-game-folder.sh" : "scripts/notify-saved-name.sh");
|
||||
@@ -1025,13 +1048,12 @@ namespace gsr {
|
||||
return;
|
||||
}
|
||||
|
||||
audio_devices = get_audio_devices();
|
||||
|
||||
// TODO: Validate input, fallback to valid values
|
||||
const std::string fps = std::to_string(config.record_config.record_options.fps);
|
||||
const std::string video_bitrate = std::to_string(config.record_config.record_options.video_bitrate);
|
||||
const std::string output_file = config.record_config.save_directory + "/Video_" + get_date_str() + "." + container_to_file_extension(config.record_config.container.c_str());
|
||||
const std::string audio_tracks_merged = merge_audio_tracks(config.record_config.record_options.audio_tracks);
|
||||
const std::string audio_devices_merged = merge_audio_tracks(config.record_config.record_options.audio_tracks);
|
||||
const std::string application_audio_merged = merge_audio_tracks(config.record_config.record_options.application_audio);
|
||||
const std::string framerate_mode = config.record_config.record_options.framerate_mode == "auto" ? "vfr" : config.record_config.record_options.framerate_mode;
|
||||
const char *video_codec = config.record_config.record_options.video_codec.c_str();
|
||||
const char *encoder = "gpu";
|
||||
@@ -1060,30 +1082,7 @@ namespace gsr {
|
||||
"-o", output_file.c_str()
|
||||
};
|
||||
|
||||
if(config.record_config.record_options.video_quality == "custom") {
|
||||
args.push_back("-bm");
|
||||
args.push_back("cbr");
|
||||
args.push_back("-q");
|
||||
args.push_back(video_bitrate.c_str());
|
||||
} else {
|
||||
args.push_back("-q");
|
||||
args.push_back(config.record_config.record_options.video_quality.c_str());
|
||||
}
|
||||
|
||||
if(config.record_config.record_options.record_area_option == "focused" || config.record_config.record_options.change_video_resolution) {
|
||||
args.push_back("-s");
|
||||
args.push_back(region);
|
||||
}
|
||||
|
||||
if(config.record_config.record_options.merge_audio_tracks) {
|
||||
args.push_back("-a");
|
||||
args.push_back(audio_tracks_merged.c_str());
|
||||
} else {
|
||||
for(const std::string &audio_track : config.record_config.record_options.audio_tracks) {
|
||||
args.push_back("-a");
|
||||
args.push_back(audio_track.c_str());
|
||||
}
|
||||
}
|
||||
add_common_gpu_screen_recorder_args(config.record_config.record_options, args, video_bitrate, region, audio_devices_merged, application_audio_merged);
|
||||
|
||||
setenv("GSR_SHOW_SAVED_NOTIFICATION", config.record_config.show_video_saved_notifications ? "1" : "0", true);
|
||||
const std::string script_to_run_on_save = resources_path + (config.record_config.save_video_in_game_folder ? "scripts/save-video-in-game-folder.sh" : "scripts/notify-saved-name.sh");
|
||||
@@ -1178,12 +1177,11 @@ namespace gsr {
|
||||
return;
|
||||
}
|
||||
|
||||
audio_devices = get_audio_devices();
|
||||
|
||||
// TODO: Validate input, fallback to valid values
|
||||
const std::string fps = std::to_string(config.streaming_config.record_options.fps);
|
||||
const std::string video_bitrate = std::to_string(config.streaming_config.record_options.video_bitrate);
|
||||
const std::string audio_tracks_merged = merge_audio_tracks(config.streaming_config.record_options.audio_tracks);
|
||||
const std::string audio_devices_merged = merge_audio_tracks(config.streaming_config.record_options.audio_tracks);
|
||||
const std::string application_audio_merged = merge_audio_tracks(config.streaming_config.record_options.application_audio);
|
||||
const std::string framerate_mode = config.streaming_config.record_options.framerate_mode == "auto" ? "vfr" : config.streaming_config.record_options.framerate_mode;
|
||||
const char *video_codec = config.streaming_config.record_options.video_codec.c_str();
|
||||
const char *encoder = "gpu";
|
||||
@@ -1218,30 +1216,7 @@ namespace gsr {
|
||||
"-o", url.c_str()
|
||||
};
|
||||
|
||||
if(config.streaming_config.record_options.video_quality == "custom") {
|
||||
args.push_back("-bm");
|
||||
args.push_back("cbr");
|
||||
args.push_back("-q");
|
||||
args.push_back(video_bitrate.c_str());
|
||||
} else {
|
||||
args.push_back("-q");
|
||||
args.push_back(config.streaming_config.record_options.video_quality.c_str());
|
||||
}
|
||||
|
||||
if(config.streaming_config.record_options.record_area_option == "focused" || config.streaming_config.record_options.change_video_resolution) {
|
||||
args.push_back("-s");
|
||||
args.push_back(region);
|
||||
}
|
||||
|
||||
if(config.streaming_config.record_options.merge_audio_tracks) {
|
||||
args.push_back("-a");
|
||||
args.push_back(audio_tracks_merged.c_str());
|
||||
} else {
|
||||
for(const std::string &audio_track : config.streaming_config.record_options.audio_tracks) {
|
||||
args.push_back("-a");
|
||||
args.push_back(audio_track.c_str());
|
||||
}
|
||||
}
|
||||
add_common_gpu_screen_recorder_args(config.streaming_config.record_options, args, video_bitrate, region, audio_devices_merged, application_audio_merged);
|
||||
|
||||
args.push_back(nullptr);
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ namespace gsr {
|
||||
static const float spacing_scale = 0.005f;
|
||||
static const float check_animation_speed = 10.0f;
|
||||
|
||||
static mgl::Color color_multiply(mgl::Color color, float multiply) {
|
||||
static mgl::Color color_multiply_ignore_alpha(mgl::Color color, float multiply) {
|
||||
return mgl::Color(color.r * multiply, color.g * multiply, color.b * multiply, color.a);
|
||||
}
|
||||
|
||||
@@ -18,12 +18,12 @@ namespace gsr {
|
||||
return source + (destination - source) * interpolation;
|
||||
}
|
||||
|
||||
static mgl::Color interpolate_color(mgl::Color source, mgl::Color destination, float interpolation) {
|
||||
static mgl::Color interpolate_color_ignore_alpha(mgl::Color source, mgl::Color destination, float interpolation) {
|
||||
mgl::Color color;
|
||||
color.r = linear_interpolation(source.r, destination.r, interpolation);
|
||||
color.g = linear_interpolation(source.g, destination.g, interpolation);
|
||||
color.b = linear_interpolation(source.b, destination.b, interpolation);
|
||||
color.a = linear_interpolation(source.a, destination.a, interpolation);
|
||||
color.a = source.a;
|
||||
return color;
|
||||
}
|
||||
|
||||
@@ -61,9 +61,9 @@ namespace gsr {
|
||||
|
||||
apply_animation();
|
||||
|
||||
const mgl::Color background_color_unchecked(0, 0, 0, 120);
|
||||
const mgl::Color background_color_checked = color_multiply(get_color_theme().tint_color, 0.6f);
|
||||
background_sprite.set_color(interpolate_color(background_color_unchecked, background_color_checked, toggle_animation_value));
|
||||
const mgl::Color background_color_unchecked = color_multiply_ignore_alpha(mgl::Color(25, 30, 34), 0.6f);
|
||||
const mgl::Color background_color_checked = color_multiply_ignore_alpha(get_color_theme().tint_color, 0.6f);
|
||||
background_sprite.set_color(interpolate_color_ignore_alpha(background_color_unchecked, background_color_checked, toggle_animation_value));
|
||||
background_sprite.set_position(draw_pos.floor());
|
||||
window.draw(background_sprite);
|
||||
|
||||
|
||||
@@ -22,6 +22,10 @@ namespace gsr {
|
||||
text.set_string(std::move(str));
|
||||
}
|
||||
|
||||
const std::string& Label::get_text() const {
|
||||
return text.get_string();
|
||||
}
|
||||
|
||||
mgl::vec2f Label::get_size() {
|
||||
if(!visible)
|
||||
return {0.0f, 0.0f};
|
||||
|
||||
45
src/gui/LineSeparator.cpp
Normal file
45
src/gui/LineSeparator.cpp
Normal file
@@ -0,0 +1,45 @@
|
||||
#include "../../include/gui/LineSeparator.hpp"
|
||||
#include "../../include/Theme.hpp"
|
||||
|
||||
#include <mglpp/window/Window.hpp>
|
||||
#include <mglpp/graphics/Rectangle.hpp>
|
||||
|
||||
namespace gsr {
|
||||
static const float height_scale = 0.001f;
|
||||
|
||||
static mgl::Color color_add_ignore_alpha(mgl::Color color, mgl::Color add) {
|
||||
return {
|
||||
(uint8_t)std::min((int)color.r + (int)add.r, 255),
|
||||
(uint8_t)std::min((int)color.g + (int)add.g, 255),
|
||||
(uint8_t)std::min((int)color.b + (int)add.b, 255),
|
||||
color.a
|
||||
};
|
||||
}
|
||||
|
||||
LineSeparator::LineSeparator(Type type, float width) : type(type), width(width) {
|
||||
|
||||
}
|
||||
|
||||
bool LineSeparator::on_event(mgl::Event&, mgl::Window&, mgl::vec2f) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void LineSeparator::draw(mgl::Window &window, mgl::vec2f offset) {
|
||||
if(!visible)
|
||||
return;
|
||||
|
||||
const mgl::vec2f draw_pos = (position + offset).floor();
|
||||
const mgl::vec2f size = mgl::vec2f(width, std::max(1.0f, height_scale * get_theme().window_height)).floor();
|
||||
mgl::Rectangle rectangle(draw_pos, size);
|
||||
rectangle.set_color(color_add_ignore_alpha(mgl::Color(25, 30, 34), mgl::Color(30, 30, 30)));
|
||||
window.draw(rectangle);
|
||||
}
|
||||
|
||||
mgl::vec2f LineSeparator::get_size() {
|
||||
if(!visible)
|
||||
return {0.0f, 0.0f};
|
||||
|
||||
const mgl::vec2f size = mgl::vec2f(width, std::max(1.0f, height_scale * get_theme().window_height)).floor();
|
||||
return size;
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "../../include/gui/SettingsPage.hpp"
|
||||
#include "../../include/gui/GsrPage.hpp"
|
||||
#include "../../include/gui/Label.hpp"
|
||||
#include "../../include/gui/LineSeparator.hpp"
|
||||
#include "../../include/gui/PageStack.hpp"
|
||||
#include "../../include/gui/FileChooser.hpp"
|
||||
#include "../../include/gui/Subsection.hpp"
|
||||
@@ -13,15 +14,19 @@
|
||||
#include <mglpp/graphics/Text.hpp>
|
||||
#include <mglpp/window/Window.hpp>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
namespace gsr {
|
||||
SettingsPage::SettingsPage(Type type, const GsrInfo &gsr_info, std::vector<AudioDevice> audio_devices, Config &config, PageStack *page_stack) :
|
||||
SettingsPage::SettingsPage(Type type, const GsrInfo &gsr_info, Config &config, PageStack *page_stack) :
|
||||
StaticPage(mgl::vec2f(get_theme().window_width, get_theme().window_height).floor()),
|
||||
type(type),
|
||||
config(config),
|
||||
audio_devices(std::move(audio_devices)),
|
||||
page_stack(page_stack),
|
||||
settings_title_text("Settings", get_theme().title_font)
|
||||
{
|
||||
audio_devices = get_audio_devices();
|
||||
application_audio = get_application_audio();
|
||||
|
||||
auto content_page = std::make_unique<GsrPage>();
|
||||
content_page->add_button("Back", "back", get_color_theme().page_bg_color);
|
||||
content_page->on_click = [page_stack](const std::string &id) {
|
||||
@@ -177,7 +182,7 @@ namespace gsr {
|
||||
return std::make_unique<Subsection>("Record area", std::move(ll), mgl::vec2f(settings_scrollable_page_ptr->get_inner_size().x, 0.0f));
|
||||
}
|
||||
|
||||
std::unique_ptr<ComboBox> SettingsPage::create_audio_track_selection_checkbox() {
|
||||
std::unique_ptr<ComboBox> SettingsPage::create_audio_device_selection_combobox() {
|
||||
auto audio_device_box = std::make_unique<ComboBox>(&get_theme().body_font);
|
||||
for(const auto &audio_device : audio_devices) {
|
||||
audio_device_box->add_item(audio_device.description, audio_device.name);
|
||||
@@ -185,7 +190,7 @@ namespace gsr {
|
||||
return audio_device_box;
|
||||
}
|
||||
|
||||
std::unique_ptr<Button> SettingsPage::create_remove_audio_track_button(List *audio_device_list_ptr) {
|
||||
std::unique_ptr<Button> SettingsPage::create_remove_audio_device_button(List *audio_device_list_ptr) {
|
||||
auto remove_audio_track_button = std::make_unique<Button>(&get_theme().body_font, "Remove", mgl::vec2f(0.0f, 0.0f), mgl::Color(0, 0, 0, 120));
|
||||
remove_audio_track_button->on_click = [this, audio_device_list_ptr]() {
|
||||
audio_devices_list_ptr->remove_widget(audio_device_list_ptr);
|
||||
@@ -193,26 +198,25 @@ namespace gsr {
|
||||
return remove_audio_track_button;
|
||||
}
|
||||
|
||||
std::unique_ptr<List> SettingsPage::create_audio_track() {
|
||||
std::unique_ptr<List> SettingsPage::create_audio_device() {
|
||||
auto audio_device_list = std::make_unique<List>(List::Orientation::HORIZONTAL, List::Alignment::CENTER);
|
||||
audio_device_list->add_widget(create_audio_track_selection_checkbox());
|
||||
audio_device_list->add_widget(create_remove_audio_track_button(audio_device_list.get()));
|
||||
audio_device_list->add_widget(create_audio_device_selection_combobox());
|
||||
audio_device_list->add_widget(create_remove_audio_device_button(audio_device_list.get()));
|
||||
return audio_device_list;
|
||||
}
|
||||
|
||||
std::unique_ptr<Button> SettingsPage::create_add_audio_track_button() {
|
||||
auto add_audio_track_button = std::make_unique<Button>(&get_theme().body_font, "Add audio track", mgl::vec2f(0.0f, 0.0f), mgl::Color(0, 0, 0, 120));
|
||||
auto add_audio_track = [this]() {
|
||||
audio_devices_list_ptr->add_widget(create_audio_track());
|
||||
std::unique_ptr<Button> SettingsPage::create_add_audio_device_button() {
|
||||
auto add_audio_track_button = std::make_unique<Button>(&get_theme().body_font, "Add audio device", mgl::vec2f(0.0f, 0.0f), mgl::Color(0, 0, 0, 120));
|
||||
add_audio_track_button->on_click = [this]() {
|
||||
audio_devices_list_ptr->add_widget(create_audio_device());
|
||||
};
|
||||
add_audio_track_button->on_click = add_audio_track;
|
||||
return add_audio_track_button;
|
||||
}
|
||||
|
||||
std::unique_ptr<List> SettingsPage::create_audio_track_section() {
|
||||
std::unique_ptr<List> SettingsPage::create_audio_device_track_section() {
|
||||
auto audio_devices_list = std::make_unique<List>(List::Orientation::VERTICAL);
|
||||
audio_devices_list_ptr = audio_devices_list.get();
|
||||
audio_devices_list_ptr->add_widget(create_audio_track());
|
||||
audio_devices_list_ptr->add_widget(create_audio_device());
|
||||
return audio_devices_list;
|
||||
}
|
||||
|
||||
@@ -223,13 +227,107 @@ namespace gsr {
|
||||
return merge_audio_tracks_checkbox;
|
||||
}
|
||||
|
||||
std::unique_ptr<RadioButton> SettingsPage::create_audio_type_button() {
|
||||
auto audio_type_radio_button = std::make_unique<RadioButton>(&get_theme().body_font);
|
||||
audio_type_radio_button->add_item("Audio devices", "audio_devices");
|
||||
audio_type_radio_button->add_item("Application audio", "app_audio");
|
||||
audio_type_radio_button_ptr = audio_type_radio_button.get();
|
||||
return audio_type_radio_button;
|
||||
}
|
||||
|
||||
std::unique_ptr<Widget> SettingsPage::create_audio_device_section() {
|
||||
auto audio_devices_section_list = std::make_unique<List>(List::Orientation::VERTICAL);
|
||||
audio_devices_section_list_ptr = audio_devices_section_list.get();
|
||||
audio_devices_section_list->add_widget(std::make_unique<Label>(&get_theme().title_font, "Audio devices", get_color_theme().text_color));
|
||||
audio_devices_section_list->add_widget(create_add_audio_device_button());
|
||||
audio_devices_section_list->add_widget(create_audio_device_track_section());
|
||||
return audio_devices_section_list;
|
||||
}
|
||||
|
||||
std::unique_ptr<ComboBox> SettingsPage::create_application_audio_selection_combobox() {
|
||||
auto audio_device_box = std::make_unique<ComboBox>(&get_theme().body_font);
|
||||
for(const auto &app_audio : application_audio) {
|
||||
audio_device_box->add_item(app_audio, app_audio);
|
||||
}
|
||||
return audio_device_box;
|
||||
}
|
||||
|
||||
std::unique_ptr<Button> SettingsPage::create_remove_application_audio_button(List *app_audio_item) {
|
||||
auto remove_audio_track_button = std::make_unique<Button>(&get_theme().body_font, "Remove", mgl::vec2f(0.0f, 0.0f), mgl::Color(0, 0, 0, 120));
|
||||
remove_audio_track_button->on_click = [this, app_audio_item]() {
|
||||
application_audio_list_ptr->remove_widget(app_audio_item);
|
||||
};
|
||||
return remove_audio_track_button;
|
||||
}
|
||||
|
||||
std::unique_ptr<List> SettingsPage::create_application_audio() {
|
||||
auto application_audio_list = std::make_unique<List>(List::Orientation::HORIZONTAL, List::Alignment::CENTER);
|
||||
application_audio_list->add_widget(create_application_audio_selection_combobox());
|
||||
application_audio_list->add_widget(create_remove_application_audio_button(application_audio_list.get()));
|
||||
return application_audio_list;
|
||||
}
|
||||
|
||||
std::unique_ptr<List> SettingsPage::create_custom_application_audio() {
|
||||
auto application_audio_list = std::make_unique<List>(List::Orientation::HORIZONTAL, List::Alignment::CENTER);
|
||||
application_audio_list->add_widget(std::make_unique<Entry>(&get_theme().body_font, "", (int)(get_theme().body_font.get_character_size() * 10.0f)));
|
||||
application_audio_list->add_widget(create_remove_application_audio_button(application_audio_list.get()));
|
||||
return application_audio_list;
|
||||
}
|
||||
|
||||
std::unique_ptr<List> SettingsPage::create_add_application_audio_buttons() {
|
||||
auto list = std::make_unique<List>(List::Orientation::HORIZONTAL, List::Alignment::CENTER);
|
||||
|
||||
auto add_application_audio_button = std::make_unique<Button>(&get_theme().body_font, "Add application audio", mgl::vec2f(0.0f, 0.0f), mgl::Color(0, 0, 0, 120));
|
||||
add_application_audio_button->on_click = [this]() {
|
||||
application_audio_list_ptr->add_widget(create_application_audio());
|
||||
};
|
||||
list->add_widget(std::move(add_application_audio_button));
|
||||
|
||||
auto add_custom_application_audio_button = std::make_unique<Button>(&get_theme().body_font, "Add custom application audio", mgl::vec2f(0.0f, 0.0f), mgl::Color(0, 0, 0, 120));
|
||||
add_custom_application_audio_button->on_click = [this]() {
|
||||
application_audio_list_ptr->add_widget(create_custom_application_audio());
|
||||
};
|
||||
list->add_widget(std::move(add_custom_application_audio_button));
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
std::unique_ptr<List> SettingsPage::create_application_audio_track_section() {
|
||||
auto application_audio_list = std::make_unique<List>(List::Orientation::VERTICAL);
|
||||
application_audio_list_ptr = application_audio_list.get();
|
||||
return application_audio_list;
|
||||
}
|
||||
|
||||
std::unique_ptr<CheckBox> SettingsPage::create_application_audio_invert_checkbox() {
|
||||
auto application_audio_invert_checkbox = std::make_unique<CheckBox>(&get_theme().body_font, "Record all applications except the selected ones");
|
||||
application_audio_invert_checkbox->set_checked(false);
|
||||
application_audio_invert_checkbox_ptr = application_audio_invert_checkbox.get();
|
||||
return application_audio_invert_checkbox;
|
||||
}
|
||||
|
||||
std::unique_ptr<List> SettingsPage::create_application_audio_section() {
|
||||
auto application_audio_section_list = std::make_unique<List>(List::Orientation::VERTICAL);
|
||||
application_audio_section_list_ptr = application_audio_section_list.get();
|
||||
application_audio_section_list->add_widget(std::make_unique<Label>(&get_theme().title_font, "Application audio", get_color_theme().text_color));
|
||||
application_audio_section_list->add_widget(create_add_application_audio_buttons());
|
||||
application_audio_section_list->add_widget(create_application_audio_track_section());
|
||||
application_audio_section_list->add_widget(create_application_audio_invert_checkbox());
|
||||
return application_audio_section_list;
|
||||
}
|
||||
|
||||
std::unique_ptr<Widget> SettingsPage::create_audio_section() {
|
||||
auto audio_device_section_list = std::make_unique<List>(List::Orientation::VERTICAL);
|
||||
audio_device_section_list->add_widget(create_add_audio_track_button());
|
||||
audio_device_section_list->add_widget(create_audio_track_section());
|
||||
audio_device_section_list->add_widget(create_merge_audio_tracks_checkbox());
|
||||
audio_device_section_list->add_widget(create_audio_codec());
|
||||
return std::make_unique<Subsection>("Audio", std::move(audio_device_section_list), mgl::vec2f(settings_scrollable_page_ptr->get_inner_size().x, 0.0f));
|
||||
List *audio_device_section_list_ptr = audio_device_section_list.get();
|
||||
auto audio_section = std::make_unique<Subsection>("Audio", std::move(audio_device_section_list), mgl::vec2f(settings_scrollable_page_ptr->get_inner_size().x, 0.0f));
|
||||
|
||||
audio_device_section_list_ptr->add_widget(create_audio_type_button());
|
||||
audio_device_section_list_ptr->add_widget(std::make_unique<LineSeparator>(LineSeparator::Type::HORIZONTAL, audio_section->get_inner_size().x));
|
||||
audio_device_section_list_ptr->add_widget(create_audio_device_section());
|
||||
audio_device_section_list_ptr->add_widget(create_application_audio_section());
|
||||
//audio_device_section_list_ptr->add_widget(std::make_unique<LineSeparator>(LineSeparator::Type::HORIZONTAL, audio_section->get_inner_size().x));
|
||||
audio_device_section_list_ptr->add_widget(create_merge_audio_tracks_checkbox());
|
||||
audio_device_section_list_ptr->add_widget(create_audio_codec());
|
||||
return audio_section;
|
||||
}
|
||||
|
||||
std::unique_ptr<List> SettingsPage::create_video_quality_box() {
|
||||
@@ -418,7 +516,7 @@ namespace gsr {
|
||||
auto settings_list = std::make_unique<List>(List::Orientation::VERTICAL);
|
||||
settings_list->set_spacing(0.018f);
|
||||
settings_list->add_widget(create_capture_target(gsr_info));
|
||||
settings_list->add_widget(create_audio_device_section());
|
||||
settings_list->add_widget(create_audio_section());
|
||||
settings_list->add_widget(create_video_section(gsr_info));
|
||||
settings_list_ptr = settings_list.get();
|
||||
settings_scrollable_page_ptr->add_widget(std::move(settings_list));
|
||||
@@ -463,6 +561,17 @@ namespace gsr {
|
||||
record_area_box_ptr->set_selected_item("window");
|
||||
else
|
||||
record_area_box_ptr->on_selection_changed("", "");
|
||||
|
||||
audio_type_radio_button_ptr->on_selection_changed = [this](const std::string&, const std::string &id) {
|
||||
if(id == "audio_devices") {
|
||||
audio_devices_section_list_ptr->set_visible(true);
|
||||
application_audio_section_list_ptr->set_visible(false);
|
||||
} else if(id == "app_audio") {
|
||||
audio_devices_section_list_ptr->set_visible(false);
|
||||
application_audio_section_list_ptr->set_visible(true);
|
||||
}
|
||||
};
|
||||
audio_type_radio_button_ptr->on_selection_changed("", "audio_devices");
|
||||
}
|
||||
|
||||
void SettingsPage::add_page_specific_widgets() {
|
||||
@@ -496,6 +605,7 @@ namespace gsr {
|
||||
select_directory_page->on_click = [this, file_chooser_ptr](const std::string &id) {
|
||||
if(id == "save")
|
||||
save_directory_button_ptr->set_text(file_chooser_ptr->get_current_directory());
|
||||
else if(id == "cancel")
|
||||
page_stack->pop();
|
||||
};
|
||||
|
||||
@@ -811,22 +921,50 @@ namespace gsr {
|
||||
save_config(config);
|
||||
}
|
||||
|
||||
void SettingsPage::load_audio_tracks(RecordOptions &record_options) {
|
||||
static const std::string* get_application_audio_by_name_case_insensitive(const std::vector<std::string> &application_audio, const std::string &name) {
|
||||
for(const auto &app_audio : application_audio) {
|
||||
if(strcasecmp(app_audio.c_str(), name.c_str()) == 0)
|
||||
return &app_audio;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void SettingsPage::load_audio_device_tracks(RecordOptions &record_options) {
|
||||
audio_devices_list_ptr->clear();
|
||||
for(const std::string &audio_track : record_options.audio_tracks) {
|
||||
std::unique_ptr<List> audio_track_widget = create_audio_track();
|
||||
std::unique_ptr<List> audio_track_widget = create_audio_device();
|
||||
ComboBox *audio_device_box = static_cast<ComboBox*>(audio_track_widget->get_child_widget_by_index(0));
|
||||
audio_device_box->set_selected_item(audio_track);
|
||||
audio_devices_list_ptr->add_widget(std::move(audio_track_widget));
|
||||
}
|
||||
}
|
||||
|
||||
void SettingsPage::load_application_audio_tracks(RecordOptions &record_options) {
|
||||
application_audio_list_ptr->clear();
|
||||
for(const std::string &audio_track : record_options.application_audio) {
|
||||
const std::string *app_audio = get_application_audio_by_name_case_insensitive(application_audio, audio_track);
|
||||
if(app_audio) {
|
||||
std::unique_ptr<List> application_audio_widget = create_application_audio();
|
||||
ComboBox *application_audio_box = static_cast<ComboBox*>(application_audio_widget->get_child_widget_by_index(0));
|
||||
application_audio_box->set_selected_item(*app_audio);
|
||||
application_audio_list_ptr->add_widget(std::move(application_audio_widget));
|
||||
} else {
|
||||
std::unique_ptr<List> application_audio_widget = create_custom_application_audio();
|
||||
Entry *application_audio_entry = static_cast<Entry*>(application_audio_widget->get_child_widget_by_index(0));
|
||||
application_audio_entry->set_text(audio_track);
|
||||
application_audio_list_ptr->add_widget(std::move(application_audio_widget));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SettingsPage::load_common(RecordOptions &record_options) {
|
||||
record_area_box_ptr->set_selected_item(record_options.record_area_option);
|
||||
merge_audio_tracks_checkbox_ptr->set_checked(record_options.merge_audio_tracks);
|
||||
application_audio_invert_checkbox_ptr->set_checked(record_options.application_audio_invert);
|
||||
change_video_resolution_checkbox_ptr->set_checked(record_options.change_video_resolution);
|
||||
|
||||
load_audio_tracks(record_options);
|
||||
audio_type_radio_button_ptr->set_selected_item(record_options.audio_type_view);
|
||||
load_audio_device_tracks(record_options);
|
||||
load_application_audio_tracks(record_options);
|
||||
color_range_box_ptr->set_selected_item(record_options.color_range);
|
||||
video_quality_box_ptr->set_selected_item(record_options.video_quality);
|
||||
video_codec_box_ptr->set_selected_item(record_options.video_codec);
|
||||
@@ -910,12 +1048,26 @@ namespace gsr {
|
||||
container_box_ptr->set_selected_item(config.streaming_config.custom.container);
|
||||
}
|
||||
|
||||
static void save_audio_tracks(std::vector<std::string> &audio_tracks, List *audio_devices_list_ptr) {
|
||||
audio_tracks.clear();
|
||||
audio_devices_list_ptr->for_each_child_widget([&audio_tracks](std::unique_ptr<Widget> &child_widget) {
|
||||
static void save_audio_device_tracks(std::vector<std::string> &audio_devices, List *audio_devices_list_ptr) {
|
||||
audio_devices.clear();
|
||||
audio_devices_list_ptr->for_each_child_widget([&audio_devices](std::unique_ptr<Widget> &child_widget) {
|
||||
List *audio_device_line = static_cast<List*>(child_widget.get());
|
||||
ComboBox *audio_device_box = static_cast<ComboBox*>(audio_device_line->get_child_widget_by_index(0));
|
||||
audio_tracks.push_back(audio_device_box->get_selected_id());
|
||||
audio_devices.push_back(audio_device_box->get_selected_id());
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
static void save_application_audio_tracks(std::vector<std::string> &application_audio, List *application_audio_list_ptr) {
|
||||
application_audio.clear();
|
||||
application_audio_list_ptr->for_each_child_widget([&application_audio](std::unique_ptr<Widget> &child_widget) {
|
||||
List *application_audio_line = static_cast<List*>(child_widget.get());
|
||||
ComboBox *application_audio_box = dynamic_cast<ComboBox*>(application_audio_line->get_child_widget_by_index(0));
|
||||
Entry *application_audio_entry = dynamic_cast<Entry*>(application_audio_line->get_child_widget_by_index(0));
|
||||
if(application_audio_box)
|
||||
application_audio.push_back(application_audio_box->get_selected_id());
|
||||
else if(application_audio_entry)
|
||||
application_audio.push_back(application_audio_entry->get_text());
|
||||
return true;
|
||||
});
|
||||
}
|
||||
@@ -929,8 +1081,11 @@ namespace gsr {
|
||||
record_options.fps = atoi(framerate_entry_ptr->get_text().c_str());
|
||||
record_options.video_bitrate = atoi(video_bitrate_entry_ptr->get_text().c_str());
|
||||
record_options.merge_audio_tracks = merge_audio_tracks_checkbox_ptr->is_checked();
|
||||
record_options.application_audio_invert = application_audio_invert_checkbox_ptr->is_checked();
|
||||
record_options.change_video_resolution = change_video_resolution_checkbox_ptr->is_checked();
|
||||
save_audio_tracks(record_options.audio_tracks, audio_devices_list_ptr);
|
||||
record_options.audio_type_view = audio_type_radio_button_ptr->get_selected_id();
|
||||
save_audio_device_tracks(record_options.audio_tracks, audio_devices_list_ptr);
|
||||
save_application_audio_tracks(record_options.application_audio, application_audio_list_ptr);
|
||||
record_options.color_range = color_range_box_ptr->get_selected_id();
|
||||
record_options.video_quality = video_quality_box_ptr->get_selected_id();
|
||||
record_options.video_codec = video_codec_box_ptr->get_selected_id();
|
||||
|
||||
@@ -36,8 +36,11 @@ namespace gsr {
|
||||
window.draw(background);
|
||||
|
||||
draw_pos += mgl::vec2f(margin_left_scale, margin_top_scale) * mgl::vec2f(get_theme().window_height, get_theme().window_height);
|
||||
|
||||
if(!label.get_text().empty()) {
|
||||
label.draw(window, draw_pos);
|
||||
draw_pos.y += label.get_size().y + title_spacing_scale * get_theme().window_height;
|
||||
}
|
||||
|
||||
inner_widget->set_position(draw_pos);
|
||||
inner_widget->draw(window, mgl::vec2f(0.0f, 0.0f));
|
||||
@@ -48,7 +51,8 @@ namespace gsr {
|
||||
return {0.0f, 0.0f};
|
||||
|
||||
const mgl::vec2f margin_size = mgl::vec2f(margin_left_scale + margin_right_scale, margin_top_scale + margin_bottom_scale) * mgl::vec2f(get_theme().window_height, get_theme().window_height);
|
||||
mgl::vec2f widgets_size = mgl::vec2f(0.0f, label.get_size().y + title_spacing_scale * get_theme().window_height) + inner_widget->get_size() + margin_size;
|
||||
const float title_height = !label.get_text().empty() ? (label.get_size().y + title_spacing_scale * get_theme().window_height) : 0.0f;
|
||||
mgl::vec2f widgets_size = mgl::vec2f(0.0f, title_height) + inner_widget->get_size() + margin_size;
|
||||
|
||||
if(std::abs(size.x) > 0.001f)
|
||||
widgets_size.x = size.x;
|
||||
@@ -57,4 +61,12 @@ namespace gsr {
|
||||
|
||||
return widgets_size;
|
||||
}
|
||||
|
||||
mgl::vec2f Subsection::get_inner_size() {
|
||||
if(!visible)
|
||||
return {0.0f, 0.0f};
|
||||
|
||||
const mgl::vec2f margin_size = mgl::vec2f(margin_left_scale + margin_right_scale, margin_top_scale + margin_bottom_scale) * mgl::vec2f(get_theme().window_height, get_theme().window_height);
|
||||
return get_size() - margin_size;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user