spacebox/src/Recorder.hpp

110 lines
3.2 KiB
C++

/* ✨ +------------------------------------------------------+
____/ \____ ✨/| Open source game framework licensed to freely use, |
✨\ / / | copy, and modify. Created for 🌠dank.game🌠 |
+--\ . . /--+ | |
| ~/ ︶ \👍| | 🌐 https://open.shampoo.ooo/shampoo/spacebox |
| ~~~🌊~~~~🌊~ | +------------------------------------------------------+
| SPACE 🪐🅱 OX | /
| 🌊 ~ ~~~~ ~~ |/
+-------------*/
#pragma once
#define GLM_ENABLE_EXPERIMENTAL
#include <list>
#include <vector>
#include <sstream>
#include <string>
#include <functional>
#include <cstdlib>
#include <fstream>
#include <thread>
#include "SDL.h"
#include "SDL_mixer.h"
#include "glm/ext.hpp"
#include "json/json.hpp"
#include "filesystem.hpp"
#include "Configuration.hpp"
#include "Animation.hpp"
#include "Log.hpp"
namespace sb
{
struct Stash
{
std::vector<unsigned char*> pixel_buffers;
std::vector<bool> flipped;
std::vector<Uint8*> audio_buffers;
std::vector<int> audio_buffer_lengths;
int frame_offset;
Stash(int frame_offset = 0) : frame_offset(frame_offset) {}
};
class Recorder
{
private:
Stash current_stash = Stash();
Stash most_recent_stash;
std::list<Stash> in_game_stashes;
std::list<Stash> video_stashes;
fs::path current_video_directory, current_audio_path;
bool is_recording = false, writing_recording = false, writing_most_recent = false;
std::ofstream audio_file;
sb::Configuration& configuration;
sb::Display& display;
float frame_length();
static void process_audio(void*, Uint8*, int);
public:
Animation animation = Animation(std::bind(&Recorder::add_frame, this));
Recorder(sb::Configuration& configuration, sb::Display& display);
/*!
* If not recording, start recording. If recording, stop recording.
*
* If a recording is being written, recording will not begin, and a warning will be logged.
*/
void toggle();
/*!
* Save the current screen pixels as a PNG in the path specified by the configuration.
*
* Parent directories in the path will be created if necessary. The file name will be auto generated based on the
* configuration.
*
* An index will be included in the file name, one higher than the highest of previous screenshots found in the output
* directory.
*/
void capture_screen();
void grab_stash();
void write_most_recent_frames();
void start_recording();
void open_audio_file();
void add_frame();
float get_memory_size() const;
/*!
* Write the size of the video memory in MB to the log.
*/
void log_video_memory_size() const;
void make_directory();
void write_stash_frames(Stash*);
void keep_stash();
void end_recording();
void finish_writing_video();
void write_mp4();
void write_audio(Uint8*, int);
void update(float timestamp);
};
};