Как стать автором
Поиск
Написать публикацию
Обновить
30

Как мы в Fix Price автоматизировали создание рекламных видео

Время на прочтение7 мин
Количество просмотров877

Привет, Хабр! Меня зовут Андрей Денисов и я видеодизайнер 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.

Теги:
Хабы:
+8
Комментарии2

Публикации

Информация

Сайт
tech.fix-price.com
Дата регистрации
Численность
свыше 10 000 человек
Местоположение
Россия