本身動手寫RTP服務器——傳輸全部格式的視頻

上一篇文章咱們介紹瞭如何用一個簡單的UDP socket搭建一個RTP服務器。我把這份80行的代碼呈現到客戶面前的時候,就有人不滿意了。
還有人在參考的時候會問:「樓主你的TS格式的文件是哪裏來的?應該去哪裏下載?」
「這也太簡單了吧,不就是用UDP把TS文件發過去麼?就這麼幾十行代碼也算個大做業?」
「平時看的視頻格式哪有TS的呀,不是avi就是mp四、rmvb什麼的,根本不實用啊!」
 
首先回答問題1:
若是你用過強大的ffmpeg,就能夠用一行簡單的命令
[plain]  view plain copy
 
 
  1. ffmpeg -i INPUTFILE.XXX OUTPUTFILE.ts  
把幾乎任何格式的文件轉換成TS文件。
 
再回答問題2:
若是能實現一樣的功能,我確實更傾向使用簡單的方法。說我偷懶也好,沒有技術含量也好。我以爲,不少時候最簡單直接的方法最有效。
 
這篇帖子主要的內容就是來回答問題3:如何用RTP協議傳輸各類格式的視頻。

預備知識

咱們是否能夠調用別人的分流器或者解碼器?
不要告訴我不能夠。若是真的不能夠,那麼咱們豈不是要把各類格式的視頻解碼器實現一遍?也就是說咱們要本身從新寫一個ffmpeg工程!
固然是能夠的,關鍵是看如何使用。有幾種選擇:借用別人的源碼而後集成到咱們的工程;或是調用別人的接口來使用已經編譯好的庫;仍是直接使用別人的程序?這就是複用粒度大小的選擇。不多有人會用第一種方法,由於別人的源碼不見得拿來就能編譯經過而且成功使用。多數人會選擇第二種方法,看起來瓜熟蒂落,也是能夠適應必定需求變化的。(這是作軟件最須要考慮的地方)
不過鑑於這個項目是一個課堂的做業,加上我比較喜歡偷懶,就選擇了最簡單的第三種方法。

參考代碼

第一步

首先須要對上一篇中的代碼作一些簡單的修改:
把原先的
[cpp]  view plain copy
 
 
  1. int main(){  
改成
[cpp]  view plain copy
 
 
  1. int main(int argc, char **argv){  
再把原先的
[cpp]  view plain copy
 
 
  1. FILE *ts_file = fopen("/home/baby/Videos/480p.ts", "r+");  
改成
[cpp]  view plain copy
 
 
  1. if (argc != 2){  
  2.     puts("Usage: ./rtp_server INPUTFILE");  
  3.     return 0;  
  4. }  
  5. FILE *ts_file = fopen(argv[1], "r+");  
能夠看出咱們此次不讀取固定文件,而是根據用戶本身的輸入讀取文件,這樣就靈活了許多。

第二步

源代碼編譯經過後,只需寫一個簡單的shell腳本mk_rtp_server.sh。
[plain]  view plain copy
 
 
  1. #!/bin/sh  
  2. mkfifo fifo.ts  
  3. ffmpeg -i $1 -y fifo.ts &  
  4. ./rtp_server fifo.ts  
只有四行有木有,很簡單有木有!
其實就是利用了ffmpeg的分流與解碼,而後利用命名管道把ffmpeg的輸出處處到一個管道中,而後再用咱們前面寫好的rtp_server去讀這個文件。
(切記ffmpeg參數裏面的-y是必不可少的)
OK,大功告成。chmod以後執行這個腳本文件./mk_rtp_server.sh INPUTFILE.XXX,拿個播放器測試一下。」嗯~果真不錯~「
只要你的ffmpeg裝的夠完整,那麼幾乎全部的格式均可以變成rtp流。包括avi之類的非實時流文件格式。
 
大功告成!而且遠遠超過了當初的需求,可是客戶的需求善變如人心,下一步又是什麼呢?
相關文章
相關標籤/搜索