之前一直想找一份可以实现Java操作视频文件的代码,找了很久,看到网上的都是很离散的一些功能实现,所以现在收集并整理了具体的功能实现,具体如下代码:
maven依赖:
<dependency>
<groupId>org.bytedeco</groupId>
<artifactId>javacv</artifactId>
<version>1.5</version>
</dependency>
<dependency>
<groupId>org.bytedeco</groupId>
<artifactId>javacv-platform</artifactId>
<version>1.5</version>
</dependency>
<dependency>
<groupId>org.bytedeco</groupId>
<artifactId>javacpp</artifactId>
<version>1.5</version>
</dependency>
<dependency>
<groupId>org.bytedeco.javacpp-presets</groupId>
<artifactId>opencv-platform</artifactId>
<version>4.0.1-1.4.4</version>
</dependency>
<dependency>
<groupId>org.bytedeco.javacpp-presets</groupId>
<artifactId>ffmpeg-platform</artifactId>
<version>4.1-1.4.4</version>
</dependency>
具体的实现工具类如下:
/**
* @author zhq.xiang
*/
public class VedioUtils {
/**
* 截取视频的第一帧图片
*
* @param videoFile 可以用 inputStream 代替
* @param outputStream
*/
public static void fetchFrame(File videoFile, OutputStream outputStream, String outFormatName) {
FFmpegFrameGrabber ff = null;
FileInputStream fis = null;
try {
fis = new FileInputStream(videoFile);
ff = new FFmpegFrameGrabber(fis);
ff.start();
int length = ff.getLengthInFrames();
int i = 0;
Frame frame = null;
while (i < length) {
// 过滤前5帧,避免出现全黑的图片,依自己情况而定
frame = ff.grabFrame();
if ((i > 5) && (frame.image != null)) {
break;
}
i++;
}
Java2DFrameConverter converter = new Java2DFrameConverter();
BufferedImage bi = converter.getBufferedImage(frame);
ImageIO.write(bi, outFormatName, outputStream);
} catch (Exception e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if(fis != null){
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
try {
if (ff != null) {
ff.stop();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
/**
* 获取视频时长 单位/秒
*
* @param video 可以用inputStream代替
* @return
*/
public static long getVideoDuration(File video) {
long duration = 0L;
FFmpegFrameGrabber ff = null;
FileInputStream fis = null;
try {
fis = new FileInputStream(video);
ff = new FFmpegFrameGrabber(fis);
ff.start();
duration = ff.getLengthInTime() / (1000 * 1000);
return duration;
} catch (FrameGrabber.Exception e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
}finally {
if(fis != null){
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(ff != null){
try {
ff.stop();
} catch (Exception e) {
e.printStackTrace();
}
}
}
return 0L;
}
/**
* 转换视频文件为mp4
*
* @param file 可以用inputStream代替
* @return
*/
public static String convert2Mp4(File file) {
FFmpegFrameGrabber frameGrabber = null;
Frame capturedFrame = null;
FFmpegFrameRecorder recorder = null;
FileInputStream fis = null;
try {
fis = new FileInputStream(file);
frameGrabber = new FFmpegFrameGrabber(fis);
frameGrabber.start();
String fileName = file.getAbsolutePath() + "__.mp4";
recorder = new FFmpegFrameRecorder(fileName, frameGrabber.getImageWidth(), frameGrabber.getImageHeight(),
frameGrabber.getAudioChannels());
//avcodec.AV_CODEC_ID_H264 清晰度较低 //AV_CODEC_ID_MPEG4 清晰度更高
recorder.setVideoCodec(avcodec.AV_CODEC_ID_MPEG4);
recorder.setFormat("mp4");
recorder.setFrameRate(frameGrabber.getFrameRate());
recorder.setSampleRate(frameGrabber.getSampleRate());
recorder.setAudioChannels(frameGrabber.getAudioChannels());
recorder.setFrameRate(frameGrabber.getFrameRate());
recorder.start();
while ((capturedFrame = frameGrabber.grabFrame()) != null) {
recorder.setTimestamp(frameGrabber.getTimestamp());
recorder.record(capturedFrame);
}
return fileName;
} catch (Exception e) {
e.printStackTrace();
} catch (FrameRecorder.Exception e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
if(fis != null){
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(recorder != null) {
try {
recorder.stop();
recorder.release();
} catch (FrameRecorder.Exception e) {
e.printStackTrace();
}
}
if(frameGrabber != null) {
try {
frameGrabber.stop();
} catch (Exception e) {
e.printStackTrace();
}
}
}
return null;
}
public static void main(String[] args) {
File file = new File("/Users/xiangzhongqiang/Downloads/hailuo_20783575_RF.mov");
String destPath = "/Users/xiangzhongqiang/Downloads/1111.jpg";
FileOutputStream fos = null;
try {
fos = new FileOutputStream(destPath);
fetchFrame(file, fos,
destPath.substring(destPath.indexOf(Constants.SYMBOL_DOT)).replaceAll("\\" + Constants.SYMBOL_DOT, ""));
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
convert2Mp4(file);
}
}