当使用ffmpeg压缩并实时创建mpeg4视频文件时,从图像浴室获取低质量视频如何提高质量?

时间:2015-06-30 16:25:33

标签: c# .net winforms ffmpeg

这里的目标是实时创建压缩的mp4视频文件。我将屏幕截图保存为硬盘上的位图类型。我想创建mp4文件并实时压缩mp4视频文件。

using System;
using System.Windows.Forms;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Drawing;
using System.IO.Pipes;
using System.Runtime.InteropServices;
using System.Diagnostics;
using System.IO;
using DannyGeneral;

namespace Youtube_Manager
{
    class Ffmpeg
    {
        NamedPipeServerStream p;
        String pipename = "mytestpipe";
        System.Diagnostics.Process process;
        string ffmpegFileName = "ffmpeg.exe";
        string workingDirectory;

        public Ffmpeg()
        {
            workingDirectory = Path.GetDirectoryName(Application.ExecutablePath);
            Logger.Write("workingDirectory: " + workingDirectory);
            if (!Directory.Exists(workingDirectory))
            {
                Directory.CreateDirectory(workingDirectory);
            }
            ffmpegFileName = Path.Combine(workingDirectory, ffmpegFileName);
            Logger.Write("FfmpegFilename: " + ffmpegFileName);
        }

        public void Start(string pathFileName, int BitmapRate)
        {
            try
            {

                string outPath = pathFileName;
                p = new NamedPipeServerStream(pipename, PipeDirection.Out, 1, PipeTransmissionMode.Byte);

                ProcessStartInfo psi = new ProcessStartInfo();
                psi.WindowStyle = ProcessWindowStyle.Hidden;
                psi.UseShellExecute = false;
                psi.CreateNoWindow = false;
                psi.FileName = ffmpegFileName;
                psi.WorkingDirectory = workingDirectory;
                psi.Arguments = @"-f rawvideo -vcodec rawvideo -pix_fmt rgb24 -video_size 1920x1080 -i \\.\pipe\mytestpipe -map 0 -c:v mpeg4 -r " + BitmapRate + " " + outPath;
                process = Process.Start(psi);
                process.EnableRaisingEvents = false;
                psi.RedirectStandardError = true;
                p.WaitForConnection();
            }
            catch (Exception err)
            {
                Logger.Write("Exception Error: " + err.ToString());
            }
        }

        public void PushFrame(Bitmap bmp)
        {
            try
            {
                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);
            }
            catch(Exception err)
            {
                Logger.Write("Error: " + err.ToString());
            }

        }

        public void Close()
        {
            p.Close();
        }
    }
}

我的硬盘上的Bitmaps图像文件每个都是1920x1080和位深度32。

视频文件位于硬盘上,大小为1.24MB

这是我在播放时从视频文件中截取的屏幕截图。 你可以看出质量有多糟糕。

screenshot from video bad quality

这是我用于从视频文件创建的屏幕截图的10张图片的链接。它们是位图。

Screenshots rar

它的论点是: 当我运行程序命令提示符窗口立即关闭时,此行不起作用。我甚至无法看到是否有任何erorr / s命令提示窗口关闭太快。

psi.Arguments = @"-f libx264 -vcodec libx264 -pix_fmt bgra -video_size 1920x1080 -i \\.\pipe\mytestpipe -map 0 -c:v mpeg4 -r " + BitmapRate + " " + outPath;

当我使用这个论点时,它正在工作但制作质量差的视频:

psi.Arguments = @"-f rawvideo -pix_fmt bgra -video_size 1920x1080 -i \\.\pipe\mytestpipe -map 0 -c:v mpeg4 -r " + BitmapRate + " " + outPath;

1 个答案:

答案 0 :(得分:2)

您误将输入参数误认为输出参数。

命令的第一部分应该是:

@"-f rawvideo -pix_fmt bgra -video_size 1920x1080 -i \\.\pipe\mytestpipe

这告诉ffmpeg使用bgra像素格式和1080p大小来预期带有原始图像的管道。

然后是第二部分 - 输出参数 - 以获得更好的质量:

-c:v libx264 -crf 20 -r " + BitmapRate + " " + outPath;

确保 outPath 具有.mp4或.mkv扩展名,因为H.264无法复制到.avi。

您可以根据需要调整crf的值。较低的值将具有更好的质量和更大的文件大小,更高的值相反。我推荐在17-24范围内的crf值。