mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-12 07:56:16 +00:00
Add video API
This commit is contained in:
parent
13a999dc4d
commit
c60d1854f4
@ -116,6 +116,10 @@
|
||||
<fileset dir="${thirdparty.dir}/yara/bin"/>
|
||||
</copy>
|
||||
<copy file="${thirdparty.dir}/yara/bin/YaraJNIWrapper.jar" todir="${ext.dir}" />
|
||||
<!--Copy ffmpeg to release-->
|
||||
<copy todir="${basedir}/release/ffmpeg" >
|
||||
<fileset dir="${thirdparty.dir}/ffmpeg"/>
|
||||
</copy>
|
||||
</target>
|
||||
|
||||
|
||||
|
168
Core/src/org/sleuthkit/autopsy/report/video/VideoSnapShotWorker.java
Executable file
168
Core/src/org/sleuthkit/autopsy/report/video/VideoSnapShotWorker.java
Executable file
@ -0,0 +1,168 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2022 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.report.video;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
import javax.swing.SwingWorker;
|
||||
import org.opencv.core.Mat;
|
||||
import org.opencv.core.Size;
|
||||
import org.opencv.imgproc.Imgproc;
|
||||
import org.opencv.videoio.VideoCapture;
|
||||
import org.opencv.videoio.VideoWriter;
|
||||
import org.opencv.videoio.Videoio;
|
||||
|
||||
/**
|
||||
* A SwingWorker that will create a video of screen captures.
|
||||
*
|
||||
* To have the the gui update with process add a PropertyChangeListener for
|
||||
* the property 'progress'.
|
||||
*
|
||||
* To update the gui on completion subclass this class and implement
|
||||
* the SwingWorker done method.
|
||||
*
|
||||
*/
|
||||
public class VideoSnapShotWorker extends SwingWorker<Void, Void>{
|
||||
private static final long MIN_FRAME_INTERVAL_MILLIS = 500;
|
||||
|
||||
private static final int DEFAULT_FRAMES_PER_SECOND = 1;
|
||||
private static final int DEFAULT_TOTAL_FRAMES = 100;
|
||||
private static final int DEFAULT_SCALE = 100;
|
||||
|
||||
private final Path inputPath;
|
||||
private final Path outputPath;
|
||||
private final long numFrames;
|
||||
private final double scale;
|
||||
private final int framesPerSecond;
|
||||
|
||||
/**
|
||||
* Creates a new instance of the SwingWorker using the default parameters.
|
||||
*
|
||||
* @param inputPath The path to the existing video.
|
||||
* @param outputPath The output path of the snapshot video.
|
||||
*/
|
||||
public VideoSnapShotWorker(Path inputPath, Path outputPath) {
|
||||
this(inputPath, outputPath, DEFAULT_TOTAL_FRAMES, DEFAULT_SCALE, DEFAULT_FRAMES_PER_SECOND);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new instance of the SwingWorker.
|
||||
*
|
||||
* @param inputPath The path to the existing video.
|
||||
* @param outputPath The output path of the snapshot video.
|
||||
* @param numFrames The number of screen captures to include in the video.
|
||||
* @param scale % to scale from the original. Passing 0 or 100 will result in no change.
|
||||
* @param framesPerSecond Effects how long each frame will appear in the video.
|
||||
*/
|
||||
public VideoSnapShotWorker(Path inputPath, Path outputPath, long numFrames, double scale, int framesPerSecond) {
|
||||
this.inputPath = inputPath;
|
||||
this.outputPath = outputPath;
|
||||
this.scale = scale;
|
||||
this.numFrames = numFrames;
|
||||
this.framesPerSecond = framesPerSecond;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Void doInBackground() throws Exception {
|
||||
File input = inputPath.toFile();
|
||||
if (!input.exists() || !input.isFile() || !input.canRead()) {
|
||||
throw new IOException(String.format("Unable to read input file %s", input.toString()));
|
||||
}
|
||||
|
||||
File outputFile = outputPath.toFile();
|
||||
outputFile.mkdirs();
|
||||
|
||||
String file_name = inputPath.toString();//OpenCV API requires string for file name
|
||||
VideoCapture videoCapture = new VideoCapture(file_name); //VV will contain the videos
|
||||
|
||||
if (!videoCapture.isOpened()) //checks if file is not open
|
||||
{
|
||||
// add this file to the set of known bad ones
|
||||
throw new Exception("Problem with video file; problem when attempting to open file.");
|
||||
}
|
||||
VideoWriter writer = null;
|
||||
try {
|
||||
// get the duration of the video
|
||||
double fps = framesPerSecond == 0 ? videoCapture.get(Videoio.CAP_PROP_FPS) : framesPerSecond; // gets frame per second
|
||||
double total_frames = videoCapture.get(7); // gets total frames
|
||||
double milliseconds = 1000 * (total_frames / fps); //convert to ms duration
|
||||
long myDurationMillis = (long) milliseconds;
|
||||
|
||||
if (myDurationMillis <= 0) {
|
||||
throw new Exception(String.format("Failed to make snapshot video, original video has no duration. %s", inputPath.toAbsolutePath()));
|
||||
}
|
||||
|
||||
// calculate the number of frames to capture
|
||||
int numFramesToGet = (int) numFrames;
|
||||
long frameInterval = myDurationMillis / numFrames;
|
||||
|
||||
if (frameInterval < MIN_FRAME_INTERVAL_MILLIS) {
|
||||
numFramesToGet = 1;
|
||||
}
|
||||
|
||||
// for each timeStamp, grab a frame
|
||||
Mat mat = new Mat(); // holds image received from video in mat format (opencv format)
|
||||
|
||||
Size s = new Size((int) videoCapture.get(Videoio.CAP_PROP_FRAME_WIDTH), (int) videoCapture.get(Videoio.CAP_PROP_FRAME_HEIGHT));
|
||||
Size newSize = (scale == 0 || scale == 100) ? s : new Size((int) (videoCapture.get(Videoio.CAP_PROP_FRAME_WIDTH) * scale), (int) (videoCapture.get(Videoio.CAP_PROP_FRAME_HEIGHT) * scale));
|
||||
|
||||
writer = new VideoWriter(outputFile.toString(), VideoWriter.fourcc('M', 'J', 'P', 'G'), 1, newSize, true);
|
||||
|
||||
if (!writer.isOpened()) {
|
||||
throw new Exception(String.format("Problem with video file; problem when attempting to open output file. %s", outputFile.toString()));
|
||||
}
|
||||
|
||||
for (int frame = 0; frame < numFramesToGet; ++frame) {
|
||||
|
||||
if(isCancelled()) {
|
||||
break;
|
||||
}
|
||||
|
||||
long timeStamp = frame * frameInterval;
|
||||
videoCapture.set(0, timeStamp); //set video in timeStamp ms
|
||||
|
||||
if (!videoCapture.read(mat)) { // on Wav files, usually the last frame we try to read does not succeed.
|
||||
continue;
|
||||
}
|
||||
|
||||
Mat resized = new Mat();
|
||||
Imgproc.resize(mat, resized, newSize, 0, 0, Imgproc.INTER_CUBIC);
|
||||
writer.write(resized);
|
||||
|
||||
setProgress(numFramesToGet/frame);
|
||||
}
|
||||
|
||||
} finally {
|
||||
videoCapture.release();
|
||||
if (writer != null) {
|
||||
writer.release();
|
||||
}
|
||||
}
|
||||
|
||||
if(isCancelled()) {
|
||||
if(outputFile.exists()) {
|
||||
outputFile.delete();
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
93
Core/src/org/sleuthkit/autopsy/report/video/VideoUtilis.java
Executable file
93
Core/src/org/sleuthkit/autopsy/report/video/VideoUtilis.java
Executable file
@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2022 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.report.video;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import org.openide.modules.InstalledFileLocator;
|
||||
import org.sleuthkit.autopsy.coreutils.ExecUtil;
|
||||
import org.sleuthkit.autopsy.coreutils.ExecUtil.ProcessTerminator;
|
||||
|
||||
public class VideoUtilis {
|
||||
|
||||
private static final String FFMPEG = "ffmpeg";
|
||||
private static final String FFMPEG_EXE = "ffmpeg.exe";
|
||||
|
||||
private VideoUtilis() {}
|
||||
|
||||
static void compressVideo(Path inputPath, Path outputPath, ProcessTerminator terminator) throws Exception {
|
||||
Path executablePath = Paths.get(FFMPEG, FFMPEG_EXE);
|
||||
File exeFile = InstalledFileLocator.getDefault().locate(executablePath.toString(), VideoUtilis.class.getPackage().getName(), true);
|
||||
if(exeFile == null) {
|
||||
throw new IOException("Unable to compress ffmpeg.exe was not found.");
|
||||
}
|
||||
|
||||
if(!exeFile.canExecute()) {
|
||||
throw new IOException("Unable to compress ffmpeg.exe could not be execute");
|
||||
}
|
||||
|
||||
|
||||
ProcessBuilder processBuilder = buildProcessWithRunAsInvoker(
|
||||
"\"" + exeFile.getAbsolutePath() + "\"",
|
||||
"-i", "\"" + inputPath.toAbsolutePath().toString() + "\"",
|
||||
"-vf", "scale=1280:-1",
|
||||
"-c:v", "libx264",
|
||||
"-preset", "veryslow",
|
||||
"-crf", "24",
|
||||
"\"" + outputPath.toAbsolutePath().toString() + "\"");
|
||||
|
||||
ExecUtil.execute(processBuilder, terminator);
|
||||
}
|
||||
|
||||
static void scaleVideo(Path inputPath, Path outputPath, int width, int height, ProcessTerminator terminator) throws Exception{
|
||||
Path executablePath = Paths.get(FFMPEG, FFMPEG_EXE);
|
||||
File exeFile = InstalledFileLocator.getDefault().locate(executablePath.toString(), VideoUtilis.class.getPackage().getName(), true);
|
||||
if(exeFile == null) {
|
||||
throw new IOException("Unable to compress ffmpeg.exe was not found.");
|
||||
}
|
||||
|
||||
if(!exeFile.canExecute()) {
|
||||
throw new IOException("Unable to compress ffmpeg.exe could not be execute");
|
||||
}
|
||||
|
||||
String scaleParam = Integer.toString(width) + ":" + Integer.toString(height);
|
||||
|
||||
ProcessBuilder processBuilder = buildProcessWithRunAsInvoker(
|
||||
"\"" + exeFile.getAbsolutePath() + "\"",
|
||||
"-i", "\"" + inputPath.toAbsolutePath().toString() + "\"",
|
||||
"-s", scaleParam,
|
||||
"-c:a", "copy",
|
||||
"\"" + outputPath.toAbsolutePath().toString() + "\"");
|
||||
|
||||
ExecUtil.execute(processBuilder, terminator);
|
||||
|
||||
}
|
||||
|
||||
static private ProcessBuilder buildProcessWithRunAsInvoker(String... commandLine) {
|
||||
ProcessBuilder processBuilder = new ProcessBuilder(commandLine);
|
||||
/*
|
||||
* Add an environment variable to force aLeapp to run with the same
|
||||
* permissions Autopsy uses.
|
||||
*/
|
||||
processBuilder.environment().put("__COMPAT_LAYER", "RunAsInvoker"); //NON-NLS
|
||||
return processBuilder;
|
||||
}
|
||||
}
|
BIN
thirdparty/ffmpeg/avcodec-59.dll
vendored
Executable file
BIN
thirdparty/ffmpeg/avcodec-59.dll
vendored
Executable file
Binary file not shown.
BIN
thirdparty/ffmpeg/avdevice-59.dll
vendored
Executable file
BIN
thirdparty/ffmpeg/avdevice-59.dll
vendored
Executable file
Binary file not shown.
BIN
thirdparty/ffmpeg/avfilter-8.dll
vendored
Executable file
BIN
thirdparty/ffmpeg/avfilter-8.dll
vendored
Executable file
Binary file not shown.
BIN
thirdparty/ffmpeg/avformat-59.dll
vendored
Executable file
BIN
thirdparty/ffmpeg/avformat-59.dll
vendored
Executable file
Binary file not shown.
BIN
thirdparty/ffmpeg/avutil-57.dll
vendored
Executable file
BIN
thirdparty/ffmpeg/avutil-57.dll
vendored
Executable file
Binary file not shown.
BIN
thirdparty/ffmpeg/ffmpeg.exe
vendored
Executable file
BIN
thirdparty/ffmpeg/ffmpeg.exe
vendored
Executable file
Binary file not shown.
BIN
thirdparty/ffmpeg/postproc-56.dll
vendored
Executable file
BIN
thirdparty/ffmpeg/postproc-56.dll
vendored
Executable file
Binary file not shown.
BIN
thirdparty/ffmpeg/swresample-4.dll
vendored
Executable file
BIN
thirdparty/ffmpeg/swresample-4.dll
vendored
Executable file
Binary file not shown.
BIN
thirdparty/ffmpeg/swscale-6.dll
vendored
Executable file
BIN
thirdparty/ffmpeg/swscale-6.dll
vendored
Executable file
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user