19 package org.sleuthkit.autopsy.coreutils;
21 import com.google.common.io.Files;
22 import java.awt.image.BufferedImage;
24 import java.io.IOException;
25 import java.nio.file.Paths;
26 import java.util.Arrays;
27 import java.util.Collections;
28 import java.util.List;
29 import java.util.SortedSet;
30 import java.util.TreeSet;
31 import java.util.logging.Level;
32 import org.netbeans.api.progress.ProgressHandle;
33 import org.opencv.core.Mat;
34 import org.opencv.highgui.VideoCapture;
35 import org.openide.util.NbBundle;
49 = Arrays.asList(
"mov",
"m4v",
"flv",
"mp4",
"3gp",
"avi",
"mpg",
50 "mpeg",
"asf",
"divx",
"rm",
"moov",
"wmv",
"vob",
"dat",
51 "m1v",
"m2v",
"m4v",
"mkv",
"mpe",
"yop",
"vqa",
"xmv",
52 "mve",
"wtv",
"webm",
"vivo",
"vc1",
"seq",
"thp",
"san",
53 "mjpg",
"smk",
"vmd",
"sol",
"cpk",
"sdp",
"sbg",
"rtsp",
54 "rpl",
"rl2",
"r3d",
"mlp",
"mjpeg",
"hevc",
"h265",
"265",
55 "h264",
"h263",
"h261",
"drc",
"avs",
"pva",
"pmp",
"ogg",
56 "nut",
"nuv",
"nsv",
"mxf",
"mtv",
"mvi",
"mxg",
"lxf",
57 "lvf",
"ivf",
"mve",
"cin",
"hnm",
"gxf",
"fli",
"flc",
58 "flx",
"ffm",
"wve",
"uv2",
"dxa",
"dv",
"cdxl",
"cdg",
59 "bfi",
"jv",
"bik",
"vid",
"vb",
"son",
"avs",
"paf",
"mm",
63 Arrays.asList(
"application/x-shockwave-flash",
80 return Collections.unmodifiableSortedSet(SUPPORTED_VIDEO_MIME_TYPES);
111 @NbBundle.Messages({
"# {0} - file name",
112 "VideoUtils.genVideoThumb.progress.text=extracting temporary file {0}"})
113 static BufferedImage generateVideoThumbnail(AbstractFile file,
int iconSize) {
114 java.io.File tempFile;
117 }
catch (NoCurrentCaseException ex) {
118 LOGGER.log(Level.WARNING,
"Exception while getting open case.", ex);
121 if (tempFile.exists() ==
false || tempFile.length() < file.getSize()) {
122 ProgressHandle progress = ProgressHandle.createHandle(Bundle.VideoUtils_genVideoThumb_progress_text(file.getName()));
125 Files.createParentDirs(tempFile);
126 if (Thread.interrupted()) {
129 ContentUtils.writeToFile(file, tempFile, progress, null,
true);
130 }
catch (IOException ex) {
131 LOGGER.log(Level.WARNING,
"Error extracting temporary file for " + ImageUtils.getContentPathSafe(file), ex);
136 VideoCapture videoFile =
new VideoCapture();
137 BufferedImage bufferedImage = null;
141 if (!videoFile.open(tempFile.toString())) {
142 LOGGER.log(Level.WARNING,
"Error opening {0} for preview generation.", ImageUtils.getContentPathSafe(file));
145 double fps = videoFile.get(CV_CAP_PROP_FPS);
146 double totalFrames = videoFile.get(CV_CAP_PROP_FRAME_COUNT);
147 if (fps <= 0 || totalFrames <= 0) {
148 LOGGER.log(Level.WARNING,
"Error getting fps or total frames for {0}", ImageUtils.getContentPathSafe(file));
151 double milliseconds = 1000 * (totalFrames / fps);
153 double timestamp = Math.min(milliseconds, 500);
155 int framkeskip = Double.valueOf(Math.floor((milliseconds - timestamp) / (THUMB_COLUMNS * THUMB_ROWS))).intValue();
157 Mat imageMatrix =
new Mat();
161 if (Thread.interrupted()) {
164 if (!videoFile.set(CV_CAP_PROP_POS_MSEC, timestamp + x * framkeskip + y * framkeskip * THUMB_COLUMNS)) {
165 LOGGER.log(Level.WARNING,
"Error seeking to " + timestamp +
"ms in {0}", ImageUtils.getContentPathSafe(file));
169 if (!videoFile.read(imageMatrix)) {
170 LOGGER.log(Level.WARNING,
"Error reading frames at " + timestamp +
"ms from {0}", ImageUtils.getContentPathSafe(file));
174 if (bufferedImage == null) {
175 bufferedImage =
new BufferedImage(imageMatrix.cols() *
THUMB_COLUMNS, imageMatrix.rows() *
THUMB_ROWS, BufferedImage.TYPE_3BYTE_BGR);
178 byte[] data =
new byte[imageMatrix.rows() * imageMatrix.cols() * (int) (imageMatrix.elemSize())];
179 imageMatrix.get(0, 0, data);
182 if (imageMatrix.channels() == 3) {
183 for (
int k = 0; k < data.length; k += 3) {
185 data[k] = data[k + 2];
190 bufferedImage.getRaster().setDataElements(imageMatrix.cols() * x, imageMatrix.rows() * y, imageMatrix.cols(), imageMatrix.rows(), data);
196 if (Thread.interrupted()) {
199 return bufferedImage == null ? null : ScalrWrapper.resizeFast(bufferedImage, iconSize);
218 throw new IllegalStateException(ex);
static List< String > getSupportedVideoExtensions()
static final int CV_CAP_PROP_FRAME_COUNT
static File getVideoFileInTempDir(AbstractFile file)
static final int THUMB_ROWS
String getTempDirectory()
static SortedSet< String > getSupportedVideoMimeTypes()
static final int THUMB_COLUMNS
static final List< String > SUPPORTED_VIDEO_EXTENSIONS
static final int CV_CAP_PROP_FPS
static final SortedSet< String > SUPPORTED_VIDEO_MIME_TYPES
synchronized static Logger getLogger(String name)
static Case getCurrentCaseThrows()
static final int CV_CAP_PROP_POS_MSEC
static File getTempVideoFile(AbstractFile file)
static boolean isVideoThumbnailSupported(AbstractFile file)