diff options
author | dec05eba <dec05eba@protonmail.com> | 2023-12-21 18:23:53 +0100 |
---|---|---|
committer | dec05eba <dec05eba@protonmail.com> | 2023-12-21 18:23:53 +0100 |
commit | a257f50a9f752919729bcf3aa3358491ff5edcad (patch) | |
tree | 62225eea968da8688ab1ff9e94ba6355f054ade1 | |
parent | 1a20c29eeba5edfd51068b5bec6ec53af0629d38 (diff) |
Fix thumbnails for broken videos (unable to seek)
-rw-r--r-- | include/FileAnalyzer.hpp | 3 | ||||
-rw-r--r-- | src/FileAnalyzer.cpp | 14 |
2 files changed, 7 insertions, 10 deletions
diff --git a/include/FileAnalyzer.hpp b/include/FileAnalyzer.hpp index 52cc328..47b02d7 100644 --- a/include/FileAnalyzer.hpp +++ b/include/FileAnalyzer.hpp @@ -46,9 +46,6 @@ namespace QuickMedia { // Set |width| or |height| to 0 to disable scaling. // TODO: Make this async - bool video_get_start_frame(const FileAnalyzer &file, const char *destination_path, int width = 0, int height = 0); - // Set |width| or |height| to 0 to disable scaling. - // TODO: Make this async bool video_get_middle_frame(const FileAnalyzer &file, const char *destination_path, int width = 0, int height = 0); class FileAnalyzer { diff --git a/src/FileAnalyzer.cpp b/src/FileAnalyzer.cpp index 9efdc52..4deb8c3 100644 --- a/src/FileAnalyzer.cpp +++ b/src/FileAnalyzer.cpp @@ -144,7 +144,7 @@ namespace QuickMedia { || strcase_equals(ext, ".mid"); } - bool video_get_frame(const FileAnalyzer &file, const char *destination_path, int width, int height, int seconds) { + static bool video_get_frame(const FileAnalyzer &file, const char *destination_path, int width, int height, int seconds, bool fallback_first_frame) { 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 @@ -162,6 +162,11 @@ namespace QuickMedia { fprintf(stderr, "Failed to execute ffmpeg, maybe its not installed?\n"); return false; } + + // Some corrupted videos (unseekable) can fail but ffmpeg doesn't report an error, it only reports a warning. + // In such cases the output file is not created and we can then instead try to get the first video frame instead + if(fallback_first_frame && get_file_type(destination_path_tmp) == FileType::FILE_NOT_FOUND) + return video_get_frame(file, destination_path, width, height, 0, false); } else { 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) { @@ -173,14 +178,9 @@ 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); + return video_get_frame(file, destination_path, width, height, middle_seconds, true); } // TODO: Remove dependency on ffprobe |