From 3397924e6697631970bb50c6475d2922656311aa Mon Sep 17 00:00:00 2001 From: Jonathan Hefner Date: Tue, 17 Nov 2020 16:25:01 -0600 Subject: [PATCH] Use FFmpeg scene detection for video previews Generating a video preview by capturing only the first frame of a video is problematic for videos that begin with a fade in from black. By using keyframe and scene detection that is built in to FFmpeg, we can generate a more representative preview. --- .../active_storage/previewer/video_previewer.rb | 16 +++++++++++++++- guides/source/active_storage_overview.md | 2 +- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/activestorage/lib/active_storage/previewer/video_previewer.rb b/activestorage/lib/active_storage/previewer/video_previewer.rb index 06ffc4d72a..aa6879b692 100644 --- a/activestorage/lib/active_storage/previewer/video_previewer.rb +++ b/activestorage/lib/active_storage/previewer/video_previewer.rb @@ -28,7 +28,21 @@ module ActiveStorage private def draw_relevant_frame_from(file, &block) - draw self.class.ffmpeg_path, "-i", file.path, "-y", "-vframes", "1", "-f", "image2", "-", &block + ffmpeg_args = [ + "-i", file.path, + "-vf", + # Select the first video frame, plus keyframes and frames + # that meet the scene change threshold. + 'select=eq(n\,0)+eq(key\,1)+gt(scene\,0.015),' + + # Loop the first 1-2 selected frames in case we were only + # able to select 1 frame, then drop the first looped frame. + # This lets us use the first video frame as a fallback. + "loop=loop=-1:size=2,trim=start_frame=1", + "-frames:v", "1", + "-f", "image2", "-", + ] + + draw self.class.ffmpeg_path, *ffmpeg_args, &block end end end diff --git a/guides/source/active_storage_overview.md b/guides/source/active_storage_overview.md index 7fc98f8a18..f131a854f2 100644 --- a/guides/source/active_storage_overview.md +++ b/guides/source/active_storage_overview.md @@ -559,7 +559,7 @@ the box, Active Storage supports previewing videos and PDF documents. ``` -WARNING: Extracting previews requires third-party applications, FFmpeg for +WARNING: Extracting previews requires third-party applications, FFmpeg v3.4+ for video and muPDF for PDFs, and on macOS also XQuartz and Poppler. These libraries are not provided by Rails. You must install them yourself to use the built-in previewers. Before you install and use third-party software,