День 1. 15 апреля, 19:39–21:19. Рембг и CDN-кэш

Вечером вернулись к Хичкоковскому плану — висящие ноги слева, закрытая дверь справа. Задача: собрать mockup «дверь + ноги», прогнать через Сидрим, получить финальный кадр shot1_door_with_foot.

Заход 1: грязный фон

Пользователь с утра отметил, что ноги в прошлом наброске были мелкие:

«Мелкие очень ноги, можешь сам посмотреть»

Оказалось, shot1_door_closed.png по факту был 892×382 — агент перепутал числа и собрал mockup в неправильном масштабе. Переделал: кроп только ноги и ботинки из body_ref.png, без пола.

body_ref — исходный эталон позы

body_ref — исходный эталон позы

Mockup собрал: тело висящее слева, дверь справа, туловище уходит вверх за кадр. Шов вокруг ног видно — это фича, layout-инструкция.

Отправил в Seedream 5.0-lite через Evolink: shot1_door_closed.png + mockup как два рефа. 37 секунд, получили shot1_door_with_foot.png (первая версия):

✅ Ноги висят в левой части, туловище за кадром.
✅ Дверь справа, закрытая, ожидающая.
✅ Обои, тумбочка, паркет — всё на месте.
✅ Ботинки и брюки тёмные, как костюм в shot1.

Хичкоковский приём работает — зритель знает что в комнате, дверь становится зловещей.

«Ботинки под другим ракурсом»

«Не, херня, ботинки же должны быть немного под другим ракурсом»

body_ref.png снят анфас, а наш кадр на дверь — с 45° слева. Ноги должны быть в ¾, не прямо. Добавил в промпт инструкцию «three-quarter angle, not head-on» — Сидрим ожидаемо проигнорировал: 3D-вращение из текста он не умеет, копирует ориентацию из рефа.

Первый запуск с инструкцией "three-quarter angle" → shot1_door_with_foot_v2.png: ноги остались фронтальными (Сидрим не умеет 3D-вращение текстом):

shot1_door_with_foot_v2 — позже пользователь переделал этот файл в 16:9 для video

shot1_door_with_foot_v2 — позже пользователь переделал этот файл в 16:9 для video

Нужен новый pose-ref — «висящее тело под нужным углом». Text-to-image, без рефов:

Пользователь:

«Зачем флип? Без флипа и так влево носки»

Да, прав. Используем как есть. Кроплю ноги, собираю mockup, отправляю — и получаю shot1_door_with_foot_v3 / _v4. Но в кадре снова фронтальные ноги, не ¾.

Инсайт дня: Evolink кеширует по имени файла

После нескольких итераций, где Сидрим упорно выдавал старые ноги, пользователь сформулировал гипотезу:

«Тут важный момент, он берёт не абстрактные ноги фронтальные, а буквально те же самые, что в первом мокапе. Есть теория, что он видит то же название файла? И даёт тебе старый URL»

URL у Evolink действительно содержит имя файла:

https://files.evolink.ai/00551HC8TAUP94NFJS/images/png/shot1_door_with_foot_mockup.png

Когда shot1_door_with_foot_mockup.png перезаписывается локально новым содержимым и загружается — Evolink дедуплицирует по имени и возвращает старый URL с кешем первой версии. Сидрим получает самый первый mockup (с фронтальными ногами), а не свежий.

Фикс в seedream_gen.py — в имя при загрузке добавился SHA-256 первых 12 символов контента:

hash_prefix = hashlib.sha256(raw).hexdigest()[:12]
filename = f"{path.stem}_{hash_prefix}{path.suffix}"

Перезапуск — и ноги реально в ¾ углу, с правильной асимметрией (правая нога вперёд, левая чуть сзади). Критический баг найден пользователем. Все предыдущие итерации Сидрим получал первый mockup, как бы мы ни меняли локальный файл.

Ещё итерации по композиции

«Да, и ты кропнул немного ноги снизу. И сами ноги чуть левее надо»
«Чуть крупнее ноги, на 20%»

v6: ноги крупнее, на самом левом краю кадра, ботинки целиком в ¾ ракурсе. Но появилась новая проблема — вокруг ног Сидрим насыпал грязи на обоях, интерпретируя резкую кромку силуэта как «что-то испачкано».

От пороговой маски к rembg

Первая попытка фикса: кроп до самой подошвы без захвата серого пола из pose-ref'а (v7). Результат — «фон исчез, только концов ботинок тоже нет». v8 — золотая середина, но пользователь:

«Неправда, носки отрезало, а фон нет»

Агент понял: Сидрим ленив — тянет всё, что в mockup'е. Серый прямоугольник вокруг ног в коллаже → серый пятно в выводе.

Решение — силуэт по маске яркости (тёмные пиксели = ноги, светлые = прозрачно). Порог 110 → v9: силуэт на обоях Сталинки, серого прямоугольника нет. Но:

«Фон не отрезало (почему не отрезает?). И носки тоже отрезаны чуточку»

Увеличил порог, убрал блюр. Mockup выглядит чисто. Отправил — SSL-ошибка на Evolink (SSLEOFError), пять попыток подряд. Подождал минуту, прошло.

v10: модель насыпала визуального мусора вокруг ног. Промптом явно запретил debris, grime, dark smudges (v11) — чище, но артефакты всё ещё есть. Попробовал с мягкой маской и blur на краях (v12):

✅ Обои Сталинки за ногами без серых патчей.
⚠️ Тёмные пятна на стене выглядят как часть узора, но...

«Не, грязь вокруг ног, просто она теперь размытая»

И вот фундаментальный вывод:

pip install rembg — библиотека alpha matting на U2Net. Через 30 секунд — 176MB модели скачано, установлено. Переписал сборку mockup'а: вместо порога по яркости — remove(legs_crop) (RGBA с чистой alpha), paste с alpha-маской.

shot1_door_with_foot — rembg победил

shot1_door_with_foot — rembg победил

v13: обои вокруг ног чистые — никакого halo, никакой грязи. Ноги висят в левой части, ботинки в ¾, дверь справа, локация M1 сохранена.

«Ну ладно, давай»

Второй утверждённый кадр. Ключевой урок: для composition mockup'ов — ровно U2Net-сегментация, пороговые маски не работают.

Seedance: первый видео-пайплайн

Пользователь сразу перевёл разговор на видео:

«А потом на основе этого кадра давай сгенерим Seedance-видео: сначала пару секунд ноги качаются, потом дверь выбивают с ноги и заходит бандит (на него есть карточка персонажа)»

Написал seedance_video.py под endpoint /v1/videos/generations, модель seedance-2.0-reference-to-video, до 9 рефов + промпт.

v1: 5с, 720p, 21:9. Рефы: shot1_door_with_foot.png + char_bandit.jpg. Без @image тегов — агент пропустил конвенцию из гайда.

v2: тот же запуск, но с явными тегами — @image1 as first frame, @image2 as character. По гайду Seedance роли рефов маркируются в тексте промпта.

[missing] shot1_video_v1 — без @image тегов, 5 сек
../archive/shot1_video_v1.mp4
[missing] shot1_video_v2 — с @image1/@image2, 5 сек
../archive/shot1_video_v2.mp4

«Вышло неплохо. Только теперь нужна версия с таймингом»

Пользователь прислал пример формата из MindStudio:

Global style: cinematic, 4K, cold colors.
[0s–4s]: Wide shot, static.
[4s–7s]: Medium shot, slow push in.
[7s–10s]: Close-up.

И ТЗ: 10 секунд, 3 секунды до выбивания двери, потом всё как было, взгляд подольше.

v3 с таймкодами. 458 сек генерации, 3.2MB.

[missing] shot1_video_v3 — 10с с таймкодами
../archive/shot1_video_v3.mp4

«В 10с видео не сработала задержка перед началом, увы. И выбивание хуже чем на коротком. Пока v2 лучшее»

6-step формула из гайда Seedance

Агент переписал по гайду: префикс Style:/Duration:/Camera:, одна камерная директива (static locked-off), явные роли рефов, таймкоды в формате [MM:SS-MM:SS], negative prompts в конце.

v4, 10 сек, 346 сек генерации, 3.4MB:

Style: cinematic black and white 35mm film, grainy, deep blacks, high contrast.
Duration: 10s.
Camera: fixed, static locked-off wide shot throughout.

@Image1 as first frame and background environment.
@Image2 as character reference.

[00:00-00:03] dead silence, hanging legs sway slightly.
[00:03-00:05] door kicked open, slamming inward.
[00:05-00:10] bandit stands frozen, breathing heavily.

Avoid jitter. Avoid bent limbs. Avoid identity drift. Avoid camera movement.
[missing] shot1_video_v4 — по гайду Seedance
../archive/shot1_video_v4.mp4

Пользователь:

«3с пауза есть, но дверь выбивается недостаточно резко и после выбивания бандит слишком быстро входит. И у него появился пистолет в руках — это лишнее»

v5 и кончились кредиты

Правка: сжал удар двери до 1 секунды ([00:03-00:04]), дал 3 секунды на силуэт в проёме до первого шага, явно в промпте и в character-реф: «hands empty, no weapons, no gun».

Запуск → HTTP 402 insufficient_quota. Один 10-сек запрос стоит 135 кредитов Evolink, осталось 30.

«Варианты: пополнить Evolink; WaveSpeed ($1 триал, возможно потрачен); fast-режим (seedance-2.0-fast-reference-to-video). Пока не пополнишь — ничего не прогоню. Промпт v5 в чате выше, скажешь когда — продолжу»

Итог вечерней сессии

За полтора часа:
- shot1_door_with_foot.pngутверждён как canon, через rembg + composition mockup.
- Найден CDN-кэш баг Evolink: дедупликация по имени файла → новое содержимое не долетает до модели. Фикс: SHA-256 префикс в имени.
- rembg / U2Net вошёл в инструментарий — для чистой сегментации вместо пороговых масок.
- Написан seedance_video.py — reference-to-video пайплайн, до 9 рефов.
- Выведена форма Seedance промпта из гайда: Style/Duration/Camera + явные роли @image + таймкоды + negatives.
- v2 (5 сек, без таймкодов) — бенчмарк. v4 (10 сек, по гайду) даёт 3-сек паузу, но выбивание мягче.
- День остановлен на insufficient_quota, промпт v5 ждёт пополнения.