之前一直想找一份可以實現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);
}
}