2012-07-25 70 views
17

ffmpeg將RTMP流處理爲輸入或輸出,並且運行良好。使用FFMPEG將視頻文件連續流傳輸到RTMP服務器

我想將一些視頻(由python腳本管理的動態播放列表)流式傳輸到RTMP服務器,而我目前正在做一些非常簡單的事情:使用FFMPEG將我的視頻一個接一個地傳輸到RTMP服務器,但是,每次視頻結束時都會導致連接中斷,並且當下一個視頻開始時,流就準備好了。

我想連續播放這些視頻而沒有任何連接斷開,然後可以正確查看該視頻流。

我使用這個命令通過一個流我的影片之一

ffmpeg -re -y -i myvideo.mp4 -vcodec libx264 -b:v 600k -r 25 -s 640x360 \ 
-filter:v yadif -ab 64k -ac 1 -ar 44100 -f flv \ 
"rtmp://mystreamingserver/app/streamName" 

我找了一些解決方法在互聯網上很多天的服務器,我發現一些人在談論使用命名管道作爲輸入在ffmpeg中,我已經嘗試過了,它不能正常工作,因爲ffmpeg不僅在關閉RTMP視頻流時關閉了新視頻,而且還關閉了它自己。

有沒有辦法做到這一點? (流的視頻動態播放列表與ffmpeg到RTMP服務器,而無需連接中斷

+1

使用命名管道是正確的選擇。你能詳細說明這不適合你嗎? – blahdiblah 2012-07-25 22:13:43

+0

@blahdiblah我使用了命名管道作爲ffmpeg的輸入,ffmpeg暫停並等待管道中的一些數據,然後我嘗試了'cat video.mp4> fifo'和ffmpeg開始流式傳輸並在流式傳輸視頻後退出。我認爲我不知道如何使用正確的方式命名管道,當我做'cat video1.mp4 video2.mp4> fifo' ffmpeg顯示錯誤'流4,偏移0x1d83c:部分文件'後流第一個視頻。我知道這是我做錯了,我必須通過管道以適當的方式傳遞視頻數據。 – KKetch 2012-07-26 07:41:11

+1

我設法通過使用每個視頻管道(ex vid1.mp4 - > pipe1,vid2.mp4 - > pipe2等)來流式傳輸視頻的靜態播放列表。然後我寫入一個名爲管道「流」的流,這種方式'cat pipe1 pipe2 pipe3> stream',並且我使用流管道作爲FFMPEG中的輸入來發布我的流,但是因爲我正在尋找一個動態播放列表**我發送更多視頻到「流」管道,以保持該流?**我還沒有弄清楚。 (注意,除了第一個視頻,我不得不使用tail命令剪切每個視頻文件的元數據以獲得這個工作) – KKetch 2012-07-28 14:53:07

回答

6

更新(因爲我不能刪除接受的答案):適當的解決方案是實現一個自定義解複用器,類似於CONCAT之一。目前還沒有任何其他清潔的方式。你必須讓你的手髒與代碼!

下面是一個醜陋的黑客攻擊,這是一個非常糟糕的方式做到這一點,只是不!

解決方案使用串聯分路器並假定您的所有源媒體文件es使用相同的編解碼器。這個例子是基於MPEG-TS的,但是對於RTMP也是一樣的。

  1. 製作一個播放列表文件抱着一個巨大的入口點列表,您的動態播放列表,格式如下:

    file 'item_1.ts' file 'item_2.ts' file 'item_3.ts' [...] file 'item_[ENOUGH_FOR_A_LIFETIME].ts'

    這些文件只是佔位符。

  2. 製作一個腳本,跟蹤你當前播放列表索引,並創建符號鏈接的即時爲current_index + 1

    ln -s /path/to/what/to/play/next.ts item_1.ts

    ln -s /path/to/what/to/play/next.ts item_2.ts

    ln -s /path/to/what/to/play/next.ts item_3.ts

    [...]

  3. 開始播放 ffmpeg -f concat -i playlist.txt -c copy output -f mpegts udp://<ip>:<port>

  4. 被憤怒的系統管理員

+0

謝謝,剛纔看到你的回答。我早先就用hinekyle的評論來解決它,即使我現在對這類黑客不感興趣 – KKetch 2015-09-01 13:59:24

+0

你能詳細說明你的意思嗎?製作一個跟蹤你當前播放列表索引並創建符號鏈接的腳本,爲current_index + 1'飛行?這是爲了什麼目的? – chovy 2016-12-10 02:08:10

+0

試圖爲.m3u8 24/7流做同樣的事情。但命令'-c copy output -f mpegts stream.m3u8'會引發錯誤。 – chovy 2016-12-10 02:56:54

0

可以通過管道將你的循環到緩衝區獲取追逐和叫名字,從這個緩衝你管你流實例。

在外殼它會是什麼樣子:

#!/bin/bash 

for i in *.mp4; do 
     ffmpeg -hide_banner -nostats -i "$i" -c:v mpeg2video [proper settings] -f mpegts - 
done | mbuffer -q -c -m 20000k | ffmpeg -hide_banner -nostats -re -fflags +igndts -thread_queue_size 512 -i pipe:0 -fflags +genpts [proper codec setting] -f flv rtmp://127.0.0.1/live/stream 

當然你也可以使用任何類型的循環,也可以通過播放列表循環。

  • 我弄清楚,MPEG是一個比較穩定的,那麼X264的輸入流
  • 我不知道爲什麼,但最少2個線程的MPEG壓縮效果更好
  • 輸入壓縮需要以便輸出幀速率更快,所以我們得到足夠快的新輸入
  • 由於非持續時間戳,我們必須忽略它們並在輸出中生成一個新的輸入
  • 緩衝區大小需要足夠大讓循環有足夠的時間來獲得新的剪輯。

我對基於Python的解決方案工作,尚未完成,但除了一些警告我的測試流運行多天:

ffplayout

這將使用XML格式的播放列表。播放列表是動態的,您可以隨時編輯當前播放列表,並更改曲目或添加新曲目。

0

需要創建兩個播放列表文件,並在每個文件的末尾指定指向另一個文件的鏈接。

list_1.txt

ffconcat version 1.0 
file 'item_1.mp4' 
file 'list_2.txt' 

list_2.txt

ffconcat version 1.0 
file 'item_2.mp4' 
file 'list_1.txt' 

現在,所有你需要的是動態地改變下一個播放列表文件的內容。

相關問題