Я получаю необработанные видеокадры из источника (который можно считать черным ящиком) со скоростью, которая может быть непоследовательной. Я пытаюсь записать видео-канал на диск. Я делаю это с AForge VideoRecorder
и пишу в файл MP4.Предоставление видео в файл, который может иметь несогласованную частоту кадров
Однако непоследовательная скорость, с которой я получаю фреймы, приводит к тому, что видео появляется ускоренным. Похоже, что у меня есть только возможность создавать видеофайлы с фиксированной частотой кадров, хотя источник не имеет фиксированной частоты кадров.
Это не проблема при визуализации на экране, так как мы можем просто сделать как можно быстрее. Я не могу сделать это при записи в файл, так как воспроизведение файла будет воспроизводиться с фиксированной частотой кадров.
Какие у вас есть решения? Выходной сигнал не должен быть одного и того же видеоформата, если есть разумный способ его конвертировать позже (что не обязательно должно быть в режиме реального времени). Видеопотоки могут быть довольно длинными, поэтому я не могу просто сохранить все в памяти и позже закодировать.
Мой код в настоящее время выглядит по линии:
VideoFileWriter writer = new VideoFileWriter();
Stopwatch stopwatch = new Stopwatch();
public override void Start() {
writer.Open("output.mp4", videoWidth, videoHeight, frameRate, AForge.Video.FFMPEG.VideoCodec.MPEG4);
stopwatch.Start();
}
public override void End() {
writer.Close();
}
public override void Draw(Frame frame) {
double elapsedTimeInSeconds = stopwatch.ElapsedTicks/(double) Stopwatch.Frequency;
double timeBetweenFramesInSeconds = 1.0/FrameRate;
if (elapsedTimeInSeconds >= timeBetweenFramesInSeconds) {
stopwatch.Restart();
writer.WriteVideoFrame(frame.ToBitmap());
}
}
Где наш черный ящик называет Start
, End
и Draw
методы. Текущая проверка, что у меня есть в Draw
, мешает нам рисовать слишком быстро, но не делает ничего, чтобы обрабатывать случай рисования слишком медленно.
Возможно, стоит использовать '' System.Diagnostics.Stopwatch' (https://msdn.microsoft.com/library/system.diagnostics.stopwatch.aspx) вместо вычитания 'DateTime', если вы работаете с высокие частоты кадров - 'секундомер' [более точный] (http://blogs.msdn.com/b/ericlippert/archive/2010/04/08/precision-and-accuracy-of-datetime.aspx). –
Это почти то же самое, что я использовал, за исключением того, что я (по какой-то причине в то время) получил промежуток времени от вычитания тиков из 'DateTime.Now' вместо того, чтобы просто вычитать напрямую (что приводит к' TimeSpan'. m довольно уверен, что вы не можете использовать 'TimeOfDay'. Это не удастся, если ваша запись пройдет полночь. Должен использовать только' DateTime.Now'. – Kat
Я использую только 25 кадров в секунду, хотя моя веб-камера может справиться с этим. просто не могу обработать этот фрейм достаточно быстро. В моем случае я принудительно перезагружаю сохранение, когда он достиг полуночи, а затем инициализирует новый. Один из лучших способов увеличить процесс создания фальшивки - создать новый отдельный поток для писателя. – keysl