📄 gui_main.cpp
字号:
}}/* * 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; if (stat(MyConfig->GetStringValue(CONFIG_RECORD_MP4_FILE_NAME), &stats) == 0) { uint64_t size = stats.st_size; size /= 1000000LLU; snprintf(buffer, sizeof(buffer), " %llu", size); } else { snprintf(buffer, sizeof(buffer), "BAD"); } 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->IsFileVideoSource() && MyConfig->IsFileAudioSource() && !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){ gtk_spin_button_update(GTK_SPIN_BUTTON(duration_spinner)); 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(); const 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){ const 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, FALSE, FALSE, 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); // picture controls button picture_settings_button = gtk_button_new_with_label(" Picture... "); gtk_box_pack_start(GTK_BOX(hbox), picture_settings_button, FALSE, FALSE, 5); gtk_signal_connect(GTK_OBJECT(picture_settings_button), "clicked", GTK_SIGNAL_FUNC(on_picture_settings_button), NULL); gtk_widget_show(picture_settings_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);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -