如何在C++中使用FFmpeg流式传输OpenCV Mat?

3
我是一个新手。我正在尝试使用ffmpeg在本地网络上流式传输使用opencv处理的一些图像。 我看到了这个: 将原始OpenCV图像导入FFmpeg 但它对我无效,它只会制造噪音。我认为我发送的数据格式不正确。 我还看了这个: 如何将opencv视频发送到ffmpeg 但是(查看最后一个答案)选项 -f jpeg_pipe 给我带来错误。
现在我该怎么做:
  • 我有一个名为“composedImage”的RGB Mat
  • 我使用以下命令进行输出:
  • std::cout << composedImage; 输出是由逗号分隔的像素值
  • 然后我调用:

./example | ffmpeg -f rawvideo -pixel_format bgr24 -video_size 160x120 -framerate 20 -i - -f udp://192.168.1.79:1234

  • 我尝试使用VLC阅读(它没有起作用),以及ffplay:

ffplay -f rawvideo -pixel_format gray -video_size 160x120 -framerate 30 udp://192.168.1.79:1234

在这里似乎很容易: http://ffmpeg.org/ffmpeg-formats.html#rawvideo 我还尝试过写入图像并发送它,但是出现了错误。 可能它在图像完成之前就尝试发送。
谢谢你的帮助。

你说你遇到了一个错误,但是具体是什么错误呢?此外,我的直觉告诉我你需要将 std::cout 设置为二进制模式才能让它正常工作。 - Stephen Newell
cout << mat 会添加括号和其他东西。 - Micka
你有没有一个例子,其中任何人都使用cout来流式传输帧? - Micka
@micka:不,我没有例子。我甚至不确定流应该是什么样子(ffmepg期望的是什么)。 - cristian b
1个回答

3

我成功地进行了流媒体传输,尽管画质很差,也许某些 ffmpeg 大师能够帮助改进 ffmpeg 命令。

#include <iostream>                                                          
#include <opencv2/opencv.hpp>                                                
#include <vector>                                      

using namespace cv;                                                          

int main() {                                                                 
    VideoCapture cap("Your video or stream goes here");
    Mat frame;                                                               
    std::ios::sync_with_stdio(false);                                        

    while (cap.read(frame)) {                                                
        for (size_t i = 0; i < frame.dataend - frame.datastart; i++) 
           std::cout << frame.data[i];                                   
    }                                                                        

    return 0;                                                                
}                                                                            

然后将其导入到ffmpeg中,像这样:
./test | ffmpeg -f rawvideo -pixel_format bgr24 -video_size 1912x796 -re -framerate 20  -i - -f mpegts -preset ultrafast udp://127.0.0.1:1234

然后使用ffplay、mpv或其他工具进行播放。

ffplay udp://127.0.0.1:1234

谢谢你的回答,这基本上可以,尽管需要做一些更改。我希望我能够正确地实现它。 - cristian b
因此,输出中打印的值是正确的,但在发送流时我遇到了问题,似乎图像的第一个块显示在帧的末尾而不是开头。此时我认为流传输存在问题。 - cristian b
1
@cristianb 你改变分辨率了吗? - aram
是的,我已经将分辨率更改为我的分辨率,但问题不在于此。似乎数据没有很好地编码,或者至少它们的顺序有问题。谢谢。 - cristian b
所以,最终我发现在for循环中添加一个偏移量(该数字是经验性找到的)可以解决问题。虽然不太优雅,但目前来说还可以。 - cristian b

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接