如何使用FFMpeg

时间:2017-05-15 12:33:59

标签: c ffmpeg rtsp

我可以使用以下代码监听并接收带有FFMpeg库的一个rtsp流:

AVFormatContext* format_context = NULL
char* url = "rtsp://example.com/in/1";
AVDictionary *options = NULL;
av_dict_set(&options, "rtsp_flags", "listen", 0);
av_dict_set(&options, "rtsp_transport", "tcp", 0);

int status = avformat_open_input(&format_context, url, NULL, &options);
av_dict_free(&options);
if( status >= 0 )
{
    status = avformat_find_stream_info( format_context, NULL);
    if( status >= 0 )
    {
        AVPacket av_packet;
        av_init_packet(&av_packet);

        for(;;)
        {                                                                      
            status = av_read_frame( format_context, &av_packet );
            if( status < 0 )
            {
                break;
            }
        }
    }
    avformat_close_input(&format_context);
}

但如果我尝试同时打开另一个类似的监听器(在另一个线程中使用另一个url),我会收到错误:

  

无法打开RTSP进行收听   rtsp://example.com/in/2:地址已在使用中

看起来avformat_open_input尝试打开前一次调用avformat_open_input已打开的套接字。有没有办法在2个线程之间共享这个套接字?可能是FFMpeg中有一些调度员负责此类任务。

重要提示:在我的情况下,我的应用程序必须充当传入RTSP连接的侦听服务器!它不是连接到另一台RTSP服务器的客户端。

3 个答案:

答案 0 :(得分:2)

如果您希望自己的应用充当侦听将数据发送到多个传入RTSP连接的服务器,则应查看FFserver

以下尝试提供有用的资源信息,以解决问题的标题

  

... 如何使用FFMpeg同时收听2个传入的rtsp流

这个在FFmpeg论坛上询问的人设法从命令行上的两个RTSP流接收数据:http://ffmpeg.gusari.org/viewtopic.php?f=11&t=3246(见3张图片后的文字)。

  

我已经实现的是通过rtsp接收两个流:

     

服务器代码:

ffmpeg -loop 1 -re -i ~/Desktop/background.png -rtsp_flags listen -timeout -1 -i rtsp://localhost:5001/live.mp4 -rtsp_flags listen -timeout -1 -i rtsp://localhost:5002/live.mp4 -filter_complex \
"[1:v] setpts=PTS-STARTPTS [left]; \
[2:v] setpts=PTS-STARTPTS [right]; \
[0:v][left]overlay=0:eof_action=pass:shortest=0 [bgleft]; \
[bgleft][right]overlay=w:eof_action=pass:shortest=0" ~/Desktop/test.mp4
     

我伪造了两个流客户端:

ffmpeg -re -i ~/Desktop/normal.mp4 -f rtsp rtsp://localhost:5001/live.mp4
ffmpeg -re -i ~/Desktop/normal.mp4 -f rtsp rtsp://localhost:5002/live.mp4
     

嗯它以某种方式工作。服务器启动,它正在等待   传入连接。当两个客户端都连接时,ffmpeg   server将流放在一起并在test.mp4中输出它们。如果一个   客户端停止,红色背景出现,视频正在继续。

不幸的是我只在命令行中使用FFmpeg,而不是C库,因此无法提供代码。但这只是访问相同功能的另一种方式。

答案 1 :(得分:0)

我当然对这个库一无所知,但在我看来,通过将你的上下文设置为NULL,你可以得到任何默认值。您可以尝试显式创建上下文。快速浏览文档即表示avformat_alloc_context可能是您正在寻找的内容。

Here's其他人在他们分配上下文的代码中,可能是工作中的确认偏差,但这似乎很重要。

或者,如果面临同样的挑战(并且因为你还没有提供最终游戏细节,我会采取创造性的自由),更简单的方法就是使用ffmpeg / libav&#39; s cli在您的音频设备上拉流和多路复用器。因此,在传入连接上,使用收到的URL生成ffplay。

修改 因此,您将URL传递到avformat_open_input,当您将流推送到您的应用程序时,您实际收到的内容是流的URL,这似乎与您非常相似。否则,你会在其他地方协商RTSP流,然后将其重新调整为ffmpeg,从而做某种恶作剧?这对我没有任何意义,只要让ffmpeg处理它。

如果您可以发布一些内容,那将有助于了解您已实施的内容。

答案 2 :(得分:-2)

您必须检查视频设备信息。原因是并非每个设备都可以流式传输多个。有限制。但大多数设备可能会流式传输到多个频道,如main_stream,channel_1,channel_2,mjpeg_stream等那么你可以同时听不同的频道。这可以解决你的问题。 P.S:频道名称取决于设备的制造商。