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);
122 @NbBundle.Messages({
"# {0} - file name",
123 "VideoUtils.genVideoThumb.progress.text=extracting temporary file {0}"})
124 static BufferedImage generateVideoThumbnail(AbstractFile file,
int iconSize) {
125 java.io.File tempFile;
128 }
catch (NoCurrentCaseException ex) {
129 LOGGER.log(Level.WARNING,
"Exception while getting open case.", ex);
132 if (tempFile.exists() ==
false || tempFile.length() < file.getSize()) {
133 ProgressHandle progress = ProgressHandle.createHandle(Bundle.VideoUtils_genVideoThumb_progress_text(file.getName()));
136 Files.createParentDirs(tempFile);
137 if (Thread.interrupted()) {
140 ContentUtils.writeToFile(file, tempFile, progress, null,
true);
141 }
catch (IOException ex) {
142 LOGGER.log(Level.WARNING,
"Error extracting temporary file for " + ImageUtils.getContentPathSafe(file), ex);
147 VideoCapture videoFile =
new VideoCapture();
148 BufferedImage bufferedImage = null;
151 if (!videoFile.open(tempFile.toString())) {
152 LOGGER.log(Level.WARNING,
"Error opening {0} for preview generation.", ImageUtils.getContentPathSafe(file));
155 double fps = videoFile.get(CV_CAP_PROP_FPS);
156 double totalFrames = videoFile.get(CV_CAP_PROP_FRAME_COUNT);
157 if (fps <= 0 || totalFrames <= 0) {
158 LOGGER.log(Level.WARNING,
"Error getting fps or total frames for {0}", ImageUtils.getContentPathSafe(file));
161 if (Thread.interrupted()) {
165 double duration = 1000 * (totalFrames / fps);
178 int[] framePositions =
new int[] {
179 (int) (duration * FRAME_GRAB_POS_RATIO[0]),
180 (int) (duration * FRAME_GRAB_POS_RATIO[1]),
181 (int) (duration * FRAME_GRAB_POS_RATIO[2]),
182 (int) (duration * FRAME_GRAB_POS_RATIO[3]),
185 Mat imageMatrix =
new Mat();
187 for (
int i=0; i < framePositions.length; i++) {
188 if (!videoFile.set(CV_CAP_PROP_POS_MSEC, framePositions[i])) {
189 LOGGER.log(Level.WARNING,
"Error seeking to " + framePositions[i] +
"ms in {0}", ImageUtils.getContentPathSafe(file));
194 if (!videoFile.read(imageMatrix)) {
195 LOGGER.log(Level.WARNING,
"Error reading frame at " + framePositions[i] +
"ms from {0}", ImageUtils.getContentPathSafe(file));
204 if (imageMatrix.empty()) {
208 int matrixColumns = imageMatrix.cols();
209 int matrixRows = imageMatrix.rows();
212 if (bufferedImage == null) {
213 bufferedImage =
new BufferedImage(matrixColumns, matrixRows, BufferedImage.TYPE_3BYTE_BGR);
216 byte[] data =
new byte[matrixRows * matrixColumns * (int) (imageMatrix.elemSize())];
217 imageMatrix.get(0, 0, data);
220 if (imageMatrix.channels() == 3) {
221 for (
int k = 0; k < data.length; k += 3) {
223 data[k] = data[k + 2];
228 bufferedImage.getRaster().setDataElements(0, 0, matrixColumns, matrixRows, data);
232 if (Thread.interrupted()) {
235 return bufferedImage == null ? null : ScalrWrapper.resizeFast(bufferedImage, iconSize);
254 throw new IllegalStateException(ex);
static List< String > getSupportedVideoExtensions()
static final int CV_CAP_PROP_FRAME_COUNT
static File getVideoFileInTempDir(AbstractFile file)
String getTempDirectory()
static final double[] FRAME_GRAB_POS_RATIO
static SortedSet< String > getSupportedVideoMimeTypes()
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)