Просмотр видео «сбоку»

в 0:55, , рубрики: в разрезе, видео, Работа с видео, сбоку, сверху

Однажды у меня родился в голове вопрос о том, как бы выглядело видео, если посмотреть на него «сбоку». То есть, если сложить все кадры видео в стопку один за другим, потом разрезать эту стопку на части вдоль оси времени, получив тем самым кадры для нового видео:

Просмотр видео «сбоку» - 1

Но в интернете я не нашёл ответа. Наконец, дошли руки проделать такой эксперимент.

Ширина нового видео в таком случае равняется количеству кадров исходного, а количество кадров нового видео — ширине исходного. Я прикинул, что лучше ограничиться небольшим форматом видео (640х360) и отрезком в 640 кадров, чтобы итоговое видео получилось не утомительным по времени и достаточным, для наблюдения эффекта. Экспортировал кадры из VirtualDub в png, набросал программку для Node.js (что первое под руку попалось), обработал, собрал новые кадры обратно в видео. И вот, что получилось.

Исходное видео:

Вид сбоку:

Результат оказался интереснее, чем я ожидал. Я думал меньше распознаваемых деталей будет. Просмотрел несколько раз, чтобы разглядеть каждую сцену, потом решил взглянуть «сверху».

Вид сверху:

Вид сверху получился квадратным, более коротким (360 кадров) и менее забавным. Учитывая полученный опыт, я попытался подобрать сцену, которая смотрелась бы интереснее — с плавно перемещающимися относительно камеры персонажами в полный рост или лицо крупным планом.

Исходное видео:

Вид сбоку:

тут код, если кому интересно

var FRAME_WIDTH = 688;
var FRAME_HEIGHT = 384;
var FRAMES_COUNT = FRAME_WIDTH;

var fs = require('fs');
var PNG = require('node-png').PNG;

function makeFileName(i, prefix) {
    prefix = prefix || "srcv/";
    return prefix + ("00" + i).substr(-3) + ".png";
}

function createFrame(dstFrameIdx) {
    var dstFrame = new PNG({
        width: FRAMES_COUNT,
        height: FRAME_HEIGHT
    });

    var done = 0;

    for (var i = 0; i < FRAME_WIDTH; i++) {
        var srcFrameData = fs.readFileSync(makeFileName(i));
        var srcFrame = new PNG({filterType: 4});

        srcFrame.on("parsed", (function (srcFrameIdx) {
            return function () {
                for (var p = 0; p < FRAME_HEIGHT; p++) {
                    var srcIdx = (FRAME_WIDTH * p + (FRAME_WIDTH - dstFrameIdx - 1)) << 2;

                    var dstIdx = (FRAMES_COUNT * p + srcFrameIdx) << 2;

                    dstFrame.data[dstIdx] = this.data[srcIdx];
                    dstFrame.data[dstIdx + 1] = this.data[srcIdx + 1];
                    dstFrame.data[dstIdx + 2] = this.data[srcIdx + 2];
                    dstFrame.data[dstIdx + 3] = this.data[srcIdx + 3];
                }

                if (++done == FRAMES_COUNT) {
                    dstFrame.pack().pipe(fs.createWriteStream(makeFileName(dstFrameIdx, "dstv/")))
                        .on("finish", function () {
                            console.log("done " + dstFrameIdx);
                            dstFrameIdx++;

                            if (dstFrameIdx < FRAMES_COUNT) {
                                createFrame(dstFrameIdx);
                            }
                        });
                }
            };
        })(i));

        srcFrame.write(srcFrameData);
    }
}

createFrame(+process.argv[2]);

Не старался и не думал об оптимизации, хотел скорее получить хоть какой-то результат. После обработки первых кадров понял, что ждать не много (минут 10-15), если запустить сразу несколько процессов, и успокоился.

YouTube вроде попортил качество видео немного, поэтому прилагаю оригинальные файлы на всякий случай. Кстати, видео «с другого направления» сжимаются хуже при тех же настройках кодека.

Если кто-то уже делал нечто подобное или встречал, или есть другие идеи по необычному представлению видео или звука, делитесь в комментариях. Спасибо за внимание :)

Автор: brdsoft

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js