C#でFFmpegを利用した動画フォーマットからMP4への変換サンプル

一、一般的な動画解像度

  • 640x480p
  • 720p形式、解像度1280×720p / 60Hz、走査周波数45kHz
  • 1080p形式、1920×1080プログレッティブスキャン、プロフェッショナル形式

二、FFmpegの主なパラメータ説明:

//パラメータ説明
/*
    * -i filename(input) ソースファイルパス
    * -y 出力ファイルが既存の場合、上書きを強制
    * -c エンコーダの指定
    * -fs limit_size 出力ファイルサイズの制限(バイト単位)
    * -s ビデオアスペクト比  4:3 320x240/640x480/800x600  16:9  1280x720 、デフォルトは元のビデオサイズと同じ
    * -vframes number 出力ビデオフレーム数の設定
    * -dframes number 出力データフレーム数の設定
    * -frames[:stream_specifier] framecount 各ストリームの指定フレーム数で書き込みを停止
    * -bsf[:stream_specifier] bitstream_filters 出力ファイルストリーム形式の指定
例:h264エンコードされたMP4ファイルを出力する場合:
ffmpeg -i h264.mp4 -c:v copy -bsf:v h264_mp4toannexb -an out.h264
    * -r 29.97 フレームレート(変更可能。非標準のフレームレートは音声と映像の同期不良を引き起こす可能性があるため、15または29.97に設定する必要があります)
    * 
    */

三、使用例コード:

    public class VideoConverter
    {
        private string ffmpegExecutable = @"C:\Tools\ffmpeg\bin\ffmpeg.exe";
        private string sourceVideoPath = @"C:\Input\source_video.avi";
        private string outputVideoPath = @"C:\Output\converted_video.mp4";
        private string thumbnailPath = @"C\Output\thumbnail.jpg";
        
        public void ConvertToMP4()
        {
            using (var conversionProcess = new Process())
            {
                conversionProcess.StartInfo.FileName = ffmpegExecutable;
                
                // MP4変換コマンドの構築
                string conversionArgs = $"-i \"{sourceVideoPath}\" -y -s 1280x720 -c:v libx264 -c:a aac -b:v 1500k -b:a 128k \"{outputVideoPath}\"";
                
                // サムネイル生成コマンド(コメントアウト解除して使用)
                //string thumbnailArgs = $"-i \"{sourceVideoPath}\" -y -s 640x360 -vframes 1 \"{thumbnailPath}\"";
                
                conversionProcess.StartInfo.Arguments = conversionArgs;
                conversionProcess.StartInfo.UseShellExecute = false;
                conversionProcess.StartInfo.RedirectStandardError = true;
                conversionProcess.StartInfo.CreateNoWindow = true;
                
                // 出力データの処理イベントハンドラ
                conversionProcess.ErrorDataReceived += ProcessOutputData;
                
                conversionProcess.Start();
                conversionProcess.BeginErrorReadLine();
                conversionProcess.WaitForExit();
            }
        }
        
        private void ProcessOutputData(object sender, DataReceivedEventArgs e)
        {
            if (!string.IsNullOrEmpty(e.Data))
            {
                // FFmpegの出力をコンソールに表示
                Console.WriteLine(e.Data);
                
                // 進捗状況の解析(必要に応じてコメント解除)
                //ParseProgressData(e.Data);
            }
        }
        
        private void ParseProgressData(string outputData)
        {
            // 動画の総時間を取得
            var durationPattern = @"Duration: (\d{2}):(\d{2}):(\d{2})\.(\d{2})";
            var durationMatch = Regex.Match(outputData, durationPattern);
            if (durationMatch.Success)
            {
                var hours = int.Parse(durationMatch.Groups[1].Value);
                var minutes = int.Parse(durationMatch.Groups[2].Value);
                var seconds = int.Parse(durationMatch.Groups[3].Value);
                var totalSeconds = hours * 3600 + minutes * 60 + seconds;
                Console.WriteLine($"動画の総時間: {totalSeconds}秒");
            }
            
            // 処理進捗を取得
            var timePattern = @"time=(\d{2}):(\d{2}):(\d{2})\.(\d{2})";
            var timeMatch = Regex.Match(outputData, timePattern);
            if (timeMatch.Success)
            {
                var hours = int.Parse(timeMatch.Groups[1].Value);
                var minutes = int.Parse(timeMatch.Groups[2].Value);
                var seconds = int.Parse(timeMatch.Groups[3].Value);
                var currentSeconds = hours * 3600 + minutes * 60 + seconds;
                Console.WriteLine($"現在の処理時間: {currentSeconds}秒");
            }
        }
    }

四、その他の変換例:

    // GIFアニメーションへの変換
    string gifArgs = $"-i \"{sourceVideoPath}\" -y -s 640x480 -f gif -vframes 30 \"{outputVideoPath}\"";
    
    // 特定時間範囲の抽出
    string trimArgs = $"-i \"{sourceVideoPath}\" -y -ss 00:01:30 -t 00:00:10 -c copy \"{outputVideoPath}\"";
    
    // 動画情報の表示
    string infoArgs = $"-i \"{sourceVideoPath}\" -hide_banner";

参考資料:

FFmpeg公式ドキュメント HTML5メディア再生ガイド

タグ: C# FFmpeg 動画変換 MP4 プロセス実行

6月5日 18:46 投稿