aboutsummaryrefslogtreecommitdiff
path: root/src/FileAnalyzer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/FileAnalyzer.cpp')
-rw-r--r--src/FileAnalyzer.cpp60
1 files changed, 53 insertions, 7 deletions
diff --git a/src/FileAnalyzer.cpp b/src/FileAnalyzer.cpp
index b397def..ccad221 100644
--- a/src/FileAnalyzer.cpp
+++ b/src/FileAnalyzer.cpp
@@ -1,4 +1,5 @@
#include "../include/FileAnalyzer.hpp"
+#include "../include/AsyncImageLoader.hpp"
#include "../include/Program.hpp"
#include <sys/stat.h>
#include <stdio.h>
@@ -20,14 +21,16 @@ namespace QuickMedia {
// What about audio ogg files that are not opus?
// TODO: Test all of these
- static const std::array<MagicNumber, 23> magic_numbers = {
+ static const std::array<MagicNumber, 25> 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', 'm', 'p', '4', '2'}, 12, 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', 'm', 'p', '4', '2'}, 11, ContentType::VIDEO_MP4 },
MagicNumber{ {0x00, 0x00, 0x00, -1, 'f', 't', 'y', '3', 'g', 'p', '5'}, 11, ContentType::VIDEO_MP4 },
MagicNumber{ {0x00, 0x00, 0x00, -1, 'f', 't', 'y', 'p', 'q', 't'}, 10, ContentType::VIDEO_MP4 },
MagicNumber{ {0x1A, 0x45, 0xDF, 0xA3}, 4, ContentType::VIDEO_WEBM },
+ MagicNumber{ {'F', 'L', 'V', 0x01}, 4, ContentType::VIDEO_FLV },
MagicNumber{ {'.', 's', 'n', 'd'}, 4, ContentType::AUDIO_BASIC },
MagicNumber{ {'F', 'O', 'R', 'M', -1, -1, -1, -1, 'A', 'I', 'F', 'F'}, 12, ContentType::AUDIO_AIFF },
MagicNumber{ { 'I', 'D', '3' }, 3, ContentType::AUDIO_MPEG },
@@ -48,7 +51,7 @@ namespace QuickMedia {
};
bool is_content_type_video(ContentType content_type) {
- return content_type >= ContentType::VIDEO_AVI && content_type <= ContentType::VIDEO_WEBM;
+ return content_type >= ContentType::VIDEO_AVI && content_type <= ContentType::VIDEO_FLV;
}
bool is_content_type_audio(ContentType content_type) {
@@ -65,6 +68,7 @@ namespace QuickMedia {
case ContentType::VIDEO_AVI: return "video/avi";
case ContentType::VIDEO_MP4: return "video/mp4";
case ContentType::VIDEO_WEBM: return "video/webm";
+ case ContentType::VIDEO_FLV: return "video/x-flv";
case ContentType::AUDIO_BASIC: return "audio/basic";
case ContentType::AUDIO_AIFF: return "audio/aiff";
case ContentType::AUDIO_MPEG: return "audio/mpeg";
@@ -81,20 +85,57 @@ namespace QuickMedia {
return "application/octet-stream";
}
+ bool is_image_ext(const char *ext) {
+ return strcasecmp(ext, ".jpg") == 0
+ || strcasecmp(ext, ".jpeg") == 0
+ || strcasecmp(ext, ".png") == 0
+ || strcasecmp(ext, ".gif") == 0
+ || strcasecmp(ext, ".webp") == 0;
+ }
+
+ bool is_video_ext(const char *ext) {
+ return strcasecmp(ext, ".webm") == 0
+ || strcasecmp(ext, ".mkv") == 0
+ || strcasecmp(ext, ".flv") == 0
+ || strcasecmp(ext, ".vob") == 0
+ || strcasecmp(ext, ".ogv") == 0
+ || strcasecmp(ext, ".avi") == 0
+ //|| strcasecmp(ext, ".ts") == 0
+ || strcasecmp(ext, ".mov") == 0
+ || strcasecmp(ext, ".qt") == 0
+ || strcasecmp(ext, ".wmv") == 0
+ || strcasecmp(ext, ".mp4") == 0
+ || strcasecmp(ext, ".m4v") == 0
+ || strcasecmp(ext, ".mpg") == 0
+ || strcasecmp(ext, ".mpeg") == 0
+ || strcasecmp(ext, ".3gp") == 0;
+ }
+
static int accumulate_string(char *data, int size, void *userdata) {
std::string *str = (std::string*)userdata;
str->append(data, size);
return 0;
}
- bool video_get_first_frame(const char *filepath, const char *destination_path) {
- const char *program_args[] = { "ffmpeg", "-y", "-v", "quiet", "-i", filepath, "-vframes", "1", "-f", "singlejpeg", destination_path, nullptr };
+ bool video_get_first_frame(const char *filepath, const char *destination_path, int width, int height) {
+ Path destination_path_tmp = destination_path;
+ destination_path_tmp.append(".ftmp");
+
+ const char *program_args[] = { "ffmpeg", "-y", "-v", "quiet", "-i", filepath, "-vframes", "1", "-f", "singlejpeg", destination_path_tmp.data.c_str(), nullptr };
std::string ffmpeg_result;
if(exec_program(program_args, nullptr, nullptr) != 0) {
fprintf(stderr, "Failed to execute ffmpeg, maybe its not installed?\n");
return false;
}
- return true;
+
+ if(width > 0 || height > 0) {
+ if(create_thumbnail(destination_path_tmp, destination_path, sf::Vector2i(width, height))) {
+ remove(destination_path_tmp.data.c_str());
+ return true;
+ }
+ }
+
+ return rename(destination_path_tmp.data.c_str(), destination_path) == 0;
}
// TODO: Remove dependency on ffprobe
@@ -154,7 +195,7 @@ namespace QuickMedia {
}
- bool FileAnalyzer::load_file(const char *filepath) {
+ bool FileAnalyzer::load_file(const char *filepath, bool load_file_metadata) {
if(loaded) {
fprintf(stderr, "File already loaded\n");
return false;
@@ -182,6 +223,11 @@ namespace QuickMedia {
unsigned char magic_number_buffer[MAGIC_NUMBER_BUFFER_SIZE];
size_t num_bytes_read = fread(magic_number_buffer, 1, sizeof(magic_number_buffer), file);
+ if(feof(file)) {
+ perror(filepath);
+ fclose(file);
+ return false;
+ }
fclose(file);
for(const MagicNumber &magic_number : magic_numbers) {
@@ -200,7 +246,7 @@ namespace QuickMedia {
}
}
- if(content_type != ContentType::UNKNOWN) {
+ if(load_file_metadata && content_type != ContentType::UNKNOWN) {
if(!ffprobe_extract_metadata(filepath, dimensions, duration_seconds)) {
// This is not an error, matrix allows files to be uploaded without metadata
fprintf(stderr, "Failed to extract metadata from file: %s, is ffprobe not installed?\n", filepath);