我正在尝试从一系列原始 rgb24 像素数据创建一个压缩的 h264 视频文件。 像素数据从 Java 应用程序流式传输到作为其子进程的 ffmpeg.exe。
出于测试目的,我创建了一个包含 rgb24 像素数据的字节数组,然后将其发送到 ffmpeg 的输入流。
除一个问题外,一切正常。
看起来编码文件的帧率是错误的。 FFMpeg 应以 30fps 的速率 (-r 30) 压缩视频文件。
我正在发送 30*20 帧。所以我应该得到一个长度为 20 秒的视频文件。 但取而代之的是视频文件的长度是 24 秒。 当我检查压缩文件属性时,它按预期显示 30fps。
看起来预期帧速率和实际帧速率之间的比率是 5 到 6 (20 --> 24,30 --> 36)。 我也尝试过流式传输 rgb32 像素数据,但我得到了相同的结果。
代码:
ByteArrayOutputStream byteArray = new ByteArrayOutputStream();
//building the frame
for (int i=0; i<1024*800; i++)
{
byteArray.write(i&0xFF); //r
byteArray.write(i&0xFF); //g
byteArray.write(i&0xFF); //b
}
byte pixelData[] = byteArray.toByteArray();
File ffmpeg_output_msg = new File("ffmpeg_output_msg.txt");
ProcessBuilder pb = new ProcessBuilder("ffmpeg.exe","-vcodec","rawvideo","-f","rawvideo","-pix_fmt","rgb24","-s","1024x800","-i","pipe:0","-r","30","-y","-c:v","libx264","out.mkv");
pb.redirectErrorStream(true);
pb.redirectOutput(ffmpeg_output_msg);
Process p = pb.start();
OutputStream ffmpegInput = p.getOutputStream();
//30fps, 20secs
for(int i=0;i<30*20;i++)
{
ffmpegInput.write(pixelData);
}
ffmpegInput.flush();
ffmpegInput.close();
任何想法可能是该问题的根源? 提前致谢
更新 我已将帧速率更改为其他值,看起来 ffmpeg 完全忽略了该参数。它始终使用 25fps。 使用“-r 30”仅影响写入文件属性的数据 (视频:MPEG4 视频 (H264) 1024x800 30fps [视频])
编码文件中是否有可能存在两种不同的帧率?
最佳答案
好的,解决了。
我必须在输出和输入 流上强制使用 fps。 在 -i 之前添加 -r 30,告诉 ffmpeg 输入流具有 30 fps 的速率。
最终的 ffmpeg:
ffmpeg.exe -r 30 -vcodec rawvideo -f rawvideo -pix_fmt rgb24 -s 1024x800 -i pipe:0 -y -c:v libx264 -r 30 out.mkv
关于java - FFMpeg 在从 Java 应用程序发送原始像素数据时以错误的帧速率进行压缩,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21059976/