我正在尝试使用ffmpeg将视频转换为图像,然后在Java程序中读取这些图像,将它们转换为文件(仅用于测试,我知道ffmpeg也可以这样做)。这在大多数情况下工作正常,除了一些图像被ffmpeg扰乱,我不知道为什么。我的代码有问题,还是一个ffmpeg怪癖?
ffmpeg有时会在这种奇怪的转换后恢复,而其他时候它会继续产生垃圾。这是一个好的和坏的图像看起来的方式,介于两者之间:
这是我正在使用的代码。
process = new ProcessBuilder(ffmpeg, "-i", "C:\myvideo.mpeg", "-r", "1", "-f", "image2pipe", "-c", "png", "-").start();
imageStream = process.getInputStream();
BufferedImage imageBuffer = ImageIO.read(imageStream);
while(imageStream.available() > 0)
{
try
{
imageBuffer = ImageIO.read(imageStream);
}
catch (Exception e)
{
e.printStackTrace();
}
if(imageBuffer != null)
{
try
{
File outputfile = new File("c:\\image.png");
ImageIO.write(imageBuffer, "png", outputfile);
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
我确实得到了一些可能提供一些有用信息的Java堆栈跟踪。它们指的是JPEG,虽然我使用PNG输出。
javax.imageio.IIOException: Unsupported JPEG process: SOF type 0xc7
at com.sun.imageio.plugins.jpeg.JPEGImageReader.readImageHeader(Native Method)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.readNativeHeader(Unknown Source)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.checkTablesOnly(Unknown Source)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.gotoImage(Unknown Source)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.readHeader(Unknown Source)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.readInternal(Unknown Source)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.read(Unknown Source)
at javax.imageio.ImageIO.read(Unknown Source)
at javax.imageio.ImageIO.read(Unknown Source)
at FilmConverter$1.run(FilmConverter.java:178)
javax.imageio.IIOException: Bogus DQT index 6
at com.sun.imageio.plugins.jpeg.JPEGImageReader.readImageHeader(Native Method)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.readNativeHeader(Unknown Source)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.checkTablesOnly(Unknown Source)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.gotoImage(Unknown Source)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.readHeader(Unknown Source)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.readInternal(Unknown Source)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.read(Unknown Source)
at javax.imageio.ImageIO.read(Unknown Source)
at javax.imageio.ImageIO.read(Unknown Source)
at FilmConverter$1.run(FilmConverter.java:178)
javax.imageio.IIOException: Unsupported JPEG process: SOF type 0xce
at com.sun.imageio.plugins.jpeg.JPEGImageReader.readImageHeader(Native Method)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.readNativeHeader(Unknown Source)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.checkTablesOnly(Unknown Source)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.gotoImage(Unknown Source)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.readHeader(Unknown Source)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.readInternal(Unknown Source)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.read(Unknown Source)
at javax.imageio.ImageIO.read(Unknown Source)
at javax.imageio.ImageIO.read(Unknown Source)
at FilmConverter$1.run(FilmConverter.java:178)
java.lang.RuntimeException: New BMP version not implemented yet.
at com.sun.imageio.plugins.bmp.BMPImageReader.readHeader(Unknown Source)
at com.sun.imageio.plugins.bmp.BMPImageReader.read(Unknown Source)
at javax.imageio.ImageIO.read(Unknown Source)
at javax.imageio.ImageIO.read(Unknown Source)
at FilmConverter$1.run(FilmConverter.java:178)
答案 0 :(得分:1)
我遇到了同样的问题并查看了FFmpeg的输出。在实际的PNG数据之间,FFmpeg似乎写入了额外的字节(大多数时间为16字节),包括字符串“END”。我不是PNG文件格式的专家,也许这些字节实际上属于PNG,但是ImageIO不会读取它们。因此,下一个PNG图像的偏移量不正确,并且ImageIO读取器迟早会遇到问题。
有用的讨论是https://stackoverflow.com/a/13777398/518491。它指出ImageIO在一个流中读取多个图像存在问题。它包含了解决此问题的方法,但是没有PNG图像之间提到的额外字节。
我可以通过执行以下操作来解决问题: