2017-05-15 79 views
4

我可以聽,並使用此代碼與FFmpeg的庫收到一個RTSP流:怎麼聽2個進入RTSP流在同一時間與FFmpeg的

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另一個線程),我得到錯誤:

Unable to open RTSP for listening rtsp://example.com/in/2: Address already in use

它看起來像avformat_open_input試圖打開這已經是由avformat_open_input以前調用打開插座。有沒有什麼辦法在2個線程之間共享這個套接字?可能在FFMpeg中有一些調度器用於這樣的任務。

重要注意事項:就我而言,我的應用程序必須作爲傳入RTSP連接的偵聽服務器!它不是連接到另一臺RTSP服務器的客戶端。

+0

如果我理解正確,主RTSP套接字僅用於命令消息,並且在底層級別的RTSP中,所有數據都是在不干擾的獨立RTP流中發送的。所以單獨處理這些流並不困難。 –

+1

它看起來不像FFmpeg允許您直接訪問套接字。但是,您可能可以使用['async'協議處理程序](https://ffmpeg.org/ffmpeg-protocols.html#async)執行此任務。我對代碼不太熟悉,所以不會提供這個答案。我很抱歉誤解你的問題。 – dho

+0

異步協議處理程序看起來很有趣。謝謝 –

回答

-2

您必須檢查視頻設備信息。原因是不是每個設備都可以流式傳輸多個。有限制。但大多數設備可能流式傳輸到多個通道,例如main_stream,channel_1,channel_2,mjpeg_stream等等。所以你可以同時聽不同的頻道。這可以解決你的問題。 P.S:通道名稱取決於設備的製造商。

+0

我不會嘗試傳輸任何東西。我嘗試同時收到多個視頻。我可以在不同的接口(即不同的IP地址)上成功接收它們,但不能在一個接口上接收它們。 P.S.我使用普通的Linux服務器沒有嵌入。 –

0

我承認對圖書館一無所知,但在我看來,通過將您的上下文設置爲NULL,您將得到任何默認值。您可以嘗試明確創建一個上下文。快速瀏覽文檔建議avformat_alloc_context可能是您正在尋找的。

Here'sHere's別人的代碼在哪裏分配上下文,可能是工作中的確認偏差,但這似乎很重要。或者,如果面臨相同的挑戰(並且因爲你沒有提供遊戲結束的細節,我正在採取創造性的自由),一個更簡單的方法可能是使用ffmpeg/libav的cli來提取流,您的音頻設備上的多路複用器。所以在傳入的連接上,產生一個ffplay與收到的URL。

編輯: 所以,你傳遞一個網址爲avformat_open_input,似乎是一個可怕的很多喜歡你時,你說流推送到您的應用程序,您實際收到是一個URL到流。否則,你會做一些與其他地方談判RTSP流的惡作劇,然後將它重新調整爲ffmpeg?這對我沒有任何意義,只是讓ffmpeg來處理它。

這將有助於看到你已經實施了,如果你可以發佈一些。

+0

1.對於網絡資源,通常將format_context = NULL設置爲avformat_open_input。即使我自己創建AVFormatContext,也沒有辦法像控制帶有pb字段的文件IO一樣控制網絡IO。 2.我無法從任何地方拉流,因爲流被推送到我的應用程序。請參閱問題末尾的註釋。 –

2

你應該看看FFserver如果你希望你的應用程序作爲服務器監聽發送數據多個來電RTSP連接。

下面試圖提供有用的資源信息來解決標題的問題。

..."How to listen to 2 incoming rtsp streams at the same time with FFMpeg"

這傢伙要求上FFmpeg的論壇管理從兩個RTSP命令行上的流接收數據:http://ffmpeg.gusari.org/viewtopic.php?f=11&t=3246(見3張圖像後的文本)。

What I already achieved is to receive two streams via rtsp:

Server code :

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 

and I faked two stream clients with :

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 

Well it's working somehow. The Server starts and it's waiting for incoming connections. When both clients are connected, the ffmpeg server puts the streams together and outputs them in test.mp4. If one client stops, the red background appears and the video is continuing.

不幸的是我只在命令行中使用FFmpeg的,而不是作爲一個C庫,所以無法提供的代碼。但這只是訪問相同功能的一種不同方式。

+0

使用不同的端口進行監聽可能是一種選擇,但在這種情況下,遠程客戶端必須知道使用哪個端口,或者如果連接失敗,則需要某種回退來更改端口。不幸的是,我不能修改客戶端軟件。 –