1. 程式人生 > >FFMPEG採集攝像頭資料並切片為iPhone的HTTP Stream流

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/

NameLast ModifiedSizeType
2012-Feb-07 10:13:385.7Kapplication/octet-stream
2012-Feb-07 10:13:380.9Kapplication/octet-stream
2012-Feb-07 10:13:389.9Kapplication/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才能播放,有幾個步驟需要注意:

  1. 視訊檔案的位元速率必須在: 100 Kbps to 1.6 Mbps    這個範圍
  2. 蘋果公司建議的視訊流為:
    • Low – 96 Kbps video, 64 Kbps audio
    • Medium – 256 Kbps video, 64 Kbps audio
    • High – 800 Kbps video, 64 Kbps audio
  3. iPhone 的螢幕視訊播放尺寸設定為: 480×320

建議使用下面的引數進行視訊轉碼:

ffmpeg -i <in file> -f mpegts -acodec libmp3lame -ar 48000 -ab 64k -s 320×240 -vcodec libx264 -b 96k -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 96k -bufsize 96k -rc_eq 'blurCplx^(1-qComp)' -qcomp 0.6 -qmin 10 -qmax 51 -qdiff 4 -level 30 -aspect 320:240 -g 30 -async 2 <output file>

要更改的引數為   “   -b, -maxrate,  -bufsize values   ”


Step 3: 下載並編譯 segmenter

現在,你已經完成了視訊採集的工作,但是還沒有完成整個構建HTTP  Streaming 的過程。 你需要一種方法來把視訊檔案切成小塊,你可以下載蘋果的 segmenter 。

下載下來後用下面的命令即可編譯 :

all:
        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的設定。

.m3u8    application/x-mpegURL
.ts      video/MP2T

假如你使用的是Apache伺服器的話,你需要新增如下的程式碼到 httpd.conf 配置檔案裡:

AddType application/x-mpegURL .m3u8
AddType 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/sh

BR=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解決同步壓縮和辦法的速度同步問題,而且要放在前面,不然不一定起作用