aboutsummaryrefslogtreecommitdiff
path: root/src/main.cpp
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2024-08-02 00:32:59 +0200
committerdec05eba <dec05eba@protonmail.com>2024-08-02 00:32:59 +0200
commit492cb57f8df3afd56c18e38ccafbf7e57360b87a (patch)
treeeed059a57e73621904d5a800f48582e7b327e7f4 /src/main.cpp
parent0f237d8ddf0151bbf0d18b060c8210cd246dcef8 (diff)
Query audio devices from gpu screen recorder instead of using pulseaudio in the gui. Makes it simpler and makes sure that the exact same device name is used that gpu screen recorder expects
Diffstat (limited to 'src/main.cpp')
-rw-r--r--src/main.cpp178
1 files changed, 30 insertions, 148 deletions
diff --git a/src/main.cpp b/src/main.cpp
index 3fc6f24..4e94474 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -10,7 +10,6 @@ extern "C" {
#include <X11/cursorfont.h>
#include <assert.h>
#include <string>
-#include <pulse/pulseaudio.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/prctl.h>
@@ -160,13 +159,7 @@ struct AudioInput {
std::string description;
};
-struct PulseAudioServerInfo {
- std::string default_sink_name;
- std::string default_source_name;
-};
-
static std::vector<AudioInput> audio_inputs;
-static PulseAudioServerInfo pa_default_sources;
enum class HotkeyMode {
NoAction,
@@ -498,128 +491,44 @@ static void setup_systray(GtkApplication *app) {
app_indicator_set_menu(app_indicator, GTK_MENU(create_systray_menu(app, SystrayPage::FRONT)));
}
-static void pa_state_cb(pa_context *c, void *userdata) {
- pa_context_state state = pa_context_get_state(c);
- int *pa_ready = (int*)userdata;
- switch(state) {
- case PA_CONTEXT_UNCONNECTED:
- case PA_CONTEXT_CONNECTING:
- case PA_CONTEXT_AUTHORIZING:
- case PA_CONTEXT_SETTING_NAME:
- default:
- break;
- case PA_CONTEXT_FAILED:
- case PA_CONTEXT_TERMINATED:
- *pa_ready = 2;
- break;
- case PA_CONTEXT_READY:
- *pa_ready = 1;
- break;
- }
-}
-
-static void pa_sourcelist_cb(pa_context*, const pa_source_info *source_info, int eol, void *userdata) {
- if(eol > 0)
- return;
+static AudioInput parse_audio_device_line(const std::string &line) {
+ AudioInput audio_input;
+ const size_t space_index = line.find(' ');
+ if(space_index == std::string::npos)
+ return audio_input;
- std::vector<AudioInput> *inputs = (std::vector<AudioInput>*)userdata;
- inputs->push_back({ source_info->name, source_info->description });
+ const StringView audio_input_name = {line.c_str(), space_index};
+ const StringView audio_input_description = {line.c_str() + space_index + 1, line.size() - (space_index + 1)};
+ audio_input.name.assign(audio_input_name.str, audio_input_name.size);
+ audio_input.description.assign(audio_input_description.str, audio_input_description.size);
+ return audio_input;
}
static std::vector<AudioInput> get_pulseaudio_inputs() {
std::vector<AudioInput> inputs;
- pa_mainloop *main_loop = pa_mainloop_new();
-
- pa_context *ctx = pa_context_new(pa_mainloop_get_api(main_loop), "gpu-screen-recorder-gtk");
- pa_context_connect(ctx, NULL, PA_CONTEXT_NOFLAGS, NULL);
- int state = 0;
- int pa_ready = 0;
- pa_context_set_state_callback(ctx, pa_state_cb, &pa_ready);
-
- pa_operation *pa_op = NULL;
-
- for(;;) {
- // Not ready
- if(pa_ready == 0) {
- pa_mainloop_iterate(main_loop, 1, NULL);
- continue;
- }
- switch(state) {
- case 0: {
- pa_op = pa_context_get_source_info_list(ctx, pa_sourcelist_cb, &inputs);
- ++state;
- break;
- }
- }
-
- // Couldn't get connection to the server
- if(pa_ready == 2 || (state == 1 && pa_op && pa_operation_get_state(pa_op) == PA_OPERATION_DONE)) {
- if(pa_op)
- pa_operation_unref(pa_op);
- pa_context_disconnect(ctx);
- pa_context_unref(ctx);
- pa_mainloop_free(main_loop);
- return inputs;
- }
-
- pa_mainloop_iterate(main_loop, 1, NULL);
+ FILE *f = popen("gpu-screen-recorder --list-audio-devices", "r");
+ if(!f) {
+ fprintf(stderr, "error: 'gpu-screen-recorder --info' failed\n");
+ return inputs;
}
- pa_mainloop_free(main_loop);
- return {};
-}
-
-static void server_info_callback(pa_context*, const pa_server_info *server_info, void *userdata) {
- PulseAudioServerInfo *u = (PulseAudioServerInfo*)userdata;
- if(server_info->default_sink_name)
- u->default_sink_name = std::string(server_info->default_sink_name) + ".monitor";
- if(server_info->default_source_name)
- u->default_source_name = server_info->default_source_name;
-}
-
-static PulseAudioServerInfo get_pulseaudio_default_inputs() {
- PulseAudioServerInfo server_info;
- pa_mainloop *main_loop = pa_mainloop_new();
-
- pa_context *ctx = pa_context_new(pa_mainloop_get_api(main_loop), "gpu-screen-recorder-gtk");
- pa_context_connect(ctx, NULL, PA_CONTEXT_NOFLAGS, NULL);
- int state = 0;
- int pa_ready = 0;
- pa_context_set_state_callback(ctx, pa_state_cb, &pa_ready);
-
- pa_operation *pa_op = NULL;
-
- for(;;) {
- // Not ready
- if(pa_ready == 0) {
- pa_mainloop_iterate(main_loop, 1, NULL);
- continue;
- }
-
- switch(state) {
- case 0: {
- pa_op = pa_context_get_server_info(ctx, server_info_callback, &server_info);
- ++state;
- break;
- }
- }
-
- // Couldn't get connection to the server
- if(pa_ready == 2 || (state == 1 && pa_op && pa_operation_get_state(pa_op) == PA_OPERATION_DONE)) {
- if(pa_op)
- pa_operation_unref(pa_op);
- pa_context_disconnect(ctx);
- pa_context_unref(ctx);
- pa_mainloop_free(main_loop);
- return server_info;
- }
-
- pa_mainloop_iterate(main_loop, 1, NULL);
+ 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 --info' output\n");
+ pclose(f);
+ return inputs;
}
+ output[bytes_read] = '\0';
+
+ string_split_char(output, '\n', [&](StringView line) {
+ const std::string line_str(line.str, line.size);
+ inputs.push_back(parse_audio_device_line(line_str));
+ return true;
+ });
- pa_mainloop_free(main_loop);
- return server_info;
+ return inputs;
}
static void used_audio_input_loop_callback(GtkWidget *row, gpointer userdata) {
@@ -1564,31 +1473,19 @@ static bool kill_gpu_screen_recorder_get_result(bool *already_dead) {
return exit_success;
}
-static const gchar* audio_row_get_id(const AudioRow *audio_row) {
- const char *text = gtk_combo_box_text_get_active_text(audio_row->input_list);
- if(strcmp(text, "Default output") == 0 && !pa_default_sources.default_sink_name.empty())
- return pa_default_sources.default_sink_name.c_str();
- else if(strcmp(text, "Default input") == 0 && !pa_default_sources.default_source_name.empty())
- return pa_default_sources.default_source_name.c_str();
- else
- return gtk_combo_box_get_active_id(GTK_COMBO_BOX(audio_row->input_list));
-}
-
static void add_audio_command_line_args(std::vector<const char*> &args, std::string &merge_audio_tracks_arg_value) {
- pa_default_sources = get_pulseaudio_default_inputs();
-
if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(merge_audio_tracks_button))) {
for_each_used_audio_input(GTK_LIST_BOX(audio_input_used_list), [&merge_audio_tracks_arg_value](const AudioRow *audio_row) {
if(!merge_audio_tracks_arg_value.empty())
merge_audio_tracks_arg_value += '|';
- merge_audio_tracks_arg_value += audio_row_get_id(audio_row);
+ merge_audio_tracks_arg_value += gtk_combo_box_get_active_id(GTK_COMBO_BOX(audio_row->input_list));
});
if(!merge_audio_tracks_arg_value.empty())
args.insert(args.end(), { "-a", merge_audio_tracks_arg_value.c_str() });
} else {
for_each_used_audio_input(GTK_LIST_BOX(audio_input_used_list), [&args](const AudioRow *audio_row) {
- args.insert(args.end(), { "-a", audio_row_get_id(audio_row) });
+ args.insert(args.end(), { "-a", gtk_combo_box_get_active_id(GTK_COMBO_BOX(audio_row->input_list)) });
});
}
}
@@ -2424,14 +2321,6 @@ static gboolean on_hotkey_entry_click(GtkWidget *button, gpointer) {
return true;
}
-static bool audio_inputs_contains(const std::vector<AudioInput> &_audio_inputs, const std::string &audio_input_name) {
- for(auto &audio_input : _audio_inputs) {
- if(audio_input.name == audio_input_name)
- return true;
- }
- return false;
-}
-
static void parse_system_info_line(GsrInfo *_gsr_info, const std::string &line) {
const size_t space_index = line.find(' ');
if(space_index == std::string::npos)
@@ -3933,13 +3822,6 @@ static void activate(GtkApplication *app, gpointer) {
select_window_userdata.app = app;
audio_inputs = get_pulseaudio_inputs();
- pa_default_sources = get_pulseaudio_default_inputs();
-
- if(!pa_default_sources.default_source_name.empty() && audio_inputs_contains(audio_inputs, pa_default_sources.default_source_name))
- audio_inputs.insert(audio_inputs.begin(), { pa_default_sources.default_source_name.c_str(), "Default input" });
-
- if(!pa_default_sources.default_sink_name.empty() && audio_inputs_contains(audio_inputs, pa_default_sources.default_sink_name))
- audio_inputs.insert(audio_inputs.begin(), { pa_default_sources.default_sink_name.c_str(), "Default output" });
if(gsr_info.system_info.display_server != DisplayServer::WAYLAND)
crosshair_cursor = XCreateFontCursor(gdk_x11_get_default_xdisplay(), XC_crosshair);