I have a folder full of images, I need to save these images into the video while doing so I want to show the user the video being played from these images (frames). I can run two separate processes one for the saving and one for the showing but this is not what I am looking for, I want to do both in one step. If you know a solution please let me know.
My code uses C with OpenCV but feel free to share with me any code written with any language, or event a concept.
I use gStreamer, ffmpeg as well for the video generation, so I am not looking how to save a video or how to show the video I am looking for a process that can do both in one operation.
CodePudding user response:
here's my quick brew using SFML. You have to link SFML and include the include folder. Simply set directory
to your target folder, I use std::filesystem
to add all files from that folder to a std::vector<std::string>
.
#include <SFML/Graphics.hpp>
#include <vector>
#include <string>
#include <iostream>
#include <filesystem>
void add_frame_to_video(std::string path) {
//your encoding stuff ...
}
int main() {
auto dimension = sf::VideoMode(1280u, 720u);
sf::RenderWindow window;
window.create(dimension, "Video Rendering");
sf::Texture frame_texture;
std::vector<std::string> frame_paths;
std::string directory = "resources/";
for (auto i : std::filesystem::directory_iterator(directory)) {
frame_paths.push_back({ i.path().string() });
}
std::size_t frame_ctr = 0u;
while (window.isOpen()) {
sf::Event event;
while (window.pollEvent(event)) {
if (event.type == sf::Event::Closed) {
window.close();
}
}
if (frame_ctr >= frame_paths.size()) {
window.close();
return EXIT_FAILURE;
}
const auto& current_frame = frame_paths[frame_ctr];
add_frame_to_video(current_frame);
if (!frame_texture.loadFromFile(current_frame)) {
std::cout << "Error: couldn't load file \"" << current_frame << "\".\n";
window.close();
return EXIT_FAILURE;
}
sf::Sprite frame_sprite;
frame_sprite.setTexture(frame_texture);
frame_ctr;
window.clear();
window.draw(frame_sprite);
window.display();
}
}
this will create a window that shows each picture per frame using sf::Texture
to load and sf::Sprite
to display the image. If no more frames are available, the window gets closed and the program terminates. If you want to add time between frames, you can set e.g. window.setFramerateLimit(10);
to have 10 frames / second.