首先我们将我们的项目拆分成两个部分,一是屏幕截图部分,二是jpg图片转AVI部分,在之后我会发出通过javaCV进行操作
不过在这个之前,我们要先安装JMF,很多博客中,总是不要求按照JMF导致不能运行,JMF是Java媒体框架,地址
还需要Jim2mov.jar
Windows直接安装即可,具体可以参考博客:JMF下载和安装
这里我测试,需要将JMF下的.jar导入到项目中
所用到的资源:http://download.youkuaiyun.com/download/whb3299065/10202791
屏幕抓取
我们通过Robot组件,来进行屏幕抓取
首先我们先看看如何捕捉一张图像:为了可以让该方法直接运行我添加一些参数
Robot robot = new Robot();
//尺寸指定为全屏
Rectangle rectangle=new Rectangle(Toolkit.getDefaultToolkit().getScreenSize());
public void capturOneImg(/**Rectangle rectangle*/) {
try {
BufferedImage image = robot.createScreenCapture(rectangle);//捕获制定屏幕矩形区域
//这个功能是对图片进行压缩并保持,调用thumbnailator工具对图片进行处理
Thumbnails.of(image).scale(0.8f).outputQuality(0.5f)
.toFile("D:\\imgs\\图片名称.jpg");
} catch (IOException e) {
e.printStackTrace();
}
}
这样就可以将屏幕截取下来,保存为一张图片了
视频转换
首先要注意的一点就是tip组一定是有序的,不然合成的视频一定会很混乱,排序过程我会在代码中展示,这里我先假设File[] jpgs是有序的。
File[] jpgs=……;
然后我们要设置视频的各种信息
// 生成视频的名称
DefaultMovieInfoProvider dmip = new DefaultMovieInfoProvider(aviFileName);
// 设置每秒帧数
dmip.setFPS(fps>0?fps:3); // 如果未设置,默认为3
// 设置总帧数
dmip.setNumberOfFrames(jpgs.length);
// 设置视频宽和高(最好与图片宽高保持一直)
dmip.setMWidth(mWidth>0?mWidth:1440); // 如果未设置,默认为1440
dmip.setMHeight(mHeight>0?mHeight:860); // 如果未设置,默认为860
然后就是直接创建一个转换对象,传入一个入伙获取图片的匿名对象,最后调用saveMovie方法,视频就保存成功了,注意的是,这个位置非常耗时,而且转成AVI后比图片组占用的空间都大
new Jim2Mov(new ImageProvider() {
public byte[] getImage(int frame) {
try {
// 设置压缩比
return MovieUtils.convertImageToJPEG((jpgs[frame]), 1.0f);
} catch (IOException e) {
System.err.println(e);
}
return null;
}
}, dmip, null).saveMovie(MovieInfoProvider.TYPE_AVI_MJPEG);
看懂了这个方法,那么我们就可以将这个类全部展示出来了,这里需要注意的是,Config是我自己定义的一个不完善的配置对象,这里建议重写一下,我会把我的config放到最后
import com.sun.image.codec.jpeg.JPEGCodec;
import net.coobird.thumbnailator.Thumbnails;
import top.whbweb.screen.recording.config.Config;
import top.whbweb.screen.recording.img2void.PicToAviUtil;
import top.whbweb.screen.recording.util.UUID;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
//录屏工具类
public class ScreenRecording {
Config config;
Robot robot;
public Thread thread;
private long sleepTime;
private boolean recordSwitch = true;
private String recordName;
public ScreenRecording() throws AWTException {
robot = new Robot();
init();
}
public void start() {
recordSwitch=true;
recordName= UUID.getUUID()+"\\";
new File(config.basePath+recordName).mkdirs();
thread.start();
}
public void pause() {
try {
thread.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void stop() {
int width= (int) config.getRectangle().getWidth();
int height= (int) config.getRectangle().getHeight();
recordSwitch=false;
PicToAviUtil.convertPicToAvi(config.basePath+recordName+"\\",
config.basePath+recordName+".avi",
config.frame,width,height
);
}
public void capturOneImg(Rectangle rectangle) {
try {
BufferedImage image = robot.createScreenCapture(rectangle);//捕获制定屏幕矩形区域
Thumbnails.of(image).scale(0.8f).outputQuality(0.5f).toFile(config.basePath+recordName + UUID.getUUID() + ".jpg");
} catch (IOException e) {
e.printStackTrace();
}
}
public Config getConfig() {
return config;
}
public void setConfig(Config config) {
this.config = config;
sleepTime = 1000 / config.getFrame();
}
public void init() {
thread = new Thread() {
@Override public void run() {
while (recordSwitch) {
try {
capturOneImg(config.getRectangle());
Thread.sleep(sleepTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
}
}
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.Comparator;
import org.jim2mov.core.DefaultMovieInfoProvider;
import org.jim2mov.core.ImageProvider;
import org.jim2mov.core.Jim2Mov;
import org.jim2mov.core.MovieInfoProvider;
import org.jim2mov.core.MovieSaveException;
import org.jim2mov.utils.MovieUtils;
/**
* 图片与视频转换工具类
*
* @author Administrator
*/
public class PicToAviUtil {
/**
* 将图片转换成视频
* @param jpgDirPath jpg图片文件夹绝对路径
* @param aviFileName 生成的avi视频文件名
* @param fps 每秒帧数
* @param mWidth 视频的宽度
* @param mHeight 视频的高度
* @throws Exception
*/
public static void convertPicToAvi(String jpgDirPath, String aviFileName, int fps, int mWidth, int mHeight) {
// jpgs目录放置jpg图片,图片文件名为(1.jpg,2.jpg...)
final File[] jpgs = new File(jpgDirPath).listFiles();
if(jpgs==null || jpgs.length==0){
return;
}
// 对文件名进行排序(本示例假定文件名中的数字越小,生成视频的帧数越靠前)
Arrays.sort(jpgs, new Comparator<File>() {
public int compare(File file1, File file2) {
String numberName1 = file1.getName().replace(".jpg", "");
String numberName2 = file2.getName().replace(".jpg", "");
return numberName1.compareTo(numberName2);
}
});
// 生成视频的名称
DefaultMovieInfoProvider dmip = new DefaultMovieInfoProvider(aviFileName);
// 设置每秒帧数
dmip.setFPS(fps>0?fps:3); // 如果未设置,默认为3
// 设置总帧数
dmip.setNumberOfFrames(jpgs.length);
// 设置视频宽和高(最好与图片宽高保持一直)
dmip.setMWidth(mWidth>0?mWidth:1440); // 如果未设置,默认为1440
dmip.setMHeight(mHeight>0?mHeight:860); // 如果未设置,默认为860
try {
new Jim2Mov(new ImageProvider() {
public byte[] getImage(int frame) {
try {
// 设置压缩比
return MovieUtils.convertImageToJPEG((jpgs[frame]), 1.0f);
} catch (IOException e) {
System.err.println(e);
}
return null;
}
}, dmip, null).saveMovie(MovieInfoProvider.TYPE_AVI_MJPEG);
} catch (MovieSaveException e) {
e.printStackTrace();
}
System.out.println("create avi success.");
}
/**
* main
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception {
String jpgDirPath = "D:\\date\\file\\playScreen\\capture\\20180111150516449285223899794475\\"; // jpg文件夹路径
String aviFileName = "file:///D:/date/file/playScreen/capture/test.avi"; // 生成的avi视频文件名(生成路径为本工程)
int fps = 5; // 每秒播放的帧数
int mWidth = 1440; // 视频的宽度
int mHeight = 860; // 视频的高度
PicToAviUtil.convertPicToAvi(jpgDirPath, aviFileName, fps, mWidth, mHeight);
}
}
测试类:
import top.whbweb.screen.recording.config.Config;
import java.awt.*;
public class ScreenRecordTest {
public static void main(String[] args) throws AWTException, InterruptedException {
new ScreenRecordTest().test();
}
public void test() throws AWTException, InterruptedException {
ScreenRecording screenRecordTest = new ScreenRecording();
Config config=new Config();
config.setRectangle(config.getScreenFull());
screenRecordTest.setConfig(config);
screenRecordTest.start();
//wait(1000*20);
screenRecordTest.stop();
}
}
配置文件
import java.awt.*;
public class Config {
public static String SCREEN_FULL="FULL_SCREEN";
public String basePath="D:\\date\\file\\playScreen\\capture\\";
public int frame=45;
public Rectangle rectangle;
public Rectangle getScreenFull() {
return new Rectangle(Toolkit.getDefaultToolkit().getScreenSize());//可以指定捕获屏幕区域
}
public String getBasePath() {
return basePath;
}
public void setBasePath(String basePath) {
this.basePath = basePath;
}
public int getFrame() {
return frame;
}
public void setFrame(int frame) {
this.frame = frame;
}
public Rectangle getRectangle() {
if (rectangle==null)
return getScreenFull();
return rectangle;
}
public void setRectangle(Rectangle rectangle) {
this.rectangle = rectangle;
}
}