简体   繁体   English

在 C# 中处理视频帧(FFMPEG 慢)

[英]Processing Video Frames in C# (FFMPEG Slow)

I am trying to extract frames out of mp4 videos in order to process them.我正在尝试从 mp4 视频中提取帧以处理它们。

Namely there is a watermark / timestamp within the video image which I want to use to automatically stitch the videos together.即视频图像中有一个水印/时间戳,我想用它来自动将视频拼接在一起。 The Video creation date is not sufficient for this task.视频创建日期不足以完成此任务。 在此处输入图片说明

Also the part of extracting the text out of the video with AI is fine.用AI从视频中提取文本的部分也很好。

However, FFMPEG seems terribly slow.但是,FFMPEG 似乎非常慢。 the source Video is 1080p / 60fps (roughly 1GB per 5 Minutes of video).源视频为 1080p/60fps(每 5 分钟视频大约 1GB)。

I have tried two methods so far using Accord.FFMPEG wrapper:到目前为止,我使用 Accord.FFMPEG 包装器尝试了两种方法:

public void GetVideoFrames(string path)
{
    using (var vFReader = new VideoFileReader())
    {
        // open video file
        vFReader.Open(path);
        // counter is beeing used to extract every xth frame (1 Frame per second)
        int counter = 0;
        for (int i = 0; i < vFReader.FrameCount;i ++)
        {
            counter++;
            if (counter <= 60)
            {
                _ = vFReader.ReadVideoFrame();
                continue;
            }
            else
            {
                Bitmap frame = vFReader.ReadVideoFrame();
                // Process Bitmap
            }
        }
    }
}

The other attempt:另一种尝试:

for (int i = 0; i < vFReader.FrameCount;i+= 60)
{
    // notice here, I am specifying which exact frame to extract
    Bitmap frame = vFReader.ReadVideoFrame(i);
    // process frame
}

The second method is what I tried first and it's totally unfeasible.第二种方法是我第一次尝试的,完全行不通。 Apparently FFMPEG makes a new seek for each specific frame and thus the operation takes longer and longer for each frame processed.显然 FFMPEG 对每个特定帧进行了新的搜索,因此处理的每个帧的操作时间越来越长。 After 5 frames already, it takes roughly 4 seconds to produce one Frame.在 5 帧之后,生成一帧大约需要 4 秒。

The first method at least does not seem to suffer from that issue as heavily but it still takes roughly 2 seconds to yield a frame.第一种方法至少似乎没有那么严重地受到这个问题的影响,但它仍然需要大约 2 秒才能产生一个帧。 At this rate i'm faster to process the video manually.按照这个速度,我可以更快地手动处理视频。

Is there anything wrong with my approach?我的方法有什么问题吗? Also I rather don't want to have a solution where I need to separately install third party libraries on the target machine.我也不想有一个解决方案,我需要在目标机器上单独安装第三方库。 So, if there are any alternatives, I'd be happy to try them out but it seems litterally everyone on stack overflow is either pointing to ffmpeg or opencv.因此,如果有任何替代方案,我很乐意尝试它们,但似乎堆栈溢出的每个人都指向 ffmpeg 或 opencv。

I think the problem isn't with FFmpeg, but with the Accord wrapper doing the seek.我认为问题不在于 FFmpeg,而在于 Accord 包装器在寻找。 I'd recommend using ffmpeg directly in a single pass to extract the frames, as it has options to extract only keyframes or every X frames (or you can just use the embedded video timestamps...).我建议直接在单次传递中使用 ffmpeg 来提取帧,因为它可以选择仅提取关键帧或每 X 帧(或者您可以只使用嵌入的视频时间戳...)。 But if you want to continue with your path then maybe consider passing the desired frame index rather than a for loop - it should be faster, and maybe you can parrallelize it.但是如果你想继续你的路径,那么也许可以考虑传递所需的帧索引而不是 for 循环 - 它应该更快,也许你可以并行化它。

But it'll be much faster to do that all in a separate ffmpeg process.但它会更快做所有在一个单独的ffmpeg的过程。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM