動画の時間が勝手に変わる
Q&A
Closed
解決したいこと
C#のバックグラウンドプロセスでffmpegを起動しOPencvSharpのVideoCaptureが保持するMatを一枚ずつループ処理でwriteし、動画を作成するツールを作っていますが、29.97fpsの動画をエンコードすると動画の尺が伸びてしまい困っています。
opencvsharpのvideowriterを素直に使わない理由についてはfieldorderやbitrateなどの設定ができない為です。
発生している問題・エラー
fpsが29.97で00:01:03の尺の動画をツールに取り込みエンコードをしてみると00:01:15になっていることに気づいたのが発端です。
フレームレートは動画のプロパティ情報を見る限り29.97のままで以上が見られず。
そこでエンコードしたものを再度ツールに取り込みvideocaptureがつかんでいる情報を確認すると
元動画ではフレームの枚数が1893であったのに対してエンコード後の動画では2268に。
いったい375枚のフレームはどこから来たのかわかりません。
ソースは此方になります。
プロセス作成
proc.StartInfo.FileName = @"C:\ffmpeg\bin\ffmpeg.exe";
//こんな感じで引数に渡される
//-f image2pipe -i pipe:.bmp -vf setfield=mode=-1 -b:v 5000k -maxrate 5000k -r 29.97 -vcodec h264_nvenc C:\output\output.mp4
proc.StartInfo.Arguments = string.Format("-f image2pipe -i pipe:.bmp -vf setfield=mode={0} -b:v {1}k -maxrate {2}k -r {3} -vcodec {4} {5}",
fieldOrder,
BitRate,
MaxBitRate,
FPS,
Codec,
OutPutFileName);
//バックグラウンドタスクスタート
proc.Start();
// 非同期出力読出し開始
proc.BeginErrorReadLine();
proc.BeginOutputReadLine();
書き込み処理
for (int Position = 0; Position < EndFrame; Position++)
{
using (var ms = new MemoryStream())
{
Mat mat = new Mat();
Cv2.Read(mat);
BitmapConverter.ToBitmap(mat).Save(ms, ImageFormat.Bmp);
ms.WriteTo(proc.StandardInput.BaseStream);
Cv2.WaitKey();
mat.Dispose();
ms.Dispose();
ms.Close();
}
}
自分で試したこと
ffmpegのargumentにオプションを設定することで解決できないか試しました。
-t 00:01:03とオプションをつけることで指定時間内のレンダリングのみすることはできましたが結局動画としては中途半端な箇所で終わってしまい根本の解決には至らず。
-vf mpdecimateで重複フレームがあれば除去するオプションを付けて上げましたがこれで処理すると動画が閲覧できず。。。
書き込み情報自体には異常がありませんでしたが閲覧ができないためこれでは困りました。
ffmpegについて精通できていないのが原因だとは思いますがどうかお力をお貸しください。
よろしくお願いします。