Рассчитать кадры для удаления, чтобы получить интервал желаемой длины

У меня есть много изображений, хранящихся на сервере, и ссылка в базе данных MySQL, чтобы я мог легко запросить у них изображение с определенных дат / времени.

Изображения принимаются с интервалом 7 изображений / час.

Допустим, я хочу создать интервал за последние 4 дня и сделать 5-секундный фильм. Как я могу рассчитать, как равномерно отбрасывать кадры, чтобы получить желаемую длину 5 секунд?

Это то, что я получил до сих пор.

Всего изображений: 4 дня * 24 часа * 7 изображений / час = 672 изображения
Требуемые изображения при 24 кадрах в секунду: 24 * 5 = 120 изображений

Разделите общее количество изображений с необходимыми изображениями, чтобы выяснить, какой / каждый кадр мне нужно сохранить

672/120 = 5,6

Затем я повторяю все 672 изображения и каждый 5-й или 6-й раз сохраняю ссылку на изображение в массиве.

Здесь моя проблема. Если я округляю вверх, я получаю видео, которое длиннее, чем я хочу, и если я округляю вниз, я получаю видео, которое короче.

Если я сохраняю каждое 5-е изображение при цикле: 134 изображения / 24 кадра в секунду = 5,6 секунды видео
Если я сохраняю каждое 6-е изображение при цикле: 112 изображений / 24 кадра в секунду = 4,6 секунды видео

Можно ли получить его лучше и при этом равномерно пропускать изображения?

Решил это, используя ответ xxfelixxx в PHP
Вот код в PHP:

$start  = 1;
$stop   = 672; // Total Images

$dur    = 5;   // Video Duration
$n      = 24 * $dur; // Required frames - 24 FPS * Duration
$next   = $start;
$step = ( $stop - $start ) / $n;

$frames = array();

for ($i = 1; $i <= $n; $i++) {
$frames[] = round($next);
$next += $step;
};

var_dump($frames);

0

Решение

Вы можете попробовать линейную интерполяцию, чтобы получить ровно 120 кадров. Интерполяция даст вам дробные числа кадров, поэтому вам просто нужно округлить до ближайшего целого числа.

Для 120 кадров в диапазоне от 1 до 672, вот индексы:

perl -e '
my $start = 1;
my $stop  = 672;
my $n     = 120;

my $step = ( $stop - $start ) / $n;
my $next = $start;
my @frames;
for ( 1 .. $n ) {
push @frames, int($next+0.5); # int truncates, so add 1/2 to round correctly
$next += $step;
};
print join(",", @frames) . "\n"'

1,7,12,18,23,29,35,40,46,51,57,63,68,74,79,85,90,96,102,107,113,118,124,130,135,141,146,152,158,163,169,174,180,186,191,197,202,208,213,219,225,230,236,241,247,253,258,264,269,275,281,286,292,297,303,309,314,320,325,331,336,342,348,353,359,364,370,376,381,387,392,398,404,409,415,420,426,432,437,443,448,454,460,465,471,476,482,487,493,499,504,510,515,521,527,532,538,543,549,555,560,566,571,577,583,588,594,599,605,610,616,622,627,633,638,644,650,655,661,666
1

Другие решения

Вам не нужно выполнять какие-либо расчеты.

Базовый шаблон команды должен быть

ffmpeg -framerate 672/5 -i img%d.png -r 24 output.mp4

FFmpeg позаботится о выборе кадра и времени. Я пропустил параметры кодирования, такие как битрейт и т. Д.

1

По вопросам рекламы [email protected]