Java 視頻處理,截幀操作


1.maven

<dependency>
            <groupId>org.bytedeco</groupId>
            <artifactId>javacv</artifactId>
            <version>1.4.1</version>
        </dependency>
        <dependency>
            <groupId>org.bytedeco</groupId>
            <artifactId>javacpp</artifactId>
            <version>1.4.1</version>
        </dependency>
        <dependency>
            <groupId>org.bytedeco.javacpp-presets</groupId>
            <artifactId>opencv-platform</artifactId>
            <version>3.4.1-1.4.1</version>
        </dependency>
        <dependency>
            <groupId>org.bytedeco.javacpp-presets</groupId>
            <artifactId>ffmpeg-platform</artifactId>
            <version>3.4.2-1.4.1</version>
</dependency>

2.工具類

 
         
import org.bytedeco.javacpp.opencv_core;
import org.bytedeco.javacpp.opencv_videoio;
import org.bytedeco.javacv.FFmpegFrameGrabber;
import org.bytedeco.javacv.Frame;
import org.bytedeco.javacv.Java2DFrameConverter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.*;
import java.util.List;

import static org.bytedeco.javacpp.opencv_imgcodecs.cvSaveImage;
import static org.bytedeco.javacpp.opencv_videoio.*;


/**
* 視頻工具
*
* @author
*/
public class VideoUtil {

private static final int SECOND = 50;

private static final Logger logger = LoggerFactory.getLogger(VideoUtil.class);

/**
* 獲取指定視頻的幀並保存為圖片至指定目錄
*
* @param videoFile 源視頻文件
* @param saveFile 截取幀的圖片存放路徑
* @throws Exception
*/
public static List<File> fetchPic(File videoFile, String saveFile, int second) throws Exception {

java.util.List<File> files = new ArrayList<>();

FFmpegFrameGrabber ff = new FFmpegFrameGrabber(videoFile);
ff.start();
int lenght = ff.getLengthInAudioFrames();
System.out.println(ff.getFrameRate());

int i = 0;
Frame frame = null;

while (i < lenght) {
// 過濾前5幀,避免出現全黑的圖片,依自己情況而定
frame = ff.grabImage();
if (i >= (int) (ff.getFrameRate() * second) && frame.image != null) {
System.out.print(i + ",");
if (frame != null && frame.image != null) {
System.out.println(i);
files.add(writeToFile(frame, saveFile, i));
}
second++;
}
i += second;
}
ff.stop();
return files;
}

public static List<Integer> getList(int count, int length) {
if (count > length) {
count = length;
}
System.out.println(length);
System.out.println(count);
int total = (int) (length / count);
List<Integer> list = new ArrayList<>();
for (int i = 0; i < count; i++) {
list.add(i * total);
System.out.println(i * total);
}
return list;
}

public static List<File> fetchPicByCount(File videoFile, String saveFile, int count) throws Exception {

java.util.List<File> files = new ArrayList<>();

FFmpegFrameGrabber ff = new FFmpegFrameGrabber(videoFile);
ff.start();

int frameLength = ff.getLengthInFrames();


System.out.println("length:" + frameLength);

List<Integer> list = getList(count, frameLength);

System.out.println(ff.getFrameRate());

int i = 0;
Frame frame = null;

while (i < frameLength) {
frame = ff.grabImage();
if (list.contains(i)) {
if (frame != null && frame.image != null) {
System.out.println(i);
files.add(writeToFile(frame, saveFile, i));
}
}
i++;
}
ff.stop();
return files;
}


public static File writeToFile(Frame frame, String saveFile, int second) throws InvokeException {
String fileName = String.valueOf(System.currentTimeMillis()) + second;
File targetFile = new File(saveFile + File.separator + fileName + ".jpg");
String imgSuffix = "jpg";

Java2DFrameConverter converter = new Java2DFrameConverter();
BufferedImage srcBi = converter.getBufferedImage(frame);
int owidth = srcBi.getWidth();
int oheight = srcBi.getHeight();
// 對截取的幀進行等比例縮放
int width = 800;
int height = (int) (((double) width / owidth) * oheight);
BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR);
bi.getGraphics().drawImage(srcBi.getScaledInstance(width, height, Image.SCALE_SMOOTH), 0, 0, null);
try {
ImageIO.write(bi, imgSuffix, targetFile);
} catch (Exception e) {
throw new InvokeException(ResultEnum.FAILED.getCode(), "截幀失敗");
}
return targetFile;
}


/**
* 獲取視頻時長,單位為秒
*
* @param file
* @return 時長(s)
*/
public static Long getVideoTime(File file) {
Long times = 0L;
try {
FFmpegFrameGrabber ff = new FFmpegFrameGrabber(file);
ff.start();
times = ff.getLengthInTime() / (1000 * 1000);
ff.stop();
} catch (Exception e) {
e.printStackTrace();
}
return times;
}

public static void getBySecond(String filePath, String directory) {
opencv_videoio.CvCapture capture = cvCaptureFromFile(filePath);
//幀率
double fps = cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_COUNT);
System.out.println("幀率:" + fps);
opencv_core.IplImage frame = null;
double pos1 = 0;

double rootCount = 0;
while (true) {

//讀取關鍵幀
frame = cvQueryFrame(capture);

rootCount = fps;
while (rootCount > 0) {
//這一段的目的是跳過每一秒鍾的幀數,也就是說fps是幀率(一秒鍾有多少幀),在讀取一幀后,跳過fps數量的幀就相當於跳過了1秒鍾。
frame = cvQueryFrame(capture);
rootCount--;
}

//獲取當前幀的位置
pos1 = cvGetCaptureProperty(capture, CV_CAP_PROP_POS_FRAMES);
System.out.println(pos1);

if (null == frame)
break;

cvSaveImage("E:/223/" + pos1 + ".jpg", frame);

}

cvReleaseCapture(capture);
}

/*public void getBySecond() {
opencv_videoio.CvCapture capture = opencv_highgui.cvC("D:/085402.crf");



//幀率
int fps = (int) opencv_highgui.cvGetCaptureProperty(capture, opencv_highgui.CV_CAP_PROP_FPS);
System.out.println("幀率:"+fps);

opencv_core.IplImage frame = null;
double pos1 = 0;

int rootCount = 0;

while (true) {

//讀取關鍵幀
frame = opencv_highgui.cvQueryFrame(capture);

rootCount = fps;
while(rootCount > 0 ){
//這一段的目的是跳過每一秒鍾的幀數,也就是說fps是幀率(一秒鍾有多少幀),在讀取一幀后,跳過fps數量的幀就相當於跳過了1秒鍾。
frame = opencv_highgui.cvQueryFrame(capture);
rootCount--;
}

//獲取當前幀的位置
pos1 = opencv_highgui.cvGetCaptureProperty(capture,opencv_highgui.CV_CAP_PROP_POS_FRAMES);
System.out.println(pos1);

if (null == frame)
break;

opencv_highgui.cvSaveImage("d:/img/" + pos1 + ".jpg",frame);

}

opencv_highgui.cvReleaseCapture(capture);
}*/

public static void main(String[] args) {
try {
//getList(10,113);

File file = new File("E:/2.mp4");
List<File> files = VideoUtil.fetchPicByCount(file, "E:/223", 100);
System.out.println(files.get(0).getName());
System.out.println(VideoUtil.getVideoTime(file));
} catch (Exception e) {
e.printStackTrace();
}
}
}

 

參考:https://blog.csdn.net/qq_22175485/article/details/81025525


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM