Pull to refresh

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

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



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



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

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



Вид сбоку:



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

Вид сверху:



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

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



Вид сбоку:



тут код, если кому интересно
var FRAME_WIDTH = 640;
var FRAME_HEIGHT = 360;
var FRAMES_COUNT = 640;

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

function makeFileName(i, prefix) {
    prefix = prefix || "src2/";
    return prefix + ("000" + i).substr(-4) + ".png";
}

function addStripe(dstFrame, dstFrameIdx, srcFrameIdx, callback) {
    fs.createReadStream(makeFileName(srcFrameIdx)).pipe(new PNG({filterType: 4})).on("parsed", 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 (++srcFrameIdx < FRAMES_COUNT) {
            addStripe(dstFrame, dstFrameIdx, srcFrameIdx, callback);
        } else {
            dstFrame.pack().pipe(fs.createWriteStream(makeFileName(dstFrameIdx, "dst2/"))).on("finish", callback);
        }
    });
}

function createFrame(dstFrameIdx) {
    addStripe(new PNG({ width: FRAMES_COUNT, height: FRAME_HEIGHT }), dstFrameIdx, 0, function () {
        console.log("done " + dstFrameIdx);
        if (++dstFrameIdx < FRAME_WIDTH) {
            createFrame(dstFrameIdx);
        }
    });
}

createFrame(+process.argv[2]);



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

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

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

Articles