aboutsummaryrefslogtreecommitdiff
path: root/src/FileAnalyzer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/FileAnalyzer.cpp')
-rw-r--r--src/FileAnalyzer.cpp32
1 files changed, 22 insertions, 10 deletions
diff --git a/src/FileAnalyzer.cpp b/src/FileAnalyzer.cpp
index 361211f..61eff7b 100644
--- a/src/FileAnalyzer.cpp
+++ b/src/FileAnalyzer.cpp
@@ -21,10 +21,12 @@ namespace QuickMedia {
// https://mimesniff.spec.whatwg.org/
// TODO: Test all of these
- static const std::array<MagicNumber, 31> magic_numbers = {
+ static const std::array<MagicNumber, 33> magic_numbers = {
MagicNumber{ {'R', 'I', 'F', 'F', -1, -1, -1, -1, 'A', 'V', 'I', ' '}, 12, ContentType::VIDEO_AVI },
MagicNumber{ {0x00, 0x00, 0x00, -1, 'f', 't', 'y', 'p', 'i', 's', 'o', 'm'}, 12, ContentType::VIDEO_MP4 },
+ MagicNumber{ {0x00, 0x00, 0x00, -1, 'f', 't', 'y', 'p', 'i', 's', 'o', '5'}, 12, ContentType::VIDEO_MP4 },
MagicNumber{ {0x00, 0x00, 0x00, -1, 'f', 't', 'y', 'p', 'm', 'p', '4', '2'}, 12, ContentType::VIDEO_MP4 },
+ MagicNumber{ {0x00, 0x00, 0x00, -1, 'f', 't', 'y', 'p', 'M', '4', 'V'}, 11, ContentType::VIDEO_MP4 },
MagicNumber{ {0x00, 0x00, 0x00, -1, 'f', 't', 'y', 'p', '3', 'g', 'p', '4'}, 12, ContentType::VIDEO_MP4 },
MagicNumber{ {0x00, 0x00, 0x00, -1, 'f', 't', 'y', 'p', '3', 'g', 'p', '5'}, 12, ContentType::VIDEO_MP4 },
MagicNumber{ {0x00, 0x00, 0x00, -1, 'f', 't', 'y', 'm', 'p', '4', '2'}, 11, ContentType::VIDEO_MP4 },
@@ -136,29 +138,29 @@ namespace QuickMedia {
|| strcase_equals(ext, ".wav")
|| strcase_equals(ext, ".wma")
|| strcase_equals(ext, ".mid");
-
}
- bool video_get_middle_frame(const FileAnalyzer &file, const char *destination_path, int width, int height) {
+ bool video_get_frame(const FileAnalyzer &file, const char *destination_path, int width, int height, int seconds) {
Path destination_path_tmp = destination_path;
destination_path_tmp.append(".tmp.jpg"); // TODO: .png, but the below code also needs to be changed for that
- const int middle_seconds = file.get_duration_seconds().value_or(0.0) / 2.0;
- char middle_seconds_str[32];
- snprintf(middle_seconds_str, sizeof(middle_seconds_str), "%d", middle_seconds);
+ char seconds_str[32];
+ snprintf(seconds_str, sizeof(seconds_str), "%d", seconds);
+
+ int allowed_exit_status[] = { 0, 69 };
if(width > 0 && height > 0) {
char size_arg_str[512];
snprintf(size_arg_str, sizeof(size_arg_str), "scale=%d:%d:force_original_aspect_ratio=decrease", width, height);
- const char *program_args[] = { "ffmpeg", "-y", "-v", "quiet", "-ss", middle_seconds_str, "-i", file.get_filepath().c_str(), "-vframes", "1", "-vf", size_arg_str, "--", destination_path_tmp.data.c_str(), nullptr };
- if(exec_program(program_args, nullptr, nullptr) != 0) {
+ const char *program_args[] = { "ffmpeg", "-y", "-v", "quiet", "-ss", seconds_str, "-i", file.get_filepath().c_str(), "-frames:v", "1", "-vf", size_arg_str, "--", destination_path_tmp.data.c_str(), nullptr };
+ if(exec_program(program_args, nullptr, nullptr, allowed_exit_status, 2) != 0) {
fprintf(stderr, "Failed to execute ffmpeg, maybe its not installed?\n");
return false;
}
} else {
- const char *program_args[] = { "ffmpeg", "-y", "-v", "quiet", "-ss", middle_seconds_str, "-i", file.get_filepath().c_str(), "-vframes", "1", "--", destination_path_tmp.data.c_str(), nullptr };
- if(exec_program(program_args, nullptr, nullptr) != 0) {
+ const char *program_args[] = { "ffmpeg", "-y", "-v", "quiet", "-ss", seconds_str, "-i", file.get_filepath().c_str(), "-frames:v", "1", "--", destination_path_tmp.data.c_str(), nullptr };
+ if(exec_program(program_args, nullptr, nullptr, allowed_exit_status, 2) != 0) {
fprintf(stderr, "Failed to execute ffmpeg, maybe its not installed?\n");
return false;
}
@@ -167,6 +169,16 @@ namespace QuickMedia {
return rename_atomic(destination_path_tmp.data.c_str(), destination_path) == 0;
}
+ bool video_get_start_frame(const FileAnalyzer &file, const char *destination_path, int width, int height) {
+ const int start_seconds = std::max(0.0, std::min(3.0, file.get_duration_seconds().value_or(0.0) - 1.0));
+ return video_get_frame(file, destination_path, width, height, start_seconds);
+ }
+
+ bool video_get_middle_frame(const FileAnalyzer &file, const char *destination_path, int width, int height) {
+ const int middle_seconds = file.get_duration_seconds().value_or(0.0) / 2.0;
+ return video_get_frame(file, destination_path, width, height, middle_seconds);
+ }
+
// TODO: Remove dependency on ffprobe
static bool ffprobe_extract_metadata(const char *filepath, std::optional<Dimensions> &dimensions, std::optional<double> &duration_seconds) {
const char *program_args[] = { "ffprobe", "-v", "quiet", "-print_format", "json", "-show_streams", "-show_format", "--", filepath, nullptr };