这里的目标是实时创建压缩的 mp4 视频文件。
我将屏幕截图作为位图类型保存在我的硬盘上。
我想创建 mp4 文件并实时压缩 mp4 视频文件。
问题是我得到的视频文件看起来很奇怪。
结果如下:Strange Video File
我正在使用带有参数的 ffmpeg 的类。
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 -pix_fmt yuv420p -video_size 1920x1080 -i \\.\pipe\mytestpipe -map 0 -c:v mpeg4 -r " + BitmapRate + " " + outPath;
//psi.Arguments = @"-framerate 1/5 -i -c:v libx264 -r 30 -pix_fmt yuv420p \\.\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();
}
}
}
然后我在这个类中使用 PushFrame 方法:
public Bitmap GetScreenShot(string folder, string name)
{
_screenShot = new Bitmap(GetScreen());
System.GC.Collect();
System.GC.WaitForPendingFinalizers();
string ingName = folder + name + images.counter.ToString("D6") + ".bmp";
_screenShot.Save(ingName,System.Drawing.Imaging.ImageFormat.Bmp);
fmpeg.PushFrame(_screenShot);
_screenShot.Dispose();
return _screenShot;
}
硬盘上的位图很好,我可以编辑/打开看到它们。
当使用命令提示符并手动键入 ffmpeg 命令时,它会压缩并创建一个 mp4 视频文件。
但是当使用 Ffmpeg 类时,我使用 PushFrame 方法创建了这个奇怪的视频文件。
这是我的 OneDrive 的链接,其中包含 10 个用于测试的屏幕截图图像文件:
screenshots rar
播放视频文件时的视频文件截图示例:
看起来很波涛汹涌。硬盘上的 Bitmaps 每一张都是 1920x1080 和 Bit depth 32
但它在视频文件中看起来不像:
这是我正在使用的论点:
psi.Arguments = @"-f rawvideo -vcodec rawvideo -pix_fmt rgb24 -video_size 1920x1080 -i \\.\pipe\mytestpipe -map 0 -c:v mpeg4 -r " + BitmapRate + " " + outPath;
视频大小非常小 1.24 MB
最佳答案
您需要同时设置 -f rawvideo
表示您用于输入的容器类型,以及 -vcodec rawvideo
这对您推送到 ffmpeg
的视频数据也是如此.否则,ffmpeg 将尝试检测您正在使用的容器类型,这可能无法按预期工作。
此外,正如@Ely 评论的那样,您需要设置 -pix_fmt rgb24
,因为这是您发送的图像的格式。
另请注意,您可以通过使用 -v debug
获得有关 ffmpeg 正在做什么的更好信息。范围。
关于c# - 为什么我在使用 ffmpeg 和管道实时创建视频文件时得到奇怪的视频文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31127286/