Commit cfaac590 authored by yanzg's avatar yanzg

视频压缩

parent 725262b1
......@@ -18,18 +18,24 @@
<artifactId>junit</artifactId>
</dependency>
<dependency>
<groupId>org.bytedeco</groupId>
<artifactId>javacv</artifactId>
<version>1.5.3</version>
</dependency>
<!--<dependency>-->
<!--<groupId>org.bytedeco</groupId>-->
<!--<artifactId>javacv</artifactId>-->
<!--<version>1.4.3</version>-->
<!--</dependency>-->
<!--<dependency>-->
<!--<groupId>org.bytedeco.javacpp-presets</groupId>-->
<!--<artifactId>ffmpeg-platform</artifactId>-->
<!--<version>4.0.2-1.4.3</version>-->
<!--</dependency>-->
<dependency>
<groupId>org.bytedeco</groupId>
<artifactId>javacv</artifactId>
<version>1.5.3</version>
</dependency>
<dependency>
<groupId>org.bytedeco</groupId>
<artifactId>ffmpeg-platform</artifactId>
......
package com.yanzuoguang.util;
import java.awt.*;
import java.awt.image.BufferedImage;
/**
* 图片旋转工具类
*
* @author 颜佐光
*/
public class ImageRotate {
/**
* 对图片进行旋转
*
* @param src 被旋转图片
* @param angel 旋转角度
* @return 旋转后的图片
*/
public static BufferedImage rotate(Image src, int angel) {
int src_width = src.getWidth(null);
int src_height = src.getHeight(null);
// 计算旋转后图片的尺寸
Rectangle rect_des = calcRotatedSize(new Rectangle(new Dimension(src_width, src_height)), angel);
BufferedImage res = new BufferedImage(rect_des.width, rect_des.height, BufferedImage.TYPE_INT_RGB);
Graphics2D g2 = res.createGraphics();
// 进行转换
g2.translate((rect_des.width - src_width) / 2,
(rect_des.height - src_height) / 2);
g2.rotate(Math.toRadians(angel), src_width / 2, src_height / 2);
g2.drawImage(src, null, null);
return res;
}
/**
* 计算旋转后的图片
*
* @param src 被旋转的图片
* @param angel 旋转角度
* @return 旋转后的图片
*/
public static Rectangle calcRotatedSize(Rectangle src, int angel) {
// 如果旋转的角度大于90度做相应的转换
if (angel >= 90) {
if (angel / 90 % 2 == 1) {
int temp = src.height;
src.height = src.width;
src.width = temp;
}
angel = angel % 90;
}
double r = Math.sqrt(src.height * src.height + src.width * src.width) / 2;
double len = 2 * Math.sin(Math.toRadians(angel) / 2) * r;
double angel_alpha = (Math.PI - Math.toRadians(angel)) / 2;
double angel_dalta_width = Math.atan((double) src.height / src.width);
double angel_dalta_height = Math.atan((double) src.width / src.height);
int len_dalta_width = (int) (len * Math.cos(Math.PI - angel_alpha
- angel_dalta_width));
int len_dalta_height = (int) (len * Math.cos(Math.PI - angel_alpha
- angel_dalta_height));
int des_width = src.width + len_dalta_width * 2;
int des_height = src.height + len_dalta_height * 2;
return new Rectangle(new Dimension(des_width, des_height));
}
}
......@@ -140,7 +140,7 @@ public class MediaHelper extends ImageHelper {
// 源文件判断
File source = new File(fromFile);
if (!source.exists()) {
throw new RuntimeException("视频转码压缩时不存在");
throw new RuntimeException("视频转码压缩时文件不存在:" + fromFile);
}
File target = new File(toFile);
if (!target.getParentFile().exists()) {
......@@ -177,40 +177,32 @@ public class MediaHelper extends ImageHelper {
* @throws IOException
*/
public static void getGrabberFFmpegImage(String filePath, String toFile, String type, int index) throws IOException {
File file2 = new File(filePath);
if (file2.exists()) {
throw new RuntimeException("视频文件" + filePath + "不存在");
}
// 初始化文件
initFile(filePath, toFile);
FFmpegFrameGrabber grabber = new FFmpegFrameGrabber(filePath);
MediaParameter parameter = new MediaParameter();
try {
// 打开视频
grabber.start();
parameter.init(grabber);
double rotate = parameter.getVideoRotateFinally();
// 整个视频的长度
int ffLength = grabber.getLengthInFrames();
// 取得能够取得的帧数
index = Math.min(ffLength, index);
for (int i = 0; i <= ffLength; i++) {
Frame f = grabber.grabImage();
if (i == index) {
// 判断是否需要旋转
if (rotate != 0) {
// 旋转角度,防止图像不正确
OpenCVFrameConverter.ToIplImage converter = new OpenCVFrameConverter.ToIplImage();
IplImage src = converter.convert(f);
f = converter.convert(rotate(src, rotate));
}
doExecuteFrame(f, toFile, type);
Frame f;
for (int i = 0; i < ffLength; i++) {
f = grabber.grabImage();
if (i >= index) {
doExecuteFrame(f, toFile, type, rotate);
break;
}
}
} finally {
grabber.close();
grabber.stop();
}
}
......@@ -237,13 +229,17 @@ public class MediaHelper extends ImageHelper {
* @param f 帧
* @param targetFilePath 封面图片
* @param type 封面图片类型
* @param type 旋转角度
*/
public static void doExecuteFrame(Frame f, String targetFilePath, String type) throws IOException {
public static void doExecuteFrame(Frame f, String targetFilePath, String type, double rotate) throws IOException {
if (null == f || null == f.image) {
return;
}
Java2DFrameConverter converter = new Java2DFrameConverter();
BufferedImage bi = converter.getBufferedImage(f);
if (rotate > 0) {
bi = ImageRotate.rotate(bi, (int) rotate);
}
File output = new File(targetFilePath);
ImageIO.write(bi, type, output);
}
......
......@@ -10,7 +10,6 @@ import org.bytedeco.javacv.FFmpegFrameRecorder;
import static org.bytedeco.ffmpeg.global.avcodec.*;
import static org.bytedeco.ffmpeg.global.avutil.*;
/**
* 压缩视频参数
*
......
......@@ -9,7 +9,6 @@ import java.io.IOException;
public class TestMediaHelper {
private boolean isFirstImage = false;
public float[] sizes = new float[]{1f, 0.5f, 1f, 1f, 0.5f, 0.5f};
public float[] quotes = new float[]{1f, 1f, 0.5f, 0.25f, 0.5f, 0.25f};
public String[] fileNames = new String[]{"100M.mp4", "z001594372388232a3017ad69c82a342.MOV", "xuziming.mp4"};
......@@ -56,6 +55,20 @@ public class TestMediaHelper {
testConvert(fileName, new MediaParameter(0.01f, 0.01f));
}
@Test
public void testVideoFirstImage() throws IOException {
String file = getFile("100M.mp4");
String targetFile = getTargetFile("target/100M.mp4");
MediaHelper.getVideoFirstImage(file, targetFile + ".jpg");
}
@Test
public void testVideoFirstImage1() throws IOException {
String file = getFile("xuziming.mp4");
String targetFile = getTargetFile("target/xuziming.mp4");
MediaHelper.getVideoFirstImage(file, targetFile + ".jpg");
}
/**
* 按照微信的压缩标准
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment