用xuggler将BuffereImage组合成视频的java
我正在尝试使用xuggler从BuffereImage列表中制作视频。我遵循了this教程,代码运行得非常完美
但是,当我将示例中的工作代码合并到我的代码中时,我得到一个RuntimeException:
java.lang.RuntimeException: failed to write packet: com.xuggle.xuggler.IPacket@46575264[complete:true;dts:67915;pts:67915;size:24201;key:false;flags:0;stream index:0;duration:1;position:-1;time base:1/65535;] at com.xuggle.mediatool.MediaWriter.writePacket(MediaWriter.java:1215) at com.xuggle.mediatool.MediaWriter.encodeVideo(MediaWriter.java:767) at com.xuggle.mediatool.MediaWriter.encodeVideo(MediaWriter.java:810) at s3.S3CompositeUtil.generateVideo(S3CompositeUtil.java:247) at s3.S3CompositeUtil.main(S3CompositeUtil.java:349)
Xuggler文档提到: 呼叫者必须确保IMediaData。getTimeStamp(),如果指定,则始终是单调递增的,否则将引发RuntimeException
但我不认为我在制作视频时所用的时间在任何时候都会减少
private void generateVideo() {
System.out.println("Creating video...");
String outputMoviePath = "";
IMediaWriter writer = null;
if (allLabels) {
outputMoviePath = TEMP_DIR_PATH + "/" + clipName + "/" + clipName + "_" + "all_labels" + ".avi";
}
else {
outputMoviePath = TEMP_DIR_PATH + "/" + clipName + "/" + clipName + "_" + labels[desiredLabelIdx] + ".avi";
}
writer = ToolFactory.makeWriter(outputMoviePath);
// add one video stream, with position 0 and ID 0, and a frame rate of OUTPUT_MOVIE_FPS
writer.addVideoStream(0, 0, ICodec.ID.CODEC_ID_MPEG4, vidWidth, vidHeight);
long startTime = System.nanoTime();
for (int idxF = 0; idxF < numFrames; idxF++) {
BufferedImage currFrameImg = convertToType(videoBIHolder.get(idxF), BufferedImage.TYPE_3BYTE_BGR);
// BufferedImage currFrameImg = videoBIHolder.get(idxF);
System.out.println("currFrameImg type is " + currFrameImg.getType()); // debug
// encode video to stream at 0
long frameTimeInVideo = System.nanoTime() - startTime;
System.out.println("Time: " + frameTimeInVideo);
writer.encodeVideo(0, currFrameImg, frameTimeInVideo, TimeUnit.NANOSECONDS);
// sleep for millisec. amount of time of the frame rate
try {
Thread.sleep((long) (1000/OUTPUT_MOVIE_FPS)); //OUTPUT_MOVIE_FPS
}
catch (InterruptedException e) {
System.err.println();
}
}
(S3CompositeUtil.java:247)是行
writer.encodeVideo(0, currFrameImg, frameTimeInVideo, TimeUnit.NANOSECONDS);
我需要输出电影FPS为1,但奇怪的是,当它为5时,视频创建没有异常,当它为2时,“视频”只是第一帧(没有其他帧),当它为1时,我得到这个异常
有什么想法吗?我真的很感激能得到的所有帮助
# 1 楼答案
我在我的一个多媒体课上教Xuggler,我的一些学生报告说,在制作定格动画或制作图片幻灯片的视频时出现了类似的问题
我们求助于至少创造2甚至10 FPS。有趣的是,你很可能不会使用太多的内存来存储视频。MPG4编码器足够聪明,只在视频文件中插入基本为空的预测帧,因为在插入全新帧之前,帧之间没有差异
这种方法的唯一缺点是会导致更多的编码开销。显然,在视频流中插入任何帧都会导致CPU负载,即使最终解码器决定只能插入空的预测帧
编辑:事实证明,我们实际上是以每秒25帧的速度在视频中插入帧。尽管存在上述所有不利因素。然而,出于好奇,我做了一个测试,帧速率在10fps到25fps之间,结果发现文件的大小没有显著变化。有趣的是,10fps的测试文件是最大的
静止图像的5秒全高清视频在450kb到580kb的范围内。因此,我建议您尝试一下帧速率,然后选择ffmpeg/Xugler能够为H264处理的最低帧速率(实际上这应该在文档中的某个地方,但我现在找不到)
为了进行测试,我使用了下面的代码再次插入相同的BuffereImage
专业提示:在实际应用中,我们使用一个线程提供图像帧,一个线程执行编码(writer.encodeVideo),这样我们就可以确保达到25 fps的准确帧速率。在您的示例中(以及在我的测试代码中),添加了Xugler/ffmpeg的编码时间