public class VideoToPicture {
public static void main(String[] args) throws IOException {
String filename = "D://tmp//4fbe1db0bd9e4a59ab380f262ea305c8.mp4";
String id = UUID.randomUUID().toString().replace("-", "");
String filename2 = "D://tmp//" + id + ".mp4";
String outputFilename = "D://tmp//" + id + ".png";
execute("视频地址", outputFilename, "mp4");
}
public static void base64ToVideo(String base64String, String outputFilename) {
String prefix = "data:video/mp4;base64,";
if (base64String.startsWith(prefix)) {
base64String = base64String.replace(prefix, "");
}
byte[] decodedData = Base64.getDecoder().decode(base64String);
FileOutputStream fos = null;
try {
fos = new FileOutputStream(outputFilename);
fos.write(decodedData);
fos.flush();
fos.close();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
* 视频文件截图转图片存储
*
* @param inputFilename 视频文件
* @param outputFilename 图片输出地址
* @param format 音频格式
*/
public static void execute(String inputFilename, String outputFilename, String format) {
Assert.hasText(inputFilename, "音频文件不能为空");
Assert.hasText(outputFilename, "图片地址不能为空");
Assert.hasText(format, "音频格式不能为空");
IContainer container = IContainer.make();
IContainerFormat containerFormat = IContainerFormat.make();
containerFormat.setInputFormat(format);
boolean notOpen = false;
try {
notOpen = container.open(inputFilename, IContainer.Type.READ, containerFormat) < 0;
} catch (Exception e) {
e.printStackTrace();
throw new IllegalArgumentException("Could not open file: " + inputFilename);
}
if (notOpen) {
throw new IllegalArgumentException("Could not open file: " + inputFilename);
}
int numStreams = container.getNumStreams();
int videoStreamId = -1;
IStreamCoder videoCoder = null;
for (int i = 0; i < numStreams; i++) {
IStream stream = container.getStream(i);
IStreamCoder coder = stream.getStreamCoder();
if (coder.getCodecType() == ICodec.Type.CODEC_TYPE_VIDEO) {
videoStreamId = i;
videoCoder = coder;
break;
}
}
if (videoStreamId == -1) {
throw new RuntimeException("No video stream in container: " + inputFilename);
}
if (videoCoder.open() < 0) {
throw new RuntimeException("Could not open video coder for container: " + inputFilename);
}
IVideoPicture picture = IVideoPicture.make(videoCoder.getPixelType(), videoCoder.getWidth(), videoCoder.getHeight());
IPacket packet = IPacket.make();
boolean isStop = false;
while (!isStop && container.readNextPacket(packet) >= 0) {
if (packet.getStreamIndex() == videoStreamId) {
int offset = 0;
while (offset < packet.getSize()) {
int bytesDecoded = videoCoder.decodeVideo(picture, packet, offset);
if (bytesDecoded < 0) {
throw new RuntimeException("Error decoding video");
}
offset += bytesDecoded;
if (picture.isComplete()) {
if (picture.getTimeStamp() > 1000) {
IConverter converter = ConverterFactory.createConverter("XUGGLER-BGR-24", picture);
BufferedImage javaImage = converter.toImage(picture);
try {
ImageIO.write(javaImage, "PNG", new File(outputFilename));
} catch (IOException e) {
e.printStackTrace();
}
isStop = true;
break;
}
}
}
}
}
videoCoder.close();
container.close();
}
}
视频截屏(视频转图片)
XT46252024-04-27 17:54
相关推荐
sinat_262292116 分钟前
Java面试实战:音视频场景下的微服务架构与缓存技术剖析mask哥10 分钟前
详解springcloudalibaba采用prometheus+grafana实现服务监控振鹏Dong12 分钟前
Java基础&集合 面试经典八股总结 [连载ing]不当菜虚困4 小时前
JAVA设计模式——(二)组合模式jack_xu5 小时前
经典大厂面试题——缓存穿透、缓存击穿、缓存雪崩CHQIUU6 小时前
Java 设计模式心法之第4篇 - 单例 (Singleton) 的正确打开方式与避坑指南碎梦归途6 小时前
23种设计模式-结构型模式之享元模式(Java版本)lozhyf7 小时前
Eureka搭建幽络源小助理7 小时前
SpringBoot民宿管理系统开发实现东阳马生架构7 小时前
Nacos简介—1.Nacos使用简介