上一篇文章我們介紹了如何用一個簡單的UDP socket搭建一個RTP服務器。我把這份80行的代碼呈現到客戶面前的時候,就有人不滿意了。
還有人在參考的時候會問:“樓主你的TS格式的文件是哪里來的?應該去哪里下載?”
“這也太簡單了吧,不就是用UDP把TS文件發過去么?就這么幾十行代碼也算個大作業?”
“平時看的視頻格式哪有TS的呀,不是avi就是mp4、rmvb什么的,根本不實用啊!”
“這也太簡單了吧,不就是用UDP把TS文件發過去么?就這么幾十行代碼也算個大作業?”
“平時看的視頻格式哪有TS的呀,不是avi就是mp4、rmvb什么的,根本不實用啊!”
首先回答問題1:
如果你用過強大的ffmpeg,就可以用一行簡單的命令
- ffmpeg -i INPUTFILE.XXX OUTPUTFILE.ts
把幾乎任何格式的文件轉換成TS文件。
再回答問題2:
如果能實現同樣的功能,我確實更傾向使用簡單的方法。說我偷懶也好,沒有技術含量也好。我覺得,很多時候最簡單直接的方法最有效。
這篇帖子主要的內容就是來回答問題3:如何用RTP協議傳輸各種格式的視頻。
不要告訴我不可以。如果真的不可以,那么我們豈不是要把各種格式的視頻解碼器實現一遍?也就是說我們要自己重新寫一個ffmpeg工程!
當然是可以的,關鍵是看如何使用。有幾種選擇:借用別人的源碼然后集成到我們的工程;或是調用別人的接口來使用已經編譯好的庫;還是直接使用別人的程序?這就是復用粒度大小的選擇。很少有人會用第一種方法,因為別人的源碼不見得拿來就能編譯通過並且成功使用。多數人會選擇第二種方法,看起來順理成章,也是可以適應一定需求變化的。(這是做軟件最需要考慮的地方)
不過鑒於這個項目是一個課堂的作業,加上我比較喜歡偷懶,就選擇了最簡單的第三種方法。
第一步
首先需要對上一篇中的代碼做一些簡單的修改:
把原先的
- int main(){
- int main(int argc, char **argv){
再把原先的
- FILE *ts_file = fopen("/home/baby/Videos/480p.ts", "r+");
- if (argc != 2){
- puts("Usage: ./rtp_server INPUTFILE");
- return 0;
- }
- FILE *ts_file = fopen(argv[1], "r+");
第二步
源代碼編譯通過后,只需寫一個簡單的shell腳本mk_rtp_server.sh。
- #!/bin/sh
- mkfifo fifo.ts
- ffmpeg -i $1 -y fifo.ts &
- ./rtp_server fifo.ts
其實就是利用了ffmpeg的分流與解碼,然后利用命名管道把ffmpeg的輸出到處到一個管道中,然后再用我們前面寫好的rtp_server去讀這個文件。
(切記ffmpeg參數里面的-y是必不可少的)
OK,大功告成。chmod之后執行這個腳本文件./mk_rtp_server.sh INPUTFILE.XXX,拿個播放器測試一下。”嗯~果然不錯~“
只要你的ffmpeg裝的夠完整,那么幾乎所有的格式都可以變成rtp流。包括avi之類的非實時流文件格式。
大功告成!並且遠遠超過了當初的需求,但是客戶的需求善變如人心,下一步又是什么呢?