java - FFMpeg 在从 Java 应用程序发送原始像素数据时以错误的帧速率进行压缩

标签 java ffmpeg pipe frame-rate

我正在尝试从一系列原始 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/

相关文章:

java - 如何追踪不同版本文档中段落的增删改查?

java - 通过 Java 中的 OutputStream 发送到 Firefox 的 HTML 代码无法识别

java - 在实际应用程序中使用模拟对象(未测试)

video - ffserver配置文件: RTSPOption

java - Spark 告诉我功能列是错误的

python - FFMPEG 的 xstack 命令导致声音不同步,是否可以在单个编码中混合音频?

javascript - 我如何在另一个 EC2 实例上运行部分代码

xcode - 可执行管道输入?

CTRL+C 和 CTRL+Z 信号在 C 中不会被阻塞

Angular/如何获取api返回数据