Linuxでffmpegとffserverを利用してライブ配信を行う

ウェブカメラ映像
以前弊社でCentOSを使ってサーバーを構築するセミナーを実施した際に、サーバーとは何か?
というお題から始まりましたが、サーバーというのはサービスを提供するものです、

またサービスを提供する方法として、既存でAという物を元にサービスを提供する機能を持たせる事ができます。
USBのウェブカメラは繋いだ本体自身でしか見る事ができませんが、
Linuxと組み合わせる事で、IPカメラに変身させることができます。

ここではffmpegというソフトウェアを用いてウェブカメラをIPカメラに変身させてみたいと思います。

■ウェブ配信サーバー(ffserver)の設定

ここではCentOS6を用いて構築を行いますが、外部リポジトリを追加する方法で利用したいと思います。
CentOSはサーバー用途に特化しており、デスクトップ用途のソフトウェアが付属していません。
ソースからコンパイルする事もできますが、
外部リポジトリを追加する事で、デスクトップ用途のソフトウェアを簡単に追加できます。
・ファイアウォールの解放
配信側のサーバーではTCP:8080番ポートを利用したいと思いますので、iptablesで解放を行ってください。
・外部リポジトリの追加
ここではatrpmsを追加します。
他にもEPELやrpmforgeなど、有志によって様々な外部リポジトリが公開されています。

rpm -ivh http://dl.atrpms.net/all/atrpms-repo-6-6.el6.x86_64.rpm

・ffmpeg/ffserverのインストール
公開するソフトウェアとしてffmpegとffserverが必要になりますので、インストールします。
ffserverはffmpegに含まれるためffmpegをインストールするのみです。

yum -y install ffmpeg

・ffserverの設定
まずはストリーミングを公開するffserverの設定を行います。
この設定は再生しやすいswfフォーマットで1280×720@1200kbps、秒間フレームを30fpsと指定しています。

vi /etc/ffserver.conf
----------------------------------------

Port 8080
BindAddress 0.0.0.0 
MaxClients 10
MaxBandwidth 10000 
NoDaemon 

<Feed webcam.ffm> 
File /tmp/webcam.ffm 
FileMaxSize 100M 
</Feed> 

<Stream test.swf>
Feed webcam.ffm
Format swf
VideoSize 1280x720
VideoFrameRate 30
Noaudio
VideoBitRate 1200
</Stream>

<Stream stat.html>
Format status 
ACL allow localhost
</Stream>
・ffserverの起動
ffserverを起動します。ここでは&を付けてバックグラウンドで起動します。

ffserver &
特にエラーが表示されなければ配信側の設定はこれで完了しました。

■ウェブカメラ接続サーバー(ffmpeg)の設定

続いてウェブカメラを接続したサーバー側の設定です。
ここではウェブカメラを接続したサーバーとウェブで配信を行うサーバーを分けていますが、
同じサーバーで構築しても問題ありません。

・外部リポジトリの追加
ffserverと同様、ここではatrpmsを追加します。
配信サーバーとウェブカメラを接続するサーバーが同じ場合は、
既にこの手順は済んでいますので次へ進んでください。

rpm -ivh http://dl.atrpms.net/all/atrpms-repo-6-6.el6.x86_64.rpm

・ffmpegのインストール
ウェブカメラを接続するサーバーではffmpegを利用します。
配信サーバーとウェブカメラを接続するサーバーが同じ場合は、
既にこの手順は済んでいますので次へ進んでください。

yum -y install ffmpeg

・USBウェブカメラの接続
サーバーにUSBウェブカメラを接続します。
ELECOM製の130万画素ウェブカメラ(UCAM-DLN130T)を使用しましたが、
大抵のウェブカメラが動作すると思います。
正常に認識された場合、dmesgで以下のメッセージが表示されます。

usb 1-1: new high speed USB device number 3 using ehci_hcd
usb 1-1: New USB device found, idVendor=056e, idProduct=700d
usb 1-1: New USB device strings: Mfr=1, Product=2, SerialNumber=0
usb 1-1: Product: UCAM-DLN130T series
usb 1-1: Manufacturer: Alcor Micro, Corp.
usb 1-1: configuration #1 chosen from 1 choice
uvcvideo: Found UVC 1.00 device UCAM-DLN130T series (056e:700d)
input: UCAM-DLN130T series as /devices/pci0000:00/0000:00:1d.7/usb1/1-1/1-1:1.0/input/input11

・ビデオデバイスの確認
念のためビデオデバイスが追加されたか確認します。

ls -l /dev/video0 
crw-rw---- 1 root video 81, 0  6月 19 12:13 2013 /dev/video0

・ffmpeg対応フォーマットの確認
ffmpegで実行可能なフォーマットを確認します。

ffmpeg -f video4linux2 -list_formats all -i /dev/video0
(中略)
[video4linux2,v4l2 @ 0x94c1c60] Raw       :   yuyv422 :     YUV 4:2:2 (YUYV) :
[video4linux2,v4l2 @ 0x94c1c60] Compressed:     mjpeg :                MJPEG :

ここではウェブカメラ側で対応フォーマットがyuyv422とmjpegの二つがあると言う事が分かりました。
フォーマットを指定しない場合、この確認は不要ですが、
ウェブカメラによって複数のフォーマットに対応している事があり、
対応フォーマットによって解像度やフレームレートが異なるケースがあります。
このウェブカメラの場合、1280×720ピクセルに対応していますが、
指定をしない場合に選択されるYUYV422形式では最大12fpsまで、MJPEG形式では30fpsまでという違いがありました。

・ffmpegの実行
ffmpegを実行してウェブカメラを接続したサーバーからストリーミング配信を行うサーバーにデータを送信します。

ffmpeg -r 30 -s 1280x720 -f video4linux2 -input_format mjpeg -i /dev/video0 http://_ffserverのIPアドレス_:8080/webcam.ffm

ここで指定した内容としては-r 30でフレームレートを30fpsに、-s 1280×720で解像度をHD画質で、
-input_format mjpegで30fpsに対応したMJPEG形式で入力し、
最後に指定したffserverへデータを送信するという内容になります。

数秒するとエンコーディング処理が実行され、配信サーバーへデータが送信されます。
エンコーディング設定はffserverで設定した内容で決定されます。
ここでは再生しやすいswfフォーマットで1280×720@1200kbps、秒間フレームを30fpsと指定しています。

・ブラウザーで確認
2ブラウザーを開き、http://_ffserverのIPアドレス_:8080/test.swfにアクセスしてみてください。

ウェブカメラ映像
これは弊社社内で実行しましたが、上記のような画面が表示されましたでしょうか?
FirefoxやChromeでうまく表示されていればOKです。
IEではうまく表示できませんので、以下のようなHTMLを置く必要があります。

<embed src="http://_ffserverのIPアドレス_:8080/test.swf" type="application/x-shockwave-flash" bgcolor="#ffffff" pluginspage="http://www.adobe.com/go/getflashplayer_jp" />

今回は配信側とウェブカメラ接続サーバーを分けましたが、
自宅のサーバーをインターネット上に公開したくない方は、
VPSサービスやクラウドサービスを利用してインターネット公開する事ができます。

今回の設定ではswf向けに設定しましたので画質はよくありませんが、
細かく設定をする事によって高画質映像で配信を行う事ができます。

最新ブログ一覧