diff options
Diffstat (limited to 'src/FileAnalyzer.cpp')
-rw-r--r-- | src/FileAnalyzer.cpp | 60 |
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); |