RTSP通过HTTP隧道传输,FFMPEG

4

我正在尝试从使用RTSP over HTTP的Axis IP摄像机进行流媒体传输。我可以得到正常的RTSP流工作,但是我找不到任何关于如何设置流的隧道模式的信息或文档。通过将控制传输设置为RTSP_MODE_TUNNEL,源代码支持此功能。我的问题很简单,如何在以下代码中实现它?

 int ret = avformat_open_input(&pFormatCtx, [@"rtsp://ip/axis-media/media.amp" UTF8String], NULL, NULL);

我尝试了以下方法:

pFormatCtx = avformat_alloc_context();
pFormatCtx->priv_data = malloc(sizeof(RTSPState));
RTSPState *rt = pFormatCtx->priv_data;
rt->control_transport = RTSP_MODE_TUNNEL;
int ret = avformat_open_input(&pFormatCtx, [@"rtsp://ip/axis-media/media.amp" UTF8String], NULL, NULL);

但是对于我来说它简单地忽略了它(仍然继续使用RTP)。我也尝试过这个方法。
 int ret = avformat_open_input(&pFormatCtx, [@"rtsp://ip/axis-media/media.amp" UTF8String], NULL, NULL);
RTSPState *rt = pFormatCtx->priv_data;
rt->control_transport = RTSP_MODE_TUNNEL;

我该如何解决这个问题?我认为由于ENUM已经存在,所以可能是一些非常简单的东西。

有效的解决方案是

AVDictionary *opts = 0;
int ret = av_dict_set(&opts, "rtsp_transport", "http", 0);


ret = avformat_open_input(&pFormatCtx, [@"rtsp://ip:80/axis-media/media.amp" UTF8String], NULL, &opts);

av_dict_free(&opts);
1个回答

10

你试过这个了吗?

AVDictionary *opts = 0;
    if (usesTcp) {
        int ret = av_dict_set(&opts, "rtsp_transport", "tcp", 0);
    }


    err = avformat_open_input(&avfContext, filename, NULL, &opts);
    av_dict_free(&opts);

谢谢!运行得非常好。在查看此问题时,您的stackoverflow和公司博客提供了许多有用的信息。 - Jon Andersen
@Michelle Cannon:你是如何设置 usesTcp 标志的?有没有办法找出 RTSP 流是通过 tcp、http 还是 udp 传输的? - Tushar Koul
我们手动设置它,因为通常知道我们想要什么。 主要问题是,在打开输入流后,它完全掌握在ffmpeg的手中。 所以你有一些选择,但它们非常少。(1) 为ffmpeg创建自定义IO处理程序。 (2) 在尝试连接后使用钩子修改ffmpeg。或者我们一直非常成功地使用“隧道”来获取流,然后再将其传递给播放器。 我们一直在使用本地live 555代理实现。 因此,在将其交给streamMorePlay播放器之前,我们可以自由发挥。 - Michelle Cannon
我们非常乐意帮助开发者,所以请随时与我们联系。 - Michelle Cannon
顺便提一下,似乎有一堆avformat_open_input选项在https://www.ffmpeg.org/ffmpeg-protocols.html#rtsp上有文档记录。对于rtsp_transport,看起来它接受“udp”,“tcp”,“http”和“udp_multicast”。还有“prefer_tcp”选项用于“rtsp_flags”,如果无法连接,则首先尝试TCP,然后尝试UDP。我已经确认“rtsp_transport”值至少在libav 11.7中有效(顺便测试了Axis相机)。 - Jason C

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