📄 gui_main.cpp
字号:
gtk_widget_show(final_size);
gtk_label_set_text(GTK_LABEL(final_size_units), "MB");
gtk_widget_show(final_size_units);
}
}
/*
* Status timer routine
*/
static gint status_timer (gpointer raw)
{
time_t secs;
const struct tm *local;
char buffer[80];
Timestamp now = GetTimestamp();
secs = (time_t)GetSecsFromTimestamp(now);
local = localtime(&secs);
strftime(buffer, sizeof(buffer), "%l:%M:%S", local);
gtk_label_set_text(GTK_LABEL(current_time), buffer);
gtk_widget_show(current_time);
strftime(buffer, sizeof(buffer), "%p", local);
gtk_label_set_text(GTK_LABEL(current_time_units), buffer);
gtk_widget_show(current_time);
time_t duration_secs = (time_t)GetSecsFromTimestamp(now - StartTime);
snprintf(buffer, sizeof(buffer), "%lu:%02lu:%02lu",
duration_secs / 3600, (duration_secs % 3600) / 60, duration_secs % 60);
gtk_label_set_text(GTK_LABEL(duration), buffer);
gtk_widget_show(duration);
if (MyConfig->GetBoolValue(CONFIG_RECORD_ENABLE)) {
struct stat stats;
stat(MyConfig->GetStringValue(CONFIG_RECORD_MP4_FILE_NAME), &stats);
snprintf(buffer, sizeof(buffer), " %lu", stats.st_size / 1000000);
gtk_label_set_text(GTK_LABEL(current_size), buffer);
gtk_widget_show(current_size);
}
if (!StopTime) {
float progress;
AVFlow->GetStatus(FLOW_STATUS_PROGRESS, &progress);
if (progress > 0.0) {
u_int32_t estDuration = (u_int32_t)(duration_secs / progress);
DisplayFinishTime(StartTime + (estDuration * TimestampTicks));
}
}
if (MyConfig->GetBoolValue(CONFIG_VIDEO_ENABLE)) {
u_int32_t encodedFrames;
AVFlow->GetStatus(FLOW_STATUS_VIDEO_ENCODED_FRAMES, &encodedFrames);
u_int32_t totalFrames = encodedFrames - StartEncodedFrameNumber;
snprintf(buffer, sizeof(buffer), " %.2f",
((float)totalFrames / (float)(now - StartTime)) * TimestampTicks);
gtk_label_set_text(GTK_LABEL(actual_fps), buffer);
gtk_widget_show(actual_fps);
gtk_label_set_text(GTK_LABEL(actual_fps_units), "fps");
gtk_widget_show(actual_fps_units);
}
bool stop = false;
if (StopTime) {
stop = (now >= StopTime);
}
if (!stop && duration_secs > 10) {
AVFlow->GetStatus(FLOW_STATUS_DONE, &stop);
}
if (!stop) {
Duration elapsedDuration;
if (AVFlow->GetStatus(FLOW_STATUS_DURATION, &elapsedDuration)) {
if (elapsedDuration >= FlowDuration) {
stop = true;
}
}
}
if (stop) {
// automatically "press" stop button
DoStop();
if (MyConfig->m_appAutomatic) {
// In automatic mode, time to exit app
gtk_main_quit();
} else {
// Make sure user knows that were done
char *notice;
if (MyConfig->GetBoolValue(CONFIG_RECORD_ENABLE)
&& MyConfig->GetBoolValue(CONFIG_RTP_ENABLE)) {
notice = "Recording and transmission completed";
} else if (MyConfig->GetBoolValue(CONFIG_RTP_ENABLE)) {
notice = "Transmission completed";
} else {
notice = "Recording completed";
}
ShowMessage("Completed", notice);
}
return (FALSE);
}
return (TRUE); // keep timer going
}
void DoStart()
{
if (!MyConfig->GetBoolValue(CONFIG_AUDIO_ENABLE)
&& !MyConfig->GetBoolValue(CONFIG_VIDEO_ENABLE)) {
ShowMessage("No Media", "Neither audio nor video are enabled");
return;
}
// lock out change to settings while media is running
LockoutChanges(true);
AVFlow->Start();
StartTime = GetTimestamp();
if (MyConfig->GetBoolValue(CONFIG_VIDEO_ENABLE)) {
if (MyConfig->IsCaptureVideoSource()) {
AVFlow->GetStatus(FLOW_STATUS_VIDEO_ENCODED_FRAMES,
&StartEncodedFrameNumber);
} else {
StartEncodedFrameNumber = 0;
}
}
FlowDuration =
gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(duration_spinner))
* durationUnitsValues[durationUnitsIndex] * TimestampTicks;
if (!MyConfig->IsCaptureVideoSource() && !MyConfig->IsCaptureAudioSource()
&& !MyConfig->GetBoolValue(CONFIG_RTP_ENABLE)) {
// no real time constraints
StopTime = 0;
} else {
StopTime = StartTime + FlowDuration;
}
status_start();
gtk_label_set_text(GTK_LABEL(start_button_label), " Stop ");
status_timer_id = gtk_timeout_add(1000, status_timer, main_window);
started = true;
}
void DoStop()
{
gtk_timeout_remove(status_timer_id);
if (MyConfig->GetBoolValue(CONFIG_RECORD_ENABLE)) {
char* notice = "CLOSING";
if (MyConfig->GetBoolValue(CONFIG_RECORD_MP4_HINT_TRACKS)) {
notice = "HINTING";
}
// borrow finish time field
gtk_label_set_text(GTK_LABEL(finish_time), notice);
gtk_widget_show_now(finish_time);
gtk_label_set_text(GTK_LABEL(finish_time_units), "");
gtk_widget_show_now(finish_time_units);
}
AVFlow->Stop();
if (MyConfig->GetBoolValue(CONFIG_RECORD_ENABLE)) {
DisplayFinishTime(GetTimestamp());
}
// unlock changes to settings
LockoutChanges(false);
gtk_label_set_text(GTK_LABEL(start_button_label), " Start ");
started = false;
}
static void on_start_button (GtkWidget *widget, gpointer *data)
{
if (!started) {
DoStart();
} else {
DoStop();
}
}
static void on_duration_changed(GtkWidget* widget, gpointer* data)
{
MyConfig->SetIntegerValue(CONFIG_APP_DURATION,
gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(duration_spinner)));
MyConfig->UpdateRecord();
}
static void on_duration_units_menu_activate(GtkWidget *widget, gpointer data)
{
durationUnitsIndex = (unsigned int)data & 0xFF;;
MyConfig->SetIntegerValue(CONFIG_APP_DURATION_UNITS,
durationUnitsValues[durationUnitsIndex]);
MyConfig->UpdateRecord();
}
static void LoadConfig()
{
AVFlow->StopVideoPreview();
char* configFileName =
gtk_entry_get_text(GTK_ENTRY(config_file_entry));
MyConfig->ReadFromFile(configFileName);
MyConfig->Update();
DisplayAllSettings();
NewVideoWindow();
// restart video source
if (MyConfig->GetBoolValue(CONFIG_VIDEO_ENABLE)) {
AVFlow->StartVideoPreview();
}
}
static void on_load_config_button (GtkWidget *widget, gpointer *data)
{
FileBrowser(config_file_entry, GTK_SIGNAL_FUNC(LoadConfig));
}
static void on_save_config_button (GtkWidget *widget, gpointer *data)
{
char* configFileName =
gtk_entry_get_text(GTK_ENTRY(config_file_entry));
MyConfig->WriteToFile(configFileName);
char notice[512];
sprintf(notice,
"Current configuration saved to %s", configFileName);
ShowMessage("Configuration Saved", notice);
}
static gfloat frameLabelAlignment = 0.025;
static void LayoutVideoFrame(GtkWidget* box)
{
GtkWidget *frame;
GtkWidget *vbox, *hbox, *vbox1, *vbox2;
GtkWidget *label;
frame = gtk_frame_new("Video");
gtk_frame_set_label_align(GTK_FRAME(frame), frameLabelAlignment, 0);
gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_ETCHED_IN);
gtk_box_pack_start(GTK_BOX(box), frame, TRUE, TRUE, 5);
vbox = gtk_vbox_new(FALSE, 1);
gtk_widget_show(vbox);
// create first row
hbox = gtk_hbox_new(FALSE, 1);
gtk_widget_show(hbox);
gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 5);
// enabled button
video_enabled_button = gtk_check_button_new_with_label("Enabled");
gtk_box_pack_start(GTK_BOX(hbox), video_enabled_button, TRUE, TRUE, 5);
gtk_signal_connect(GTK_OBJECT(video_enabled_button),
"toggled",
GTK_SIGNAL_FUNC(on_video_enabled_button),
NULL);
gtk_widget_show(video_enabled_button);
// create second row
hbox = gtk_hbox_new(FALSE, 1);
gtk_widget_show(hbox);
gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 5);
// preview label
label = gtk_label_new(" Preview:");
gtk_widget_show(label);
gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 5);
// none preview radio button
video_none_preview_button = gtk_radio_button_new_with_label(NULL, "None");
gtk_widget_show(video_none_preview_button);
gtk_box_pack_start(GTK_BOX(hbox), video_none_preview_button,
FALSE, FALSE, 0);
// raw preview radio button
video_preview_radio_group =
gtk_radio_button_group(GTK_RADIO_BUTTON(video_none_preview_button));
video_raw_preview_button =
gtk_radio_button_new_with_label(video_preview_radio_group, "Raw");
gtk_widget_show(video_raw_preview_button);
gtk_box_pack_start(GTK_BOX(hbox), video_raw_preview_button,
FALSE, FALSE, 0);
// encoded preview radio button
video_preview_radio_group =
gtk_radio_button_group(GTK_RADIO_BUTTON(video_none_preview_button));
video_encoded_preview_button =
gtk_radio_button_new_with_label(video_preview_radio_group, "Encoded");
gtk_widget_show(video_encoded_preview_button);
gtk_box_pack_start(GTK_BOX(hbox), video_encoded_preview_button,
FALSE, FALSE, 0);
gtk_signal_connect(GTK_OBJECT(video_none_preview_button),
"toggled",
GTK_SIGNAL_FUNC(on_video_preview_button),
NULL);
gtk_signal_connect(GTK_OBJECT(video_raw_preview_button),
"toggled",
GTK_SIGNAL_FUNC(on_video_preview_button),
NULL);
gtk_signal_connect(GTK_OBJECT(video_encoded_preview_button),
"toggled",
GTK_SIGNAL_FUNC(on_video_preview_button),
NULL);
// create third row
hbox = gtk_hbox_new(FALSE, 1);
gtk_widget_show(hbox);
gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 5);
// secondary vbox for two labels
vbox1 = gtk_vbox_new(FALSE, 1);
gtk_widget_show(vbox1);
gtk_box_pack_start(GTK_BOX(hbox), vbox1, TRUE, TRUE, 5);
video_settings_label1 = gtk_label_new("");
gtk_misc_set_alignment(GTK_MISC(video_settings_label1), 0.0, 0.5);
gtk_box_pack_start(GTK_BOX(vbox1), video_settings_label1, TRUE, TRUE, 0);
video_settings_label2 = gtk_label_new("");
gtk_misc_set_alignment(GTK_MISC(video_settings_label2), 0.0, 0.5);
gtk_box_pack_start(GTK_BOX(vbox1), video_settings_label2, TRUE, TRUE, 0);
// secondary vbox to match stacked labels
vbox2 = gtk_vbox_new(FALSE, 1);
gtk_widget_show(vbox2);
gtk_box_pack_start(GTK_BOX(hbox), vbox2, FALSE, FALSE, 5);
// settings button
video_settings_button = gtk_button_new_with_label(" Settings... ");
gtk_box_pack_start(GTK_BOX(vbox2), video_settings_button, FALSE, FALSE, 5);
gtk_signal_connect(GTK_OBJECT(video_settings_button),
"clicked",
GTK_SIGNAL_FUNC(on_video_settings_button),
NULL);
gtk_widget_show(video_settings_button);
// empty label to get sizing correct
video_settings_label3 = gtk_label_new("");
gtk_box_pack_start(GTK_BOX(vbox2), video_settings_label3, TRUE, TRUE, 0);
gtk_container_add(GTK_CONTAINER(frame), vbox);
gtk_widget_show(frame);
}
static void LayoutAudioFrame(GtkWidget* box)
{
GtkWidget *frame;
GtkWidget *vbox, *hbox, *vbox1, *vbox2;
frame = gtk_frame_new("Audio");
gtk_frame_set_label_align(GTK_FRAME(frame), frameLabelAlignment, 0);
gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_ETCHED_IN);
gtk_box_pack_start(GTK_BOX(box), frame, TRUE, TRUE, 5);
vbox = gtk_vbox_new(FALSE, 1);
gtk_widget_show(vbox);
// create first row, homogenous
hbox = gtk_hbox_new(TRUE, 1);
gtk_widget_show(hbox);
gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 5);
// enabled button
audio_enabled_button = gtk_check_button_new_with_label("Enabled");
gtk_box_pack_start(GTK_BOX(hbox), audio_enabled_button, TRUE, TRUE, 5);
gtk_signal_connect(GTK_OBJECT(audio_enabled_button),
"toggled",
GTK_SIGNAL_FUNC(on_audio_enabled_button),
NULL);
gtk_widget_show(audio_enabled_button);
// mute button
audio_mute_button = gtk_check_button_new_with_label("Mute");
gtk_box_pack_start(GTK_BOX(hbox), audio_mute_button, TRUE, TRUE, 5);
gtk_signal_connect(GTK_OBJECT(audio_mute_button),
"toggled",
GTK_SIGNAL_FUNC(on_audio_mute_button),
NULL);
gtk_widget_show(audio_mute_button);
// create second row
hbox = gtk_hbox_new(FALSE, 1);
gtk_widget_show(hbox);
gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 5);
// settings summary
// secondary vbox for two labels
vbox1 = gtk_vbox_new(FALSE, 1);
gtk_widget_show(vbox1);
gtk_box_pack_start(GTK_BOX(hbox), vbox1, TRUE, TRUE, 5);
audio_settings_label1 = gtk_label_new("");
gtk_misc_set_alignment(GTK_MISC(audio_settings_label1), 0.0, 0.5);
gtk_widget_show(audio_settings_label1);
gtk_box_pack_start(GTK_BOX(vbox1), audio_settings_label1, TRUE, TRUE, 0);
audio_settings_label2 = gtk_label_new("");
gtk_misc_set_alignment(GTK_MISC(audio_settings_label2), 0.0, 0.5);
gtk_widget_show(audio_settings_label2);
gtk_box_pack_start(GTK_BOX(vbox1), audio_settings_label2, TRUE, TRUE, 0);
// secondary vbox to match stacked labels
vbox2 = gtk_vbox_new(FALSE, 1);
gtk_widget_show(vbox2);
gtk_box_pack_start(GTK_BOX(hbox), vbox2, FALSE, FALSE, 5);
// settings button
audio_settings_button = gtk_button_new_with_label(" Settings... ");
gtk_box_pack_start(GTK_BOX(vbox2), audio_settings_button, FALSE, FALSE, 5);
gtk_signal_connect(GTK_OBJECT(audio_settings_button),
"clicked",
GTK_SIGNAL_FUNC(on_audio_settings_button),
NULL);
gtk_widget_show(audio_settings_button);
// empty label to get sizing correct
audio_settings_label3 = gtk_label_new("");
gtk_box_pack_start(GTK_BOX(vbox2), audio_settings_label3, TRUE, TRUE, 0);
// finalize
gtk_container_add(GTK_CONTAINER(frame), vbox);
gtk_widget_show(frame);
}
static void LayoutRecordingFrame(GtkWidget* box)
{
GtkWidget *frame;
GtkWidget *vbox, *hbox;
frame = gtk_frame_new("Recording");
gtk_frame_set_label_align(GTK_FRAME(frame), frameLabelAlignment, 0);
gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_ETCHED_IN);
gtk_box_pack_start(GTK_BOX(box), frame, TRUE, TRUE, 5);
vbox = gtk_vbox_new(FALSE, 1);
gtk_widget_show(vbox);
// create first row, homogenous
hbox = gtk_hbox_new(TRUE, 1);
gtk_widget_show(hbox);
gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 5);
// enabled button
record_enabled_button = gtk_check_button_new_with_label("Enabled");
gtk_box_pack_start(GTK_BOX(hbox), record_enabled_button, TRUE, TRUE, 5);
gtk_signal_connect(GTK_OBJECT(record_enabled_button),
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -