May 29, 2013
ストリーミング動画録画ソフトを作成する

RaspberryPiをストリーミングサーバーにしましたが、動画を録画するソフトが欲しくなったので制作しました。
jpg連番でファイルを落としてffmpgでaviに変換、出力します。
アルゴリズムは以下の通り
1.System.Netで/?action=snapshotからjpgの連番で動画を取得
2.連番のjpg画像をfmpegで変換、出力
3.jpg連番ファイルを削除
fmpegのインストール方法
1.ここからffmpegをダウンロード。Windows版。通常はStaticをダウンロード。32bitまたは64bitで落とすファイルが違うので注意。
2.任意の場所で解凍。自分は.NETで使用する為、VB.NETのプロジェクトのDebugフォルダの中に解凍しました。
ffmpegの使用方法
ffmpeg -i "c:/image/image%05d.jpg" -vcodec mjpeg -q 0 c:/image/out.avi
-i “c:/image/image%08d.jpg” が連番ファイル指定。%08dが5桁の数字(連番処理)
-vcodec mjpeg でコーデックを指定。avi以外にもmpgやmp4などを出力できる。
-q 0 質を落とさない
c:/image/out.avi 出力パスと出力ファイル名
コーデックと出力ファイル名がマッチしていないとエラーを吐く
ffmpegを解凍したフォルダのbinの中に移動しないと上記は動かないので注意。
jpgの連番を取得するスレッド
Private Sub CapJpeg() Dim num As Long Dim URLTextLine As String = "190.10.10.10:8080/?action=snapshot" Dim IDTextLine As String = "ID" Dim PASSTextLine As String = "PASSWORD" num = 0 While num > -1 If RaspVideoCap.CapFlg = True Then '録画停止ボタンが押されたかどうか num += 1 Dim URLPath As String = URLTextLine Dim DownloadPath As String = "ffmpeg\bin\Temp" & ("" & num).PadLeft(8, "0") & ".jpg" Dim wc As New System.Net.WebClient Dim nc As New System.Net.NetworkCredential(IDTextLine, PASSTextLine) wc.Credentials = nc wc.DownloadFile(URLPath, DownloadPath) wc.Dispose() System.Threading.Thread.Sleep(200) Else num = -1 End If End While End Sub
注意すべき点はファイル名をFileName0001、FileName0002などで保存すること。
ファイル名の長さを固定した連番ファイルにするには
(“” & num).PadLeft(i, “D”)
を使用するiは文字列数、Dは置換する文字列(ここでは0)
vb.netでコマンドプロンプトからffmpegを実行してjpg連番ファイルをaviに落とすコード
'コマンドプロンプトを呼び出す Dim oCmd As New System.Diagnostics.Process oCmd.StartInfo.UseShellExecute = True oCmd.StartInfo.FileName = "cmd.exe" oCmd.Start() ' コマンドプロンプトが起動するまで待つ Thread.Sleep(200) ' 起動したコマンドプロンプトのタイトル名を引数にする AppActivate("c:\windows\System32\cmd.exe") SendKeys.SendWait("cd ffmpeg\bin{Enter}") ' ffmpegが起動できるフォルダ階層まで移動する '生成する動画ファイル名を作成する FileName = DateTime.Now.ToString("yyyy.MM.dd_HH.mm.ss.") System.Threading.Thread.Sleep(200) ' ffmpegを起動、変換処理を開始する SendKeys.SendWait("ffmpeg -r " & FlmTime & " -i ""Temp" & "{%}" & "08d.jpg"" -q 0 -vcodec " & VideoFormat & " " & SavePathLine & "" & FileName & "" & FileExtention & "{Enter}")
FlmTimeは1秒当たりのフレーム数。録画時間と取得できた枚数で算出すればOK。
System.Threading.Thread.Sleep(200)はなぜかこれを入れると処理が安定する。
jpgの連番ファイル削除処理
For i = 1 To CapImageNum System.IO.File.Delete("ffmpeg\bin\Temp" & ("" & i).PadLeft(8, "0") & ".jpg") Next
とりあえずこれらを組み合わせてRaspberryPiのストリーミング動画を録画することが出来ました。
これから機能を拡張していこうと思います。(動きを検知して録画とか) Tweet