gpt4 book ai didi

java - 从 ffmpeg 的标准输出读取的图像有时确实会变得困惑。为什么?

转载 作者:行者123 更新时间:2023-12-01 12:09:32 26 4
gpt4 key购买 nike

我正在尝试使用 ffmpeg 将视频转换为图像,然后在 Java 程序中读取这些图像,将它们转换为文件(这只是为了测试,我知道 ffmpeg 也可以做到)。这在大多数情况下都工作得很好,除了一些图像被 ffmpeg 打乱,我不知道为什么。是我的代码有问题,还是 ffmpeg 的怪癖?

ffmpeg 有时会在这种奇怪的转换后恢复,而有时它会继续产生垃圾。这就是好图像和坏图像的样子,在两者之间拍摄一秒钟:Good. Bad.

这是我正在使用的代码。

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 堆栈跟踪,它们可能会提供一些有用的信息。尽管我使用 PNG 进行输出,但它们引用的是 JPEG。

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)

最佳答案

我遇到了同样的问题,并查看了 FFmpeg 的输出。在实际的 PNG 数据之间,FFmpeg 似乎写入了额外的字节(大多数情况下为 16 个字节),包括字符串“END”。我不是 PNG 文件格式的专家,也许这些字节实际上属于 PNG,但 ImageIO 不会读取它们。因此,下一个 PNG 图像的偏移量是不正确的,ImageIO 读取器迟早会遇到问题。

一个有用的讨论是 https://stackoverflow.com/a/13777398/518491 。它指出 ImageIO 在读取一个流中的多个图像时存在问题。它包含此问题的解决方案,但没有提到 PNG 图像之间的附加字节。

我可以通过执行以下操作来解决该问题:

  1. 将 FFmpeg 输出包装到 BufferedInputStream
  2. 标记流
  3. 对于每个图像,转到下一个 PNG header 的开头,即跳过所有字节,直到找到 PNG header 0x89、0x50、0x4E、0x47、0x0D、0x0A、0x1A、0x0A。重置并跳过流,直到它回到 header 的第一个字节 (0x89)
  4. 像链接文章中一样读取图像(ImageIO.createImageInputStream、ImageReader,...)
  5. 跳过 PNG 图像的所有字节 (getStreamPosition) 并再次标记流
  6. 继续第 3 步

关于java - 从 ffmpeg 的标准输出读取的图像有时确实会变得困惑。为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27341819/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com