Integration of MultiFileRecorder in UI for sequence creation

This commit is contained in:
Bruno Herbelin
2022-07-04 00:07:23 +02:00
parent af009e03a0
commit 85194c7f4f
6 changed files with 235 additions and 104 deletions

View File

@@ -87,6 +87,7 @@ using namespace std;
#include "NetworkSource.h"
#include "SrtReceiverSource.h"
#include "StreamSource.h"
#include "MultiFileSource.h"
#include "PickingVisitor.h"
#include "ImageFilter.h"
#include "ImageShader.h"
@@ -104,6 +105,7 @@ TextEditor _editor;
#define LABEL_AUTO_MEDIA_PLAYER ICON_FA_CARET_SQUARE_RIGHT " Dynamic selection"
#define LABEL_STORE_SELECTION " Store selection"
#define LABEL_EDIT_FADING ICON_FA_RANDOM " Fade in & out"
#define LABEL_VIDEO_SEQUENCE " Encode an image sequence"
// utility functions
void ShowAboutGStreamer(bool* p_open);
@@ -6219,7 +6221,7 @@ void Navigator::RenderNewPannel()
// News Source selection pannel
//
static const char* origin_names[SOURCE_TYPES] = { ICON_FA_PHOTO_VIDEO " File",
ICON_FA_SORT_NUMERIC_DOWN " Sequence",
ICON_FA_IMAGES " Sequence",
ICON_FA_PLUG " Connected",
ICON_FA_COG " Generated",
ICON_FA_SYNC " Internal"
@@ -6237,7 +6239,7 @@ void Navigator::RenderNewPannel()
static DialogToolkit::OpenFolderDialog folderimportdialog("Select Folder");
// clic button to load file
if ( ImGui::Button( ICON_FA_FILE_EXPORT " Open File", ImVec2(ImGui::GetContentRegionAvail().x IMGUI_RIGHT_ALIGN, 0)) )
if ( ImGui::Button( ICON_FA_FOLDER_OPEN " Open File", ImVec2(ImGui::GetContentRegionAvail().x IMGUI_RIGHT_ALIGN, 0)) )
fileimportdialog.open();
// Indication
ImGui::SameLine();
@@ -6424,62 +6426,126 @@ void Navigator::RenderNewPannel()
// Folder Source creator
else if (Settings::application.source.new_type == SOURCE_SEQUENCE){
bool update_new_source = false;
static DialogToolkit::MultipleImagesDialog _selectImagesDialog("Select Images");
//static bool _create_video_sequence = false;
static DialogToolkit::MultipleImagesDialog _selectImagesDialog("Select multiple images");
static MultiFileSequence _numbered_sequence;
static MultiFileRecorder _video_recorder;
static int _fps = 25;
// clic button to load file
if ( ImGui::Button( ICON_FA_IMAGES " Open images", ImVec2(ImGui::GetContentRegionAvail().x IMGUI_RIGHT_ALIGN, 0)) ) {
if ( ImGui::Button( ICON_FA_FOLDER_OPEN " Open images", ImVec2(ImGui::GetContentRegionAvail().x IMGUI_RIGHT_ALIGN, 0)) ) {
sourceSequenceFiles.clear();
_selectImagesDialog.open();
}
// Indication
ImGui::SameLine();
ImGuiToolkit::HelpToolTip("Create a source from a sequence of numbered images.");
ImGuiToolkit::HelpToolTip("Create a source displaying a sequence of images (PNG, JPG, TIF);\n"
ICON_FA_CARET_RIGHT " files numbered consecutively\n"
ICON_FA_CARET_RIGHT " create a video from many images\n");
// return from thread for folder openning
if (_selectImagesDialog.closed()) {
// clear
new_source_preview_.setSource();
// store list of files from dialog
sourceSequenceFiles = _selectImagesDialog.images();
if (sourceSequenceFiles.empty())
Log::Notify("No file selected.");
// ask to reload the preview
update_new_source = true;
// set sequence
_numbered_sequence = MultiFileSequence(sourceSequenceFiles);
// automatically create a MultiFile Source if possible
if (_numbered_sequence.valid()) {
std::string label = BaseToolkit::transliterate( BaseToolkit::common_pattern(sourceSequenceFiles) );
new_source_preview_.setSource( Mixer::manager().createSourceMultifile(sourceSequenceFiles, _fps), label);
}
}
// multiple files selected
if (sourceSequenceFiles.size() > 1) {
// set framerate
static int _fps = 30;
static bool _fps_changed = false;
ImGui::Text("\nCreate image sequence:");
// show info sequence
ImGuiTextBuffer info;
ImGui::PushStyleColor(ImGuiCol_FrameBg, ImVec4(0.14f, 0.14f, 0.14f, 0.9f));
info.appendf("%d %s", (int) sourceSequenceFiles.size(), _numbered_sequence.codec.c_str());
ImGui::SetNextItemWidth(IMGUI_RIGHT_ALIGN);
if ( ImGui::SliderInt("Framerate", &_fps, 1, 30, "%d fps") ) {
_fps_changed = true;
}
// only call for new source after mouse release to avoid repeating call to re-open the stream
else if (_fps_changed && ImGui::IsMouseReleased(ImGuiMouseButton_Left)){
update_new_source = true;
_fps_changed = false;
ImGui::InputText("Images", (char *)info.c_str(), info.size(), ImGuiInputTextFlags_ReadOnly);
info.clear();
if (_numbered_sequence.location.empty())
info.append("Not consecutively numbered");
else
info.appendf("%s", SystemToolkit::base_filename(_numbered_sequence.location).c_str());
ImGui::SetNextItemWidth(IMGUI_RIGHT_ALIGN);
ImGui::InputText("Filenames", (char *)info.c_str(), info.size(), ImGuiInputTextFlags_ReadOnly);
ImGui::PopStyleColor(1);
// offer to open file browser at location
std::string path = SystemToolkit::path_filename(sourceSequenceFiles.front());
std::string label = BaseToolkit::truncated(path, 25);
label = BaseToolkit::transliterate(label);
ImGuiToolkit::ButtonOpenUrl( label.c_str(), path.c_str(), ImVec2(IMGUI_RIGHT_ALIGN, 0) );
ImGui::SameLine(0, IMGUI_SAME_LINE);
ImGui::Text("Folder");
// set framerate
ImGui::SetNextItemWidth(IMGUI_RIGHT_ALIGN);
ImGui::SliderInt("Framerate", &_fps, 1, 30, "%d fps");
if (ImGui::IsItemDeactivatedAfterEdit()){
if (new_source_preview_.filled()) {
std::string label = BaseToolkit::transliterate( BaseToolkit::common_pattern(sourceSequenceFiles) );
new_source_preview_.setSource( Mixer::manager().createSourceMultifile(sourceSequenceFiles, _fps), label);
}
}
if (update_new_source) {
std::string label = BaseToolkit::transliterate( BaseToolkit::common_pattern(sourceSequenceFiles) );
new_source_preview_.setSource( Mixer::manager().createSourceMultifile(sourceSequenceFiles, _fps), label);
ImGui::Spacing();
// Offer to create video from sequence
if ( ImGui::Button( ICON_FA_FILM " Make a video", ImVec2(ImGui::GetContentRegionAvail().x, 0)) ) {
// start video recorder
_video_recorder.setFiles( sourceSequenceFiles );
_video_recorder.setFramerate( _fps );
_video_recorder.setProfile( (VideoRecorder::Profile) Settings::application.record.profile );
_video_recorder.start();
// dialog
ImGui::OpenPopup(LABEL_VIDEO_SEQUENCE);
}
// video recorder finished: inform and open pannel to import video source from recent recordings
if ( _video_recorder.finished() ) {
Log::Notify("Image sequence saved to %s.", _video_recorder.filename().c_str());
if (Settings::application.recentRecordings.load_at_start)
UserInterface::manager().navigator.setNewMedia(Navigator::MEDIA_RECORDING, _video_recorder.filename());
}
else if (ImGui::BeginPopupModal(LABEL_VIDEO_SEQUENCE, NULL, ImGuiWindowFlags_NoResize))
{
ImGui::Spacing();
ImGui::Text("Please wait while the video is being encoded...");
ImGui::Spacing();
ImGui::ProgressBar(_video_recorder.progress());
if (ImGui::Button("Cancel"))
_video_recorder.cancel();
ImGui::EndPopup();
}
}
// single file selected
else if (sourceSequenceFiles.size() > 0) {
ImGui::Text("Single file selected");
if (update_new_source) {
std::string label = BaseToolkit::transliterate( sourceSequenceFiles.front() );
new_source_preview_.setSource( Mixer::manager().createSourceFile(sourceSequenceFiles.front()), label);
}
// open image file as source
std::string label = BaseToolkit::transliterate( sourceSequenceFiles.front() );
new_source_preview_.setSource( Mixer::manager().createSourceFile(sourceSequenceFiles.front()), label);
// done with sequence
sourceSequenceFiles.clear();
}
}
// Internal Source creator
else if (Settings::application.source.new_type == SOURCE_INTERNAL){