FFMPEG採集攝像頭資料並切片為iPhone的HTTP Stream流
一、Windows下面編譯ffmpeg
首先需要解決的問題是:在windows下面編譯 ffmpeg, 並讓其支援dshow, 本人把ffmpeg編譯成功了, 但是編譯出來的ffmpeg不支援dshow, 在網上找了有文章介紹如何編譯ffmpeg讓其支援dhsow, 按照文章說的方法試了N次, 終究沒有成功。無奈只有找現成的windows下面的exe了。
在這裡找到了可用的ffmpeg.exe, 測試了一下,支援dshow。
下載解壓到C盤根目錄。
二、測試FFMPEG支援dshow的情況
執行下面的命令 , 即可顯示你的系統支援音訊捕獲裝置,視訊捕獲裝置:
c:\> ffmpeg -list_devices true -f dshow -i dummy ffmpeg version N-45279-g6b86dd5... --enable-runtime-cpudetect libavutil 51. 74.100 / 51. 74.100 libavcodec 54. 65.100 / 54. 65.100 libavformat 54. 31.100 / 54. 31.100 libavdevice 54. 3.100 / 54. 3.100 libavfilter 3. 19.102 / 3. 19.102 libswscale 2. 1.101 / 2. 1.101 libswresample 0. 16.100 / 0. 16.100 [dshow @ 03ACF580] DirectShow video devices [dshow @ 03ACF580] "Integrated Camera" [dshow @ 03ACF580] "screen-capture-recorder" [dshow @ 03ACF580] DirectShow audio devices [dshow @ 03ACF580] "Internal Microphone (Conexant 2" [dshow @ 03ACF580] "virtual-audio-capturer" dummy: Immediate exit requested
我們下來使用 視訊捕獲裝置 "Integraged Camera" 儲存為MP4檔案:
c:\> ffmpeg -f dshow -i video="Integrated Camera" out.mp4
嘿嘿,攝像頭燈亮了,檔案已經輸出到了和 ffmpeg.exe 相同的路徑下面。 用VLC播放 out.mp4檔案,正常。
用下面的命令可以檢視視訊捕獲裝置支援的圖片大小等詳細資訊。
C:\ffmpeg\bin>ffmpeg -f dshow -list_options true -i video="Integrated Camera"
用下面的命令我們可以把視訊解析度儲存為1280x720, FPS為15幀/秒, 輸出為 out.avi 檔案。是不是很方便啊 ?
C:\>ffmpeg -f dshow -s 1280x720 -r 15 -vcodec mjpeg -i video="Integrated Camera" out.avi
三、測試FFMPEG對DSHOW支援的另外一種方法
用下面的命令我們也可以輸出視訊捕獲裝置,只不過不是名字,而是ID的形式。
ffmpeg -y -f vfwcap -i list
輸出如下 :libavutil 52. 41.100 / 52. 41.100 libavcodec 55. 24.100 / 55. 24.100 libavformat 55. 13.102 / 55. 13.102 libavdevice 55. 3.100 / 55. 3.100 libavfilter 3. 82.100 / 3. 82.100 libswscale 2. 4.100 / 2. 4.100 libswresample 0. 17.103 / 0. 17.103 libpostproc 52. 3.100 / 52. 3.100 [vfwcap @ 000000000034d940] Driver 0 [vfwcap @ 000000000034d940] Microsoft WDM Image Capture (Win32) [vfwcap @ 000000000034d940] Version: 6.1.7600.16385 list: Input/output error
從上面看出 vfwcap的索引號為0, 用下面的命令即可捕獲視訊資料。其中 -i 0 就代表使用ID為0的視訊採集裝置, -r 25代表幀率為25幀/秒
ffmpeg -y -f vfwcap -r 25 -i 0 out.mp4
四、Apple公司的HLS檔案切片相關資料
下面是相關的技術資料的地址 :
MPEG TS segmenter by Chase Douglas source: http://svn.assembla.com/svn/legend/segmenter/ ffmpeg & segmenter LiveStream Howto: http://www.ioncannon.net/programming/452/iphone-http-streaming-with-ffmpeg-and-an-open-source-segmenter/ Apple's LiveStream docs: https://developer.apple.com/library/ios/#documentation/NetworkingInternet/Conceptual/StreamingMediaGuide/Introduction/Introduction.html Apple's LiveStream draft at IETF: http://tools.ietf.org/html/draft-pantos-http-live-streaming-07" ffmpeg 0.10.0 release: http://ffmpeg.org/download.html#release_0.10 Cardon McDonal's IOCANNON: http://www.ioncannon.net/
Index of /src/mpegts-segmenter/
Name | Last Modified | Size | Type |
---|---|---|---|
2012-Feb-07 10:13:38 | 5.7K | application/octet-stream | |
2012-Feb-07 10:13:38 | 0.9K | application/octet-stream | |
2012-Feb-07 10:13:38 | 9.9K | application/octet-stream |
還附帶檔案切片原始碼。
下面的地址也可以下載 切片工具的原始碼,這個工具可能比較完善一點吧。
五、用FFMPEG實現iPhone的HTTP Stream技術步驟
Step 1: 獲取最新版本的 FFMpeg
The FFMpeg download page 從該地址獲取最新版本的ffmpeg
使用下面的命令進行配置,生成Makefile檔案,然後make吧。
configure --enable-gpl --enable-nonfree --enable-pthreads --enable-libfaac --enable-libfaad --enable-libmp3lame --enable-libx264其中最重要的事情是注意 --enable-libx264 這個編譯選項。
Step 2: 轉碼視訊格式,讓 iPhone 可以使用
我們必須讓ffmpeg建立 X264編碼格式的視訊流, iPhone才能播放,有幾個步驟需要注意:
- 視訊檔案的位元速率必須在: 100 Kbps to 1.6 Mbps 這個範圍
- 蘋果公司建議的視訊流為:
- Low – 96 Kbps video, 64 Kbps audio
- Medium – 256 Kbps video, 64 Kbps audio
- High – 800 Kbps video, 64 Kbps audio
- iPhone 的螢幕視訊播放尺寸設定為: 480×320
建議使用下面的引數進行視訊轉碼:
要更改的引數為 “ -b, -maxrate, -bufsize values ”
Step 3: 下載並編譯 segmenter
現在,你已經完成了視訊採集的工作,但是還沒有完成整個構建HTTP Streaming 的過程。 你需要一種方法來把視訊檔案切成小塊,你可以下載蘋果的 segmenter 。
下載下來後用下面的命令即可編譯 :
gcc -Wall -g segmenter.c -o segmenter -lavformat -lavcodec -lavutil -lbz2 -lm -lz -lfaac -lmp3lame -lx264 -lfaad
clean:
rm segmenter
在編譯完成了 segmenter 工具之後, 你就可以建立你的 HTTP Streaming 內容了。
命令格式為:
segmenter <input MPEG-TS file> <segment duration in seconds> <output MPEG-TS file prefix> <output m3u8 index file> <http prefix>下面是一個使用的例子,從視訊檔案建立一個流, 每個切片檔案10秒:
segmenter sample_low.ts 10 sample_low stream_low.m3u8 http://www.ioncannon.net/Step 4: 準備 HTTP server 伺服器
進行到這一步的時候, 你應該已經有好多視訊流的切片檔案了,這些檔案可以上傳到web伺服器, 但是這裡有一個比較重要的事情需要注意,那就是mime types的設定。
.ts video/MP2T
假如你使用的是Apache伺服器的話,你需要新增如下的程式碼到 httpd.conf 配置檔案裡:
AddType application/x-mpegURL .m3u8AddType video/MP2T .ts
假如你使用的是 lighttpd 伺服器的話,你需要新增下面的程式碼到你的配置檔案中:
mimetype.assign = ( ".m3u8" => "application/x-mpegURL", ".ts" => "video/MP2T" )Step 5: 測試 stream
萬事俱備只欠東風了,下來需要使用 HTML5 的 video 標籤,例子如下:
<html><head>
<title>Video Test</title>
<metaname="viewport"content="width=320; initial-scale=1.0; maximum-scale=1.0; user-scalable=0;"/>
</head>
<bodystyle="background-color:#FFFFFF; ">
<video width='150'height='150'src="stream-128k.m3u8"/>
</body>
</html>
上面所有的步驟都正確的話,你現在應該已經看到視訊了。
Step 6: 自動化的 stream 編碼和切片 segmentation
這是一個小指令碼,可以把輸入檔案編碼轉換後再切片為10秒一個的檔案小塊。
#!/bin/shBR=800k
ffmpeg -i $1 -f mpegts -acodec libmp3lame -ar 48000-ab 64k-s 320×240-vcodec libx264-b$BR-flags +loop-cmp +chroma-partitions +parti4x4+partp8x8+partb8x8-subq 5-trellis 1-refs 1-coder 0 -me_range 16 -keyint_min 25 -sc_threshold 40 -i_qfactor 0.71-bt 200k-maxrate$BR-bufsize$BR -rc_eq'blurCplx^(1-qComp)'-qcomp 0.6-qmin 10-qmax 51-qdiff 4-level 30-aspect 320:240-g 30-async 2 sample_$BR_pre.ts
segmenter sample_$BR_pre.ts 10 sample_$BR stream-$BR.m3u8 http://www.ioncannon.net/
rm -f sample_$BR_pre.ts
Step 7: 建立不同位元速率 rate 的 HTTP stream
之前將的例子都是建立單一位元速率的HTTP Stream, 我們需要建立不同位元速率的視訊流, 下面是一個簡單的小例子。
#EXTM3U
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=96000
http://192.168.132.15/ipv/stream-96k.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=256000
http://192.168.132.15/ipv/stream-256k.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=800000
http://192.168.132.15/ipv/stream-800k.m3u8
六、讓nginx支援MP4檔案的直接播放
編譯的時候可能會有點小錯誤:
解決錯誤:
因為在新版本的nginx中廢棄了 zero_in_uri 這個flag,稍微修改一下 nginx_mod_h264_streaming 的原始碼
vim /usr/local/src/nginx_mod_h264_streaming-2.2.7/src/ngx_http_streaming_module.c
把158到161行註釋掉
157 /* TODO: Win32 */158 //if (r->zero_in_uri)
159 //{
160 // return NGX_DECLINED;
161 //}
然後再make就正常了,make install 完成安裝
在nginx配置檔案中加入
location ~ .mp4$ {mp4;
}
下面的命令從攝像頭採集資料後傳送到伺服器進行切片
C:\ffmpeg-win64-static\bin>ffmpeg.exe -f dshow -i video="Integrated Camera" -vcodec libx264 -pix_fmt yuv420p -f flv rtmp://192.168.59.129/hls/mystream
下面的命令時以檔案gd.flv為輸入資料流, 轉碼後傳送到伺服器進行切片
C:\ffmpeg-win64-static\bin>ffmpeg.exe -re -i "E:\Movie\gd.flv" -vcodec copy -acodec copy -f flv rtmp://192.168.59.129/hls/mystream
ffmpeg.exe -f dshow -i video="Integrated Camera":audio="麥克風 (Realtek High Definition Au" -q 4 -s 640*480 -aspect 4:3 -r 10 -vcodec flv -ar 22050 -ab 64k -ac 1 -acodec libmp3lame -threads 4 -f flv rtmp://192.168.59.129/hls/mystream
ffmpeg.exe -f dshow -i video="Integrated Camera":audio="麥克風 (Realtek High Definition Au" -s 640*480 -vcodec libx264 -acodec libmp3lame -pix_fmt yuv420p -threads 4 -f flv rtmp://192.168.59.129/hls/mystream
虛擬切片:
攝像頭採集後的資料直接切片 :
ffmpeg.exe -f dshow -i video="Integrated Camera":audio="麥克風 (Realtek High Definition Au" -s 640*480 -vcodec libx264 -acodec libmp3lame -flags -global_header -map 0 -f segment -segment_time 10 -segment_list live.m3u8 -segment_format mpegts live%05d.ts
FMPEG 把檔案傳送到rtmp的速度不正常的問題:
ffmpeg -re -i "輸入檔案"-qscale 3 -s 720*360 -aspect 16:9 -r 25 -threads 4 -vcodec flv-acodec libmp3lame -ar 44100 -ab 128k -ac 2 -f flvrtmp://127.0.0.1/rtmpsvr/RtmpVideo關鍵是 -re解決同步壓縮和辦法的速度同步問題,而且要放在前面,不然不一定起作用!