Привет, Хабр! Меня зовут Андрей Денисов и я видеодизайнер Fix Price. Сегодня я расскажу о нашем новом программном комплексе, который позволяет создавать ролики с рекламой наших товаров вдвое быстрее, чем раньше.
Наши магазины работают уже в 10 странах мира, а в России, Беларуси, Казахстане, мы регулярно размещаем разнообразные рекламные материалы в различных форматах. Подгонять ролики вручную под требования законодательства разных стран, особенности дизайна и форматы вещания очень затратно по времени. Также нужно учесть, что отдел рекламы должен готовить еженедельно не менее 80 роликов (это без учёта дополнительных акций, появления новых товаров и других событий).
Поэтому возникла необходимость найти решение, которое помогло бы не расширяя штат сотрудников, оптимизировать время производства шаблонных роликов. Базового программного решения на рынке не оказалось, в связи с этим мы командой глубже изучили возможности программного пакета adobe, что позволило мне попытаться разработать ПО самому и в последствии внедрить его в работу всей команде.
Fix Studio и её компоненты
Мы назвали программное обеспечение “Fix Studio”. Оно состоит из нескольких компонентов и интегрировано в общий программный комплекс Adobe. Давайте познакомимся подробнее с этими компонентами.
Fix Tool
Представляет собой расширение для Adobe After Effects. Fix Tool позволяет автоматически обрабатывать данные из файлов Excel (названия, цены, фотографии и т.д.), работает в связке HTML, JavaScript, ExtendedScript в сочетании с ExtendScript. Фактически всё, что должен сделать монтажёр, — дать команду Fix Tool на обработку файла Excel, и программа автоматически разместит все элементы ролика, прописанные в файле, на нужных местах. Это позволяет сэкономить не менее часа на создании каждого видео.
Версия предыдущего года выглядела так:

Новая версия ещё в работе (на скрине демо-версия), но дизайн немного изменился:

Вот кусочки кода:
Когда FixTool начинает обработку, он проверяет наличие материалов с помощью следующих параметров:
const configList = [ { label: "Фото OLV", field: "ЛК (lk)", basePath: "Z:\\\\!ДИЗАЙН-ВИДЕО ДМ\\\\КОЛЛЕКТ ФАЙЛЫ\\\\ФОТО ТОВАРОВ", subfolder: "OLV", extension: ".jpg" },
В случае, если какие либо фото отсутствуют, то Fix Tool сообщит об этом с помощью функции:
checkMissingFiles(jsonData, configList, function (missing) { const labels = Object.keys(missing); if (labels.length > 0) { let message = ""; labels.forEach(label => { message += `Отсутствуют ${label} в соответствующих папках:\n`; message += missing[label].join("\n") + "\n\n"; }); message += "Отправьте этот текст менеджеру по видео-контенту. Попробуйте выполнить операцию снова, когда файлы будут добавлены."; showModal(message); } else { processExcelData(jsonData); }
Далее FT начинает парсить excel таблицу:
const lk = nextRow["ЛК (lk)"] || "Нет данных"; const tradeName = nextRow["Торговое название 1"] || "Нет данных"; const tradeName2 = nextRow["Торговое название 2"] || "Нет данных"; const tagName = nextRow["Тэг"] || "Нет данных"; const price = nextRow["Цена"] || "Нет данных"; const phtvkl = nextRow["Фотовключение"] || "Нет данных"; batch.push(`${lk}|${tradeName}|${tradeName2}|${tagName}|${price}|${phtvkl}`);
Передача полученной информации в After Effects:
const combinedArgs = `10|${country}|${temptype}|${sogltype}|${nabivka}|${category}|${sound}|${batch.join("|")}`;
Внутри After Effects происходит обработка:
var parts = args.split('|'); var duration = parts[0]; // "10" или "5" var country = parts[1]; var temptype = parts[2]; var sogltype = parts[3]; var nabivka = parts[4]; var category = parts[5]; var sound = parts[6];
И идёт определение композиций, которые будут использоваться для обработки:
// Определяем список основных композиций и вспомогательных композиций if (duration === "10") {if (temptype.indexOf("LED") !== -1) {originalCompNames = ["240X720_10S_" + sogltype + "_" + temptype, "384X704_10S_" + sogltype + "_" + temptype]} else { originalCompNames = ["16X9_10S_" + sogltype + "_" + temptype, "9X16_10S_" + sogltype + "_" + temptype]}; compsToDuplicate = ["PRICE1", "PRICE2", "PRICE3", "PRODUCT1", "PRODUCT2", "PRODUCT3", "PHTVKL1", "PHTVKL2", "PHTVKL3", "shutterstock", "Sound"]; }
Fix Encoder
Это приложение мы интегрировали в Adobe Media Encoder с помощью утилиты Fix Link. Оно создано на Python и активно использует библиотеку FFmpeg для пакетной обработки видеофайлов в разных форматах. Fix Encoder автоматизирует работу с метаданными и параметрами кадрирования. Но, в отличие от Media Encoder, где нам приходится отдельно применять пресеты и шаблоны к каждому ролику, в Fix Encoder достаточно указать папку с видеороликами, папку выгрузки и необходимый пресет.
Облегчает он работу и с не шаблонным, уникальным видео контентом. Раньше у дизайнеров много времени отнимало добавление логотипа и ценников в каждый ролик, причём нужно было учитывать форматы (для каждой страны — свой, где-то нужно сделать ролик без ценника и т.д.). Fix Encoder решил эту проблему благодаря пакетной обработки видео с учётом предустановленных настроек. В результате дизайнеры экономят более 90% времени, которое раньше уходило на последовательную обработку каждого видео. Теперь наглядно скринами:
Сам Fix Encoder выглядит просто, минималистично и «user-friendly»: имеет всего 3 кнопки и окно со списком элементов.

Когда пользователь нажимает кнопку “+”, перед ним открывается окно с добавлением элемента в очередь.
В виде кода это выглядит следующим образом:
# Создание окна для выбора параметров add_window = ctk.CTkToplevel(self) add_window.title("Добавить в очередь") # Устанавливаем владение мышью и клавиатурой для нового окна add_window.grab_set()
Для разных пресетов есть разные условия, если пользователь забудет выбрать какой-либо из элементов, то ему придет оповещение:
# Проверка на наличие файла брифа только для пресетов "Новинки" и "ООН" if current_preset in ["Новинки", "ООН"] and brief_file_label.cget("text") in ["Файл брифа не выбран", ""]: tk.messagebox.showerror("Ошибка", "Пожалуйста, выберите файл брифа для выбранного пресета.") return # Проверка на наличие папки с видео if video_folder_label.cget("text") in ["Папка с видео не выбрана", ""]: tk.messagebox.showerror("Ошибка", "Пожалуйста, выберите папку с видео.") return # Проверка на наличие папки с видео if output_folder_label.cget("text") in ["Папка выгрузки не выбрана", ""]: tk.messagebox.showerror("Ошибка", "Пожалуйста, выберите папку выгрузки.") return
После добавления элемента в очередь, пользователь видит его в списке элементов.
Также пользователь может открыть контекстное меню, кликнув конкретный элемент и нажав ПКМ:

Далее, когда пользователь нажимает на кнопку обработки, то Fix Encoder начинает проверять элементы на статус, если элемент в очереди имеет статус «В очереди», то он начинает его обработку, а после меняет статус элемента на «Выполнено», для большинства пресетов обычно используется библиотека FFmpeg, которая позволяет быстро обработать видеоролики:
if status == "В очереди" and preset == "LED 384x704": # Выполняется рендер video_folder_path = item[0] output_folder_path = item[1] path = os.path.join(f'{output_folder_path}\\LED') os.makedirs(path, exist_ok=True) for filename in os.listdir(video_folder_path): if filename.endswith('.mp4'): filename_without_ext, ext = os.path.splitext(filename) subprocess.run(['ffmpeg', '-y', '-i', os.path.join(video_folder_path, filename), '-vf', 'scale=384x704', '-an', os.path.join(f'{output_folder_path}\\LED\\{filename_without_ext}.mp4')],creationflags=subprocess.CREATE_NO_WINDOW) self.tree.item(i, values=item[:-1] + ["Выполнено"])
Если в обработку берется телевизионный формат, то Fix Encoder обращается к Fix Link следующим образом:
os.system('taskkill /im "Adobe Media Encoder.exe" /F') # Выполняется рендер video_folder_path = item[0] output_folder_path = item[1] # Путь к исполняемому файлу ExtendScript (Adobe Media Encoder) extendscript_path = r'"%ALLUSERSPROFILE%\Microsoft\Windows\Start Menu\Programs\Adobe Media Encoder 2025.lnk"' # Путь к вашему скрипту JSX jsx_script_path = r'C:\FixStudio\bin\Utilites\FixLink.jsx' # Путь к файлу, в который будут записаны данные data_file_path = r'C:\FixStudio\bin\Utilites\data.txt' # Значение переменной, которое нужно передать в скрипт JSX # Записываем данные в файл with open(data_file_path, 'w') as f: f.writelines([video_folder_path + '\n',output_folder_path + '\n',"KZ"]) # Команда для запуска Adobe Media Encoder с передачей пути к файлу данных
Так как Adobe Media Encoder выполняет сценарии только один раз после запуска, то Fix Encoder закрывает его перед началом работы. И затем заново открывает, но уже с аргументом для запуска Fix Link.
В случае обработки новинок или ООН, Fix Encoder обращается к брифу, брифы заполняются менеджерами.
Fix Link
Эта утилита — связующее звено Fix Encoder с Media Encoder. Она позволяет автоматизировать процесс кодирования группы роликов и использовать все возможности Media Encoder внутри автоматизированных сценариев. Фактически Fix Link указывает Media Encoder на действия для выполнения: например, применить к видеороликам, расположенным в определенном месте, конкретный пресет, настройки и выгрузить их в определенную папку.
После запуска Adobe Media Encoder запускает Fix Link (который был указан ранее в качестве аргумента для запуска Adobe Media Encoder внутри Fix Encoder), который сообщает ему данные для обработки:
if (country === "RU") { if (exporter) { // Add each video file to the batch and apply the specified preset for (var i = 0; i < videoFiles.length; i++) { var wapfolder1 = new Folder(outfolder + "\\wap\\16x9"); var wapfolder2 = new Folder(outfolder + "\\wap\\FHD"); wapfolder1.create(); wapfolder2.create(); var videoFile = videoFiles[i]; var source = videoFile.fsName; var destination1 = (outfolder + "\\wap\\16x9"); var destination2 = (outfolder + "\\wap\\FHD"); var preset1 = "C:\\FixStudio\\bin\\Utilites\\EPR\\RU\\SD_16-9_1.epr"; var preset2 = "C:\\FixStudio\\bin\\Utilites\\EPR\\RU\\FullHD.epr"; var matchSourceSettings = false; // optional var writeFramesToDisk = false; // optional var itemsToEncode = (videoFiles.length * 2); var encoderWrapper = exporter.exportItem( source, destination1, preset1, matchSourceSettings, writeFramesToDisk );
После того, как Adobe Media Encoder заканчивает обработку, он закрывается:
if (encoderWrapper && encoderWrapper1) { encoderWrapper.addEventListener( "onEncodeFinished", function (eventObj) { itemsEncoded++; // Increment itemsEncoded when a file has finished encoding. if (itemsEncoded === itemsToEncode) { app.quit(); } }, false );
Пользователь не видит сам Fix Link, так как он всего лишь сообщает Media Encoder видео в обработку и ее параметры.
Пример ролика
Итак, Fix Studio обращается к брифу, собирает все необходимые данные из разных папок и файлов и размещает их в нужных местах видео согласно запрограммированному шаблону. Вот как это выглядит:

Это для понимания, сколько видеороликов требуется сделать. Раньше у дизайнера могло уйти несколько рабочих дней на выполнение данной задачи, а сейчас примерно 4-6 часов.
Преимущества Fix Studio
Главные достоинства разработки для сотрудников студии:
-
Быстрый запуск благодаря Fix Tool и импорту данных из Excel;
-
Автоматизация кодирования сотен файлов одновременно;
-
Полноценная интеграция с ТВ-форматами путём связывания Fix Encoder с Media Encoder через Fix Link.
В результате мы:
-
Получили колоссальную экономию времени;
-
Уменьшили влияние человеческого фактора при создании видеоконтента;
-
Обеспечили полноценную интеграцию Fix Studio с продуктами Adobe.
ссылка на оригинал статьи https://habr.com/ru/articles/930974/
Добавить комментарий