-1

このコードは、ffmpeg.exe を使用してファイルを圧縮し、次に pipstream write im を使用して、40ms ごとに Form1 タイマーからビットマップを取得し、それをパイプストリームに書き込みます。

アプリケーションを閉じると、ハードディスクに新しい avi ビデオ ファイルが作成されます。

ファイルがハードディスク上にまだ作成されていなくても、おそらく40ミリ秒ごと、または新しいビットマップが到着するたびに、ファイルのサイズをリアルタイムで確認したい. 例:

40kb、40ms 後 120kb、40ms 後 200kb など。

public void Start(string pathFileName, int BitmapRate)
        {
            string outPath = pathFileName;
            p = new NamedPipeServerStream(pipename, PipeDirection.Out, 1, PipeTransmissionMode.Byte);
            b = new byte[1920 * 1080 * 3]; // some buffer for the r g and b of pixels of an image of size 720p

            ProcessStartInfo psi = new ProcessStartInfo();
            psi.WindowStyle = ProcessWindowStyle.Hidden;
            psi.UseShellExecute = false;
            psi.CreateNoWindow = false;
            psi.FileName = ffmpegFileName;
            psi.WorkingDirectory = workingDirectory;
            psi.Arguments = @"-f rawvideo -pix_fmt bgr0 -video_size 1920x1080 -i \\.\pipe\mytestpipe -map 0 -c:v libx264 -r " + BitmapRate + " " + outPath;
            process = Process.Start(psi);
            process.EnableRaisingEvents = false;
            p.WaitForConnection();
        }

        public void PushFrame(Bitmap bmp)
        {

            int length;
            // Lock the bitmap's bits.
            //bmp = new Bitmap(1920, 1080);
            Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
            //Rectangle rect = new Rectangle(0, 0, 1280, 720);
            System.Drawing.Imaging.BitmapData bmpData =
                bmp.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadOnly,
                bmp.PixelFormat);

            int absStride = Math.Abs(bmpData.Stride);
            // Get the address of the first line.
            IntPtr ptr = bmpData.Scan0;

            // Declare an array to hold the bytes of the bitmap.
            //length = 3 * bmp.Width * bmp.Height;
            length = absStride * bmpData.Height;
            byte[] rgbValues = new byte[length];

            //Marshal.Copy(ptr, rgbValues, 0, length);
            int j = bmp.Height - 1;
            for (int i = 0; i < bmp.Height; i++)
            {
                IntPtr pointer = new IntPtr(bmpData.Scan0.ToInt32() + (bmpData.Stride * j));
                System.Runtime.InteropServices.Marshal.Copy(pointer, rgbValues, absStride * (bmp.Height - i - 1), absStride);
                j--;
            }
            p.Write(rgbValues, 0, length);
            bmp.UnlockBits(bmpData);

どうすればできますか?

4

1 に答える 1

0

可能性としては、ffmpeg にその出力をファイルではなく stdout に書き込むようにすることができます。その後、 RedirectStandardOutputプロパティを設定して、出力をキャプチャできます。

リダイレクトされた出力を読み取ってディスクに保存するのは、ユーザー次第です。もちろん、データを保存しているときに、どれだけのデータを保存したかを正確に知ることができます。

于 2013-06-06T22:56:00.063 に答える