
היו לי שמונה קליפים מדהימים באיכות 1080p ולא הייתה לי דרך נקייה להפוך אותם למסמך אחד.
זה היה הרגע שבו החידוש דעך. הדוגמנית הציגה לי צילומים קולנועיים בערך שתי דקות כל אחד. אחר כך ישבתי שם עם שמונה קבצים נפרדים, עוצמת קול לא תואמת, קליפ אחד בקצב פריימים שגוי ודד-ליין. החלק הכיפי נגמר. העבודה עצמה הייתה תיקייה של נכסים מנותקים ועבודת תפירה ידנית שלא רציתי לעשות פעמיים.
אז עשיתי מה שאנחנו עושים עם כל פלט מבולגן ולא דטרמיניסטי: עטפתי אותו בצינור.
הפוסט הזה הוא הצינור. זהו מבנה ההנחיות שאני משתמש בו כדי לקבל צילומים ניתנים לשחזור, ואת סקריפט ffmpeg אני משתמש בו כדי להפוך ערימת קליפים גולמיים לקובץ אחד מנורמל, עם כתוביות ומאוחסן בארכיון. שום דבר מזה אינו אקזוטי. זו הנקודה.
כלי וידאו מבוססי בינה מלאכותית יוצרים קליפים. הם לא מרכיבים אותם. עבודת ההנדסה אינה ביצירה, אלא בריסון הפלט: קבלת קלט עקבי, לאחר מכן נרמול, שרשור ואחסון התוצאות כך שהתהליך יהיה חוזר על עצמו במקום טיפול חד פעמי שלכם.
אם תיקחו רק דבר אחד: התייחסו לקליפים שנוצרו כאל פריטי בנייה לא מהימנים. תקניזרו אותם בדרך פנימה, ולעולם אל תערכו ידנית את שלב ההרכבה.
אני יוצר באמצעות Seedance 2.0, מודל הטקסט-לסרטון והתמונה-לסרטון של ByteDance. המודל הוא טכנולוגיה מקורית של ByteDance (ראו דף צוות Seed), אבל ממשק החזית האינטרנטי המתארח בו אני משתמש אינו חושף API REST ציבורי, וגם רוב העטיפות הפונות לצרכן עבורו לא.
זה נשמע כמו שובר עסקה לאוטומציה. זה לא. זה פשוט מעביר את האוטומציה לשני קצוות השלב הידני:
1. לפני הדור: תבנית מהירה שמייצרת צילומים עקביים וניתנים לשחזור, כך שאני לא מאלתר כל פעם.
2. לאחר הדור: צינור ffmpeg שבולע כל מה שנוחת בתיקייה ומייצר פלט נקי אחד.
ההדבקה והלחיצה האנושית באמצע נשארת ידנית. כל מה שמסביבה לא חייב להיות כזה.
האצווה הראשונה שלי הייתה גרועה. תנועה נוקשה, מוצר שהתחלף בין פריימים, אודיו שיצא מסנכרון. הבעיה לא הייתה המודל. הבעיה הייתה שכתבתי הנחיות כמו אדם שמתאר וייב במקום במאי שנותן שם לשוט.
התיקון היה מבנה חריצים קבוע. מעורפל בפנים, מעורפל בחוץ:
[subject + setting], [what moves and how], [lighting], [camera move over N seconds], [mood/style]
דוגמה קונקרטית, שנכתבה על פי התבנית הזו:
A matte-black water bottle on a wet concrete ledge, light rain,
slow droplets sliding down the surface, soft overcast key light from
the left, camera pushes in slowly over 4 seconds, calm premium mood.
ההבדל בין זה לבין "סרטון מוצר מגניב של בקבוק מים" הוא ההבדל בין דחיפה שמישה בניסיון הראשון לבין שלושה דורות מבוזבזים. אני שומר את אלה כקבצי טקסט רגילים, אחד לכל צילום, בשם shot-01.txt דרך shot-08.txt, כך שרצף נשלט על ידי גרסה וניתן להריץ אותו מחדש על ידי אדם תוך דקות.
# A sequence is just a directory of prompt files + the clips they produced
shots/
├── shot-01.txt # prompt
├── shot-01.mp4 # generated clip
├── shot-02.txt
├── shot-02.mp4
└── ...
עכשיו התשומות ניתנות לחיזוי. הגיע הזמן להפוך גם את התפוקות לצפויות.
הנה הטעות שכולם עושים: הם מנסים לשרשר קליפים ישירות ולקבל סחף אודיו, קפיצות בקצב פריימים, או כשל קשיח. מנגנון ה-concat demuxer של ffmpeg זקוק לכל קלט כדי לחלוק את אותו קודק, רזולוציה, קצב פריימים ופריסת אודיו. קליפים שנוצרו לעיתים רחוקות עושים זאת.
אז אני מקודד מחדש כל קליפ למפרט אחד קודם. לפני שלב זה, בערך 7 מתוך כל 10 אצוות שניסיתי לחבר נכשלו או הוציאו סחף אודיו. אחרי זה, כמעט אף אחד לא עשה זאת. מנגנון ה-concat demuxer מפסיק להילחם בך ברגע שכל קלט תואם:
#!/usr/bin/env bash
# normalize.sh — bring every clip to one spec before stitching
set -euo pipefail
mkdir -p normalized
for f in shots/*.mp4; do
name=$(basename "$f")
ffmpeg -y -i "$f" \
-vf "scale=1920:1080:force_original_aspect_ratio=decrease,pad=1920:1080:(ow-iw)/2:(oh-ih)/2,fps=30" \
-c:v libx264 -preset medium -crf 18 \
-c:a aac -ar 48000 -ac 2 \
"normalized/$name"
done
מה כל חלק קונה לך:
scale=...force_original_aspect_ratio=decrease ועוד pad מתאים כל רזולוציה מוזרה למסגרת 1080p מבלי למתוח פנים.fps=30 כופה קצב פריימים אחד, הדבר ששובר בשקט את השרשור.-ar 48000 -ac 2 מתקנן את השמע לסטריאו של 48kHz, כך שהעוצמה והסנכרון יפסיקו לריב איתך.-crf 18 שומר על ניקיון חזותי; העלה אותו ל-23 עבור קבצים קטנים יותר.עם כל קליפ באותו מפרט, ה-concat demuxer פשוט עובד. אני יוצר את רשימת הקבצים מכל מה שנמצא בתיקייה, כך שהוספת שוט תשיעי פירושה להיכנס. shot-09.mp4 ולהפעיל מחדש, בלי לערוך כלום.
#!/usr/bin/env bash
# assemble.sh — stitch normalized clips into one deliverable
set -euo pipefail
# Build the concat list in sorted order
: > list.txt
for f in $(ls normalized/*.mp4 | sort); do
echo "file '$PWD/$f'" >> list.txt
done
# Concatenate without re-encoding (fast, lossless, same spec)
ffmpeg -y -f concat -safe 0 -i list.txt -c copy stitched.mp4
# Optional: burn in captions from a subtitle file
if [ -f captions.srt ]; then
ffmpeg -y -i stitched.mp4 \
-vf "subtitles=captions.srt:force_style='FontSize=22,MarginV=40'" \
-c:a copy final.mp4
else
cp stitched.mp4 final.mp4
fi
# Archive with a timestamped, content-addressable name
stamp=$(date +%Y%m%d-%H%M%S)
hash=$(md5 -q final.mp4 2>/dev/null || md5sum final.mp4 | cut -d' ' -f1)
mkdir -p deliverables
cp final.mp4 "deliverables/${stamp}-${hash:0:8}.mp4"
echo "Archived deliverables/${stamp}-${hash:0:8}.mp4"
מכיוון ששלב הקונקט הוא -c copy, זה כמעט מיידי וללא אובדן נתונים. כל העבודה הקשה התרחשה במעבר הנורמליזציה, לשם הוא שייך. שם הארכיון נושא חותמת זמן וקידומת גיבוב, כך שתמיד אוכל לעקוב אחר קובץ שנמסר חזרה לריצה המדויקת שביצעה אותו.
אזהרה אחת כנה. מצב מרובה ההפניות של הכלי (הזנת טקסט ועוד כמה תמונות ועוד קליפ הפניה בצילום אחד) הוא התכונה המרשימה, והוא עולה בערך פי שניים מעלות האשראי של יצירת טקסט רגיל לסרטון. למדתי זאת על ידי שריפת כמות חינמית של קבצים אחר הצהריים, תוך יצירת מחדש של אותו רצף מכיוון שהמשכתי לכוונן קלט אחד.
התיקון שהציל אותי: תחילה למקד כל קלט בנפרד במצב זול של הפניה יחידה, ואז לעבור למצב מרובה הפניות בלבד במעבר הסופי. להתייחס למצב היקר כאל בניית ייצור, לא לולאת פיתוח.

אני רוצה להיות ישר לגבי המגבלות, כי צינור אמין רק כמו הכנות שלו:
הרצתי את זה על קליפים מ SeedAIVideo, ממשק קדמי מתארח עבור Seedance 2.0 שאני משתמש בו לייצור. גילוי נאות: זה הכלי שאני יוצר איתו, וה-pipeline שלמעלה הוא במכוון אגנוסטי לכלים. חצי ה-ffmpeg עובד על פלט מכל מודל טקסט-לווידאו. אם אתה משתמש במחולל אחר, רק שלב 1 משתנה.
ההנדסה המעניינת בסרטוני בינה מלאכותית אינה המודל. זוהי השכבה המשעממת והאמינה שסביבו: קלט סטנדרטי, ארטיפקטים מנורמלים, שלב קונקרטי שלעולם לא נוגעים בו ידנית, וארכיון שניתן לבקר בו. בנה את זה פעם אחת ותיקייה של קליפים מנותקים הופכת למוצר שניתן להפעיל שוב, לא עבודה ידנית שאתה חושש לחזור עליה.
שווה קריאה את ההפניה המלאה של ffmpeg עבור המסננים לעיל אם ברצונך לכוונן את מעבר הנורמליזציה.
איזה חלק מתהליך העבודה של נכסי הבינה המלאכותית שלך הוא עדיין שלב ידני שאתה מטפל בו? זה בדרך כלל הדבר הבא שכדאי לכתוב עליו סקריפט.