feat: shortcut
This commit is contained in:
1 parent
05a7c1cd83
commit
37fbe5d787
2 files changed
+15
-61
No files matched your search
+13
-59
@@ -19,8 +19,6 @@ namespace {
|
||||
|
||||
constexpr const char* kAppId = "io.github.transui";
|
||||
constexpr const char* kConfigGroup = "transui";
|
||||
constexpr gint64 kSilenceTimeoutUs = 2 * G_USEC_PER_SEC;
|
||||
constexpr double kSoundThresholdDb = -42.0;
|
||||
|
||||
const SecretSchema kSecretSchema = {
|
||||
"io.github.transui.credentials", SECRET_SCHEMA_NONE,
|
||||
@@ -45,10 +43,7 @@ struct App {
|
||||
GtkWidget* processing = nullptr;
|
||||
GtkWidget* elapsed_label = nullptr;
|
||||
guint elapsed_source = 0;
|
||||
guint silence_source = 0;
|
||||
guint level_watch = 0;
|
||||
guint elapsed_seconds = 0;
|
||||
gint64 last_sound_us = 0;
|
||||
GstElement* pipeline = nullptr;
|
||||
std::string recording_path;
|
||||
std::atomic<bool> cancelled{false};
|
||||
@@ -290,53 +285,11 @@ gboolean tick_elapsed(gpointer data) {
|
||||
return G_SOURCE_CONTINUE;
|
||||
}
|
||||
|
||||
void stop_recording(GtkButton*, gpointer data);
|
||||
|
||||
gboolean monitor_audio_level(GstBus*, GstMessage* message, gpointer data) {
|
||||
if (GST_MESSAGE_TYPE(message) != GST_MESSAGE_ELEMENT) return G_SOURCE_CONTINUE;
|
||||
const GstStructure* structure = gst_message_get_structure(message);
|
||||
if (!structure || !gst_structure_has_name(structure, "level")) return G_SOURCE_CONTINUE;
|
||||
const GValue* rms = gst_structure_get_value(structure, "rms");
|
||||
if (!rms || !GST_VALUE_HOLDS_LIST(rms)) return G_SOURCE_CONTINUE;
|
||||
|
||||
auto* app = static_cast<App*>(data);
|
||||
for (guint index = 0; index < gst_value_list_get_size(rms); ++index) {
|
||||
const GValue* channel = gst_value_list_get_value(rms, index);
|
||||
if (G_VALUE_HOLDS_DOUBLE(channel) && g_value_get_double(channel) > kSoundThresholdDb) {
|
||||
app->last_sound_us = g_get_monotonic_time();
|
||||
break;
|
||||
}
|
||||
}
|
||||
return G_SOURCE_CONTINUE;
|
||||
}
|
||||
|
||||
gboolean detect_silence(gpointer data) {
|
||||
auto* app = static_cast<App*>(data);
|
||||
if (!app->pipeline) {
|
||||
app->silence_source = 0;
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
if (g_get_monotonic_time() - app->last_sound_us < kSilenceTimeoutUs)
|
||||
return G_SOURCE_CONTINUE;
|
||||
|
||||
app->silence_source = 0;
|
||||
stop_recording(nullptr, app);
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
void remove_recording_sources(App* app) {
|
||||
void stop_elapsed_timer(App* app) {
|
||||
if (app->elapsed_source) {
|
||||
g_source_remove(app->elapsed_source);
|
||||
app->elapsed_source = 0;
|
||||
}
|
||||
if (app->silence_source) {
|
||||
g_source_remove(app->silence_source);
|
||||
app->silence_source = 0;
|
||||
}
|
||||
if (app->level_watch) {
|
||||
g_source_remove(app->level_watch);
|
||||
app->level_watch = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void remove_recording(App* app) {
|
||||
@@ -347,7 +300,7 @@ void remove_recording(App* app) {
|
||||
}
|
||||
|
||||
void close_recorder(App* app) {
|
||||
remove_recording_sources(app);
|
||||
stop_elapsed_timer(app);
|
||||
if (app->pipeline) {
|
||||
gst_element_set_state(app->pipeline, GST_STATE_NULL);
|
||||
gst_object_unref(app->pipeline);
|
||||
@@ -557,7 +510,7 @@ void show_processing(App* app) {
|
||||
void stop_recording(GtkButton*, gpointer data) {
|
||||
auto* app = static_cast<App*>(data);
|
||||
if (!app->pipeline) return;
|
||||
remove_recording_sources(app);
|
||||
stop_elapsed_timer(app);
|
||||
gst_element_send_event(app->pipeline, gst_event_new_eos());
|
||||
GstBus* bus = gst_element_get_bus(app->pipeline);
|
||||
GstMessage* message = gst_bus_timed_pop_filtered(bus, 3 * GST_SECOND,
|
||||
@@ -585,7 +538,7 @@ void cancel_recording(GtkButton*, gpointer data) {
|
||||
void recorder_closed(GtkWidget*, gpointer data) {
|
||||
auto* app = static_cast<App*>(data);
|
||||
app->recorder = nullptr;
|
||||
remove_recording_sources(app);
|
||||
stop_elapsed_timer(app);
|
||||
if (app->pipeline) {
|
||||
gst_element_set_state(app->pipeline, GST_STATE_NULL);
|
||||
gst_object_unref(app->pipeline);
|
||||
@@ -595,7 +548,14 @@ void recorder_closed(GtkWidget*, gpointer data) {
|
||||
}
|
||||
|
||||
void start_recording(App* app) {
|
||||
if (app->recorder) { gtk_window_present(GTK_WINDOW(app->recorder)); return; }
|
||||
if (app->recorder) {
|
||||
stop_recording(nullptr, app);
|
||||
return;
|
||||
}
|
||||
if (app->processing) {
|
||||
gtk_window_present(GTK_WINDOW(app->processing));
|
||||
return;
|
||||
}
|
||||
if (app->config.local_url.empty() && (!app->config.hosted_first || app->config.hosted_url.empty())) {
|
||||
open_settings(app);
|
||||
show_error(GTK_WINDOW(app->settings), "Set an endpoint first.");
|
||||
@@ -608,8 +568,7 @@ void start_recording(App* app) {
|
||||
app->recording_path = template_path;
|
||||
g_free(template_path);
|
||||
gchar* pipeline_text = g_strdup_printf(
|
||||
"autoaudiosrc ! audioconvert ! audioresample ! "
|
||||
"level interval=100000000 post-messages=true ! wavenc ! filesink location=\"%s\"",
|
||||
"autoaudiosrc ! audioconvert ! audioresample ! wavenc ! filesink location=\"%s\"",
|
||||
app->recording_path.c_str());
|
||||
GError* error = nullptr;
|
||||
app->pipeline = gst_parse_launch(pipeline_text, &error);
|
||||
@@ -620,9 +579,6 @@ void start_recording(App* app) {
|
||||
remove_recording(app);
|
||||
return;
|
||||
}
|
||||
GstBus* level_bus = gst_element_get_bus(app->pipeline);
|
||||
app->level_watch = gst_bus_add_watch(level_bus, monitor_audio_level, app);
|
||||
gst_object_unref(level_bus);
|
||||
if (gst_element_set_state(app->pipeline, GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE) {
|
||||
show_error(nullptr, "Could not access an audio input.");
|
||||
close_recorder(app);
|
||||
@@ -659,9 +615,7 @@ void start_recording(App* app) {
|
||||
gtk_box_pack_start(GTK_BOX(actions), cancel, false, false, 0);
|
||||
gtk_box_pack_start(GTK_BOX(actions), stop, false, false, 0);
|
||||
app->elapsed_seconds = 0;
|
||||
app->last_sound_us = g_get_monotonic_time();
|
||||
app->elapsed_source = g_timeout_add_seconds(1, tick_elapsed, app);
|
||||
app->silence_source = g_timeout_add(100, detect_silence, app);
|
||||
g_signal_connect(cancel, "clicked", G_CALLBACK(cancel_recording), app);
|
||||
g_signal_connect(stop, "clicked", G_CALLBACK(stop_recording), app);
|
||||
g_signal_connect(window, "destroy", G_CALLBACK(recorder_closed), app);
|
||||
|
||||
Reference in new issue
Block a user