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

Java 视频处理,截帧操作的更多相关文章

  1. java获取视频播第一帧

    FFMPEG 功能很强大,做视频必备的软件.大家可通过 http://ffmpeg.org/ 了解.Windows版本的软件,可通过 http://ffmpeg.zeranoe.com/builds/ ...

  2. OpenCV 编程简单介绍(矩阵/图像/视频的基本读写操作)

    PS. 因为csdn博客文章长度有限制,本文有部分内容被截掉了.在OpenCV中文站点的wiki上有可读性更好.而且是完整的版本号,欢迎浏览. OpenCV Wiki :<OpenCV 编程简单 ...

  3. Opencv基础知识-----视频的读取和操作

    Opencv读取视频代码 #include "stdafx.h" #include"highgui.h"   int main(int argc,char* a ...

  4. selenium webdriver 截屏操作

    有时候我们需要进行截屏操作,特别是遇到一些比较重要的页面信息(出现错误)或者出现不同需要进行对比时, 我们就需要对正在处理的页面进行截屏! 未经作者允许,禁止转载! package test_wait ...

  5. AsciiPic Java视频转成字符画

    AsciiPic Java视频转成字符画 github下载 https://github.com/dejavudwh/AsciiPic 运行截图 //没有做GUI 比较简陋 节省时间 main里的文件 ...

  6. tcpdump截帧工具使用

    一.tcpdump介绍 ​ tcpdump是Linux下功能强大的截帧工具,相当于windows下的wireshark一下,只是操作方式是命令行的,需要熟悉Linux命令行操作. ​ 常用的Linux ...

  7. java的基础知识文件操作和标识符

    1.文件夹的操作 dir :显示当前文件夹中的所有文件和文件夹. cd 路径:  进入到指定的路径. cd ..  : 回到上一级目录 cd  \ : 回到当前目录的跟目录 md 文件夹名  创建一个 ...

  8. Elasticsearch【JAVA REST Client】客户端操作

    ES系统作为集群,环境搭建非常方便简单. 现在在我们的应用中,如何对这个集群进行操作呢? 我们利用ES系统,通常都是下面的架构: 在这里,客户端的请求通过LB进行负载均衡,因为操作任何一个ES的实例, ...

  9. Java Calendar 类的时间操作

    Java Calendar 类的时间操作 标签: javaCalendar时间Date 2013-07-30 17:53 140401人阅读 评论(7) 收藏 举报 分类: 所有(165) Java ...

随机推荐

  1. 使用 OpenSSL 创建私有 CA:1 根证书

    OpenSSL 创建私有 CA 三部曲:使用 OpenSSL 创建私有 CA:1 根证书使用 OpenSSL 创建私有 CA:2 中间证书使用 OpenSSL 创建私有 CA:3 用户证书 OpenS ...

  2. CSS3下的渐变文字效果实现

    如下,第一种方法已实践 一.方法一:借助mask-image属性 可以狠狠地点击这里:CSS3下的渐变文字效果方法一demo 如果您手头上的浏览器是Chrome或是Safari,则您可以在demo页面 ...

  3. 小小知识点(二)——如何修改win10 的C盘中用户下的文件夹名称

    1.以管理员身份登录计算机 在win10桌面的开始界面处有个用户头像,点击在里面找到administrator: 如果没有,则需进行如下设置: (1)右键计算机,双击管理,找到如下所示的用户中的adm ...

  4. html总结:文本框填满表格

    <style> input { width: 100%; }</style>

  5. nginx 1.4.3能直接升到1.8.1吗

    nginx 1.4.3能直接升到1.8.1吗_百度知道https://zhidao.baidu.com/question/564529441847261484.html nginx-1.6.3平滑升级 ...

  6. MySQL之慢查询日志和通用查询

    MySQL中的日志包括:错误日志.二进制日志.通用查询日志.慢查询日志等等.这里主要介绍下比较常用的两个功能:通用查询日志和慢查询日志. 1.通用查询日志:记录建立的客户端连接和执行的语句. 2.慢查 ...

  7. Laravel 服务容器、服务提供器、契约实例讲解

        前言 刚开始看laravel服务容器.契约.服务提供器的确生涩难懂,不单单是概念繁多,而且实际的demo很难找(找是找到了,但难用啊),最后就隔一段时间看一遍,大概个十来遍,还真给看出个门道, ...

  8. [转帖]IP /TCP协议及握手过程和数据包格式中级详解

    IP /TCP协议及握手过程和数据包格式中级详解 https://www.toutiao.com/a6665292902458982926/ 写的挺好的 其实 一直没闹明白 网络好 广播地址 还有 网 ...

  9. Linux基础学习笔记1

    MBR分区 主分区: 1-4,一块硬盘最多四个主分区,对主机必须有,主区可以格式化ntfs,存数据: 扩展分区:1-4,一块硬盘最多一个扩展分区,可以没有扩展分区,划分更小的单元,即逻辑分区: 逻辑分 ...

  10. web service 异常

    1.org/apache/commons/discovery/tools/DiscoverSingleton Exception in thread "main" java.lan ...