aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2023-12-21 18:23:53 +0100
committerdec05eba <dec05eba@protonmail.com>2023-12-21 18:23:53 +0100
commita257f50a9f752919729bcf3aa3358491ff5edcad (patch)
tree62225eea968da8688ab1ff9e94ba6355f054ade1
parent1a20c29eeba5edfd51068b5bec6ec53af0629d38 (diff)
Fix thumbnails for broken videos (unable to seek)
-rw-r--r--include/FileAnalyzer.hpp3
-rw-r--r--src/FileAnalyzer.cpp14
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