Aug 10, 2017

Применение маски в After Effects _после_ применения других эффектов

Сегодняшний хак по After Effects поможет вам вмешаться в порядок выполнения операций в АЕ и применить маску (или несколько масок) слоя ПОСЛЕ применения других эффектов (или где-то в середине). Для этого вы просто создаете эффект Set Channels с альфой на Off и ограничиваете действие эффекта целевой маской с помощью Compositing Options. См. картинку.

Эффект Set Channels устанавливает альфа канал в ноль, и чтобы маска работала в режиме Add надо ее инвертировать, то есть альфа канал обнулится для всей картинки кроме области маски. Естественно, этот метод поддерживает все фичи масок.

В приведенном примере на картинке вы видите, как маскированная часть изображения трансформирована и подкрашена и только затем обрезана таким вот методом. Очень удобно вместо использования Track Matte, например в случае если вам нужно двигать/скейлить изображение внтури маски.

Jul 21, 2017

Лайфхак по FFmpeg #1

Сегодня первый лайфхак по ffmpeg (для Windows). Мне надоело постоянно запускать какие-то конвертеры и что-то там настраивать. Все чаще я использую ffmpeg вместо адобовской кодилки и из-за качества в т.ч. Пришла мне такая мысль, добавить пункты автоматической конвертации в нужный формат через меню Винды Send To (Отправить), которое вы видите при правом клике на любой файл.

Итак тут первый пример, если пендрите в ffmpeg, то на его основании можете сделать кучу разных пресетов. Все очень просто!

1. Скачайте, установите ffmpeg. Я его к тому же добавила в системный PATH, чтобы можно было легко запустить отовсюду.

2. Создайте .bat файл с текстом (3 строки):
@echo off
"c:\Program Files\ffmpeg\bin\ffmpeg.exe" -i %1 -c:v libx264 -preset slow -crf 18 -c:a copy %1_output.mp4
pause
Назовите этот файл, допустим convert to preview mp4.bat
Если вы установили ffmpeg в отличную папку, измените путь на соответствующий.

3. Положите этот bat файл куда вам удобно (например в документы), создайте его ярлык (перетащите, зажав Alt), а его положите в папочку %userprofile%/SendTo
Переименуйте его, если необходимо убрать слово "Ярлык", но не изменяйте расширения .lnk, также вы можете изменить в его свойствах иконку и настройки консоли. Если вы вдруг не можете найти папку SendTo, то загляните в ...\AppData\Roaming\Microsoft\Windows\SendTo, но обычно на нее есть ярлык в папке юзера.

4. Теперь вам достаточно в проводнике кликнуть по любому видео правой кнопкой и выбрать Send To, там вы увидите то самое название convert to preview mp4 (или как вы там переименовали сам ярлык). Команда добавляет к имени исходного файла  _output.mp4, сохранится файл в исходную папочку.

Конкретно этот пресет создает h264 high 4:2:2 L3.1, yuv422p, а звуковую дорожку копирует как есть из исходника. Позже сделаю еще несколько бат-файлов с разными вариантами сжатия. Пишите, какие вам нужны. А далее я расскажу как собрать секвенции, как конвертить стерео, как размукзсить или замуксить mkv.

Субхак. Сами bat-файлы можно хранить в вашей облачной папке, тогда все пресеты будут автоматически синхронизироваться для всех машин.

Подсказка. Скорость потока регулируется ключом -crf, значения от 0 (lossless) до 53 (и до 63 в 10-битном цвете) по экспоненциальной шкале, т.е. разность в 6 единиц = изменение потока в 2 раза. Значение 18 принято считать visually lossless. Но на скорость потока влияет и параметр -preset.

ПС. Да, я знаю, есть много GUI для ffmpeg, но среди опробованных мною ни один не прижился. Этот способ чрезвычайно прост, бесплатен, вся процедура займет у вас считанные минуты. Пожалуйста!

АПДЕЙТ
Вот такие три варианта настроек у меня в работе сейчас, пока все mp4, добавилась проверка на передачу параметра. Три текста для отдельных bat-фалов:

h264 mp4 420p законстрейнейный под level3.0 (более совместимый со старыми устройствами и плеерами)
@ECHO OFF
IF %1.==. (
ECHO [-------------- SendTo FFmpeg converter ---------------]
ECHO [     NO FILE SPECIFIED                                ]
ECHO [------------------------------------------------------]
) ELSE (
"c:\Program Files\ffmpeg\bin\ffmpeg.exe" -v warning -i %1 -c:v libx264 -profile:v baseline -level 3.0 -pix_fmt yuv420p -preset slow -crf 24 -c:a aac -b:a 128k -y %1_420_constrL3.mp4
ECHO [-------------- SendTo FFmpeg converter ---------------]
ECHO [     SERVED                                           ]
ECHO [------------------------------------------------------]
)
PAUSE
h264 mp4 422p medium quality, slower
@ECHO OFF
IF %1.==. (
ECHO [-------------- SendTo FFmpeg converter ---------------]
ECHO [     NO FILE SPECIFIED                                ]
ECHO [------------------------------------------------------]
) ELSE (
"c:\Program Files\ffmpeg\bin\ffmpeg.exe" -v warning -i %1 -c:v libx264 -preset slower -crf 16 -pix_fmt yuv422p -c:a copy -y %1_422_medium_slower.mp4
ECHO [-------------- SendTo FFmpeg converter ---------------]
ECHO [     SERVED                                           ]
ECHO [------------------------------------------------------]
)
PAUSE
h264 mp4 422p high quality, slower
@ECHO OFF
IF %1.==. (
ECHO [-------------- SendTo FFmpeg converter ---------------]
ECHO [     NO FILE SPECIFIED                                ]
ECHO [------------------------------------------------------]
) ELSE (
"c:\Program Files\ffmpeg\bin\ffmpeg.exe" -v warning -i %1 -c:v libx264 -preset slower -crf 8 -pix_fmt yuv422p -c:a copy -y %1_422_highest_slower.mp4
ECHO [-------------- SendTo FFmpeg converter ---------------]
ECHO [     SERVED                                           ]
ECHO [------------------------------------------------------]
)
PAUSE

May 25, 2017

Работа с массивами и строками в выражениях After Effects (статья дополняется)

* Эта статья находится в разработке, многое еще ищется и добавляется*
Это небольшой справочник, который я решила сделать для себя и всех, кто часто использует выражения при работе в Adobe After Effects. Поскольку выражения являются подмножеством JS, то многие возможности ускользают от пользователей After Effects, мало знакомых с программированием. Я решила пройтись по JS и протестировать совместимые функции и методы. Надеюсь этот справочник поможет вам успешнее использовать выражения в вашей работе и применять больше генеративных возможностей. Этот справочник будет уточняться и расширяться. Все, что здесь написано, проверено для версии CC 2014.


1. Массивы

Массив (объект Array) это объект, в котором сохранено некоторое количество других объектов, где каждому из них сопоставлен последовательный номер (индекс элемента). Элементы называются объектами, т.к. не имеют четкого типа. Вы можете смешивать в массиве значения разных типов (например и числовые и текстовые). Но за этим кроются некоторые подводные камни. Для простоты будем пока рассматривать одномерный массив вида:
[1, 2, 3, 5, 7, "eight", -10]
Операции с массивам перебором элементов в цикле это громоздко и медленно, давайте посмотрим, какие возможности нам предоставляет Java Script. Начнем с базовых арифметических операций. Для этого нам надо избавиться от текстового значения в примере выше, иначе мы получим сообщение об ошибке, т.к аримфетические операции не могут применяться к текстовым значениям. Для следующих примеров возьмем за исходный массив:
a = [1, 2, 3, 5, 7, 8, -10]
Я наверное опущу такие простые операции, как извлечение элемента массива вида b = a[3], когда в результате переменной b мы присваиваем значение третьего элемента. Не забывайте, что нумерация элементов массива начинается с нуля.

1.1 Сложение и вычитание массивов

b = a + 1

В данной операции правый операнд рассматривается как массив из одного элемента, то есть выглядит как a + [1], таким образом единица добавится к нулевому элементу массива а, получаем:
[1, 2, 3, 5, 7, 8, -10] => [2, 2, 3, 5, 7, 8, -10]
Отсюда легко догадаться каков будет результат следующей операции:
b = a + [1, 1, 1]
К первым трем элемента будет добавлено по единице:
[1, 2, 3, 5, 7, 8, -10] => [2, 3, 4, 5, 7, 8, -10]

1.2 Умножение и деление

b = a * 2
Здесь все работает немного по-другому, и операция умножения или деления выполняется для всех элементов массива. Результат:
[1, 2, 3, 5, 7, 8, -10] => [2, 4, 6, 10, 14, 16, -20]
Умножение массива на массив невозможно.

1.3 Теперь рассмотрим функции объекта Math с массивами

Допустим нам надо вычислить значения синуса. Конструкция Math.sin(a) не сработает и вернет нам результат NaN. Поэтому самое время добавить к нашим знаниям метод применения функции ко всем элементам массива. Метод объекта массива map не вошел в АЕ, но зато вошел метод apply объекта Function. Итак применим функцию вычисления синуса к массиву:
b = Math.sin.apply([], a)
Конструкция выглядит немного странно, потому что формально мы применяем метод не к массиву, а к функции, и ей передаем массив в качестве аргумента. При этом наш массив это второй аргумент, первый аргумент указывает на прототип данных и нам не важен. Однако ж здесь нас ждет разочарование, результатом этой функции в АЕ будет значение только первого элемента. Пока я еще пытаюсь найти решение, однако же есть как минимум две очень полезные функции объекта Math, которые работают таким способом, это Math.max и Math.minТаким способом мы можем быстро найти максимальное или минимальное значение в массиве:
b = Math.max.apply([], a)
или (по идее правильнее)
b = Math.max.apply(Math, a)
возвращает нам значение 8:
[1, 2, 3, 5, 7, 8, -10] => 8

И тут давайте ввернем полезный метод slice объекта Array. Он поможет нам отсечь часть массива, например:

b = a.slice(2,5)
вернет нам массив, который будет копией элементов со 2 по 5 массива a:
[1, 2, 3, 5, 7, 8, -10] => [3, 5, 7, 8]
Или вот так (второй аргумент опциональный, если его нет, берется все до конца)
b = a.slice(3)
вернет нам все, начиная с третьего элемента:
[1, 2, 3, 5, 7, 8, -10] => [5, 7, 8, -10]
А теперь применим все вместе и найдем в массиве минимальное значение между вторым и пятым элементом:
b = Math.min.apply([], a.slice(2, 5))
получим значение 3
[1, 2, 3, 5, 7, 8, -10] => 3

1.4 Теперь все функции и методы массивов

Количество элементов в массиве (длина массива)
b = a.length => 7
Преобразования массива в строку
a.toString() => "1, 2, 3, 5, 7, 8, -10"
a.toLocaleString()
Преобразование в строку исходного кода
a.toSource() => "[1, 2, 3, 5, 7, 8, -10]"
Объединение массивов/значений в массив последовательно
b = a.concat(32,53,75) => [1, 2, 3, 5, 7, 8, -10, 32, 53, 75]
b = a.concat([32,53,75]) => [1, 2, 3, 5, 7, 8, -10, [32, 53, 75]]
Переворот массива (обратная последовательность элементов)
b = a.reverse() => [-10, 8, 7, 5, 3, 2, 1]
Cлияние массива в строку с разделителем (символ разделителя указан в операнде)
b = a.join(";") => "1;2;3;5;7;8;-10"
Cортировка массива (по возрастанию)
b = a.sort() => [-10, 1, 2, 3, 5, 7, 8]
Аргументом функции sort может выступать другая функция, но в АЕ этот метод похоже не работает

Извлечение части массива (по первому и последнему индексам элементов)

b = a.slice(4) => [7, 8, -10]
b = a.slice(3, 5) => [5, 7] 
Извлечение части массива (по индексу и количеству элементов)
b = a.splice(2) => [3, 5, 7, 8, -10]
b = a.splice(2,4) => [3, 5, 7, 8]
В JS этот метод может так же удалять и вставлять значения в массив, но не поддерживается в АЕ 

Все предыдущие методы работы с массивами возвращали измененные значения, следующие же методы изменяют сам массив, поэтому в примерах указываются два значения, первое - новое значение массива a, второе - возвращаемое знавчение b.

Отброс последнего элемента массива с укорочением его длины, возвращает выброшенное значение (последний элемент)

b = a.pop() => [1, 2, 3, 5, 7, 8] -10
Такая же операция но с нулевым элементом массива (сдвиг массива)
b = a.shift() => [2, 3, 5, 7, 8, -10] 1
Вставка значений в конец массива с увеличением его длины, возвращает новую длину массива
b = a.push(-9,-8,-7) => [1, 2, 3, 5, 7, 8, -10, -9, -8, -7]  10
b = a.push([-9,-8,-7]) => [1, 2, 3, 5, 7, 8, -10, [-9, -8, -7]]  8
Вставка значений в начало массива с увеличением его длины, возвращает новую длину массива
b = a.unshift(-2, -1, 0) => [-2, -1, 0, 1, 2, 3, 5, 7, 8, -10, -9, -8, -7]  10
b = a.unshift([-2, -1, 0]) => [[-2, -1, 0], 1, 2, 3, 5, 7, 8, -10, -9, -8, -7]  8

2. Строки

Не будем расматривать бестолковые методы html-форматирования, они нам вряд ли понадобятся. Вот их перечень на случай, если вы захотите оформить что-то в html: .anchor .big .blink .bold .fixed .fontcolor .fontsize .italics .link .small .strike .sub .sup

Создание строки s

s = "something"  => "something"
s = String("something")  => "something"
s = new String("something") => "something"
s = String(a) => "1, 2, 3, 5, 7, 8, -10"
Строки (объект String) по сути тоже являются массивами, но все их элементы это символы. Поэтому некоторые методы строк очень схожи с методами массивов. Так же как и с массивами вы можете обращаться к символам внутри строки по индексу, нумерация так же начинается с нуля. Пусть далее str = "test this thing" 
s = str[2] => "s"
s = ss.charAt(2) => "s"
Длина строки (количество символов)
b = str.length => 15
Индекс первого найденного включения строки (символа или символов) в строке
b = str.indexOf("i") => 7
b = str.indexOf("thing") => 10
b = str.indexOf("x") => -1
Индекс последнего найденного включения строки (символа или символов) в строке
string.lastIndexOf("i") => 12
string.lastIndexOf("thing") => 10
string.lastIndexOf("a") => -1 

string.charCodeAt()- код символа по индексу
ss + "" = ss.concat("")- идентично, сложение строк
string.localeCompare() - сравнение строк с кучей опций (см документацию по яве)
string.match(regexp)- проверка строки на соответствие Regular Expression
string.replace(regexp,"")- замена подстроки по Regular Expression. Пример:
 ss.replace(/thing/gi,"thing") => "test this thing"
string.search("s" or regexp) - поиск внутри строки s или Regular Expression
string.slice(a,b) - извлечение строки между указанными индексами
string.split("s", [n]) - разбиение строки на массив строк, разделитель - символ s, n - лимит
b = ss.split(" ", 3) => ["test","this","thing"]
string.substr(m,[length]) - извлечение строки с индекса по количеству символов
string.substring(m,[n]) - извлечение строки межу казанными индексами
string.toLocaleLowerCase() str.toLowerCase() - перевод строки в нижний регистр
string.toLocaleUpperCase() str.toUpperCase() - перевод строки в верхний регистр
string.toSource() - исходный код объявления строки
string.toString()
string.valueOf()


Дополнительно полезно:

instanceOf - тест на тип данных объекта. Пример: a instanceOf Array = true
eval(string) - вычисление арифметического выражения внутри строки
parseInt(string) - извлечение целого числа из строки
("00000000" + Number).substr(-n) Добавить n нулей перед числом Number

= еще будет =

операции с массивами строк
многомерные массивы


function.length - количество аргументов функции
function.arguments() - аргументы функции
function.name() - имя функции
function.prototype.call() - вызов функции как метод (похоже на apply но к набору значений)
function.toString() - получение исходного кода функции (если функция объялена в коде)

2.1 Примеры

Перевернуть порядок слов (разделитель - пробел)
s.split(' ').reverse().join(' ')  => "thing this test"
Сумма элементов массива. Здесь массив записывается в виде строки суммы и затем вычислется с помощью инструкции eval
eval(valList.join('+')) 
Минимальный элемент массива
b = Math.min.apply(Math, a) 
Максимальный элемент массива
b = Math.max.apply(Math, a) 

Jan 4, 2017

Motion Blur


Это просто пост-памятка, может кому тоже пригодится.
Post Motion Blur для 3DS Max и Mental Ray с композом в After Effects при помощи RSMB Pro от RE:Vision





1. Motion Vector Export (mi) map повесить на camera output shader, её параметры будут
Max Displace = 2000 (большое начение для работы в 32 битах в AE)
Blue Channel = off
Floating Point = off или 0 (строго)
Blur Environment/Background = off (строго, т.к. для motion vectors нужен альфа канал)

2. Зафигачить Render Passes, так как motion vectors пойдут в основной вывод, поэтому надо использовать beauty pass для вывода самого рендера, чтобы не считать beauty отдельно еще раз.

3. Финальные вектора должны выглядеть почти равномерно зелено-грязными (важно). В AE футаж векторов сделать RGB preserve. И тогда RSMB Pro Vectors в AE возьмет без всяких проблем. Блюр будет лучше, если использовать высокую битность проекта с Blend gamma 1.0 или в линейном цветовом пространстве. Рекомендуют так же, чтобы альфа у motion vectors была premultiplied black, но я сама важности этого не проверяла.