До списку уроків
8A · Урок 10 з 16

Мій перший монтаж у командному рядку

виконано0%
Крок 1

Що робимо сьогодні

Модуль I · Тема 5 «Мультимедіа: відео» · урок 2 з 2 · 120 хвилин

Мета. Зібрати ролик приблизно на 10 секунд — без відеоредактора. Вирізати кілька фрагментів із джерела. Склеїти їх. Накласти титр. Усе це — самими командами. І записати монтаж так, щоб його можна було повторити з нуля.

Після уроку ти вмієш

Слова concat, drawtext і «монтажний лист» поки нічого не означають — розберемо їх по черзі.

Що з уроку 9 беремо готовим fps, роздільну здатність, бітрейт, різницю «кодек ≠ контейнер» і ключові кадри ми вже розібрали. Сьогодні вони працюють як інструмент: саме через ключові кадри обрізання «плаває», а через різні параметри доріжок падає склейка.

Хід уроку

ЕтапХвЩо робимо
Розминка5Дивимось готовий 10-секундний ролик і розбираємо його на операції
Обрізання і склейка15-ss, -t, список файлів і -f concat
Практика 1 — обов'язкова30Три фрагменти → merged.mp4, перевірка тривалості
Перерва10
Практика 225Титр drawtext — обов'язково; fade — рівень «+»
Практика 315cmd.txt, probe.txt, report.csv, монтажний лист
Очна здача медіа15Учитель дивиться final.mp4 на твоєму екрані
Підсумок і ДЗ5Куди й з якими параметрами експортувати
Разом120
Головне правило теми: важке — локально, легке — на сервер ffmpeg сьогодні не запускається на сервері жодного разу. Усі команди ти набираєш у терміналі власного комп'ютера (PowerShell або Terminal), у теці media/lesson-05/. По FTP їдуть рівно чотири легкі файли: cmd.txt, probe.txt, report.csv і index.html із монтажним листом. Готовий ролик учитель дивиться очно, на твоєму екрані — FTP-приймальня .mp4 просто відхилить.
Перше, що робить клас — три перевірки Виконай їх зараз, а не на тридцятій хвилині практики. Перша має надрукувати версію, друга — рядок drawtext, третя — рядок libx264. Якщо хоч одна нічого не знайшла, підніми руку.
macOS / Linux / Git Bash
$ ffmpeg -version $ ffmpeg -filters | grep drawtext $ ffmpeg -encoders | grep libx264
Windows PowerShell
$ ffmpeg -version $ ffmpeg -filters | Select-String drawtext $ ffmpeg -encoders | Select-String libx264
Тека уроку зветься за темою, а не за номером уроку Урок десятий, а тека — media/lesson-05/ і ~/www/lesson-05/. Так задумано: нумерація йде за темами, а «Відео» — тема п'ята. Не шукай lesson-10, її немає.
Крок 2

Анатомія команди ffmpeg

Одне правило пояснює 90% помилок: опція діє на той файл, який іде після неї

Команда ffmpeg схожа на довгий рядок без ладу. Насправді порядок у ній жорсткий, і читають її зліва направо, як речення. Частин п'ять, і кожна відповідає на своє питання.

Глобальні опції стоять на самому початку. Вони діють на весь запуск, а не на якийсь один файл. Таких у нас дві: -hide_banner прибирає зайвий службовий текст, -y дозволяє мовчки перезаписати результат. Про них є врізка одразу під схемою.

Опції входу кажуть, як читати файл, що стоїть після них. Саме тут місце для -ss, коли ролик має починатися не з нульової секунди.

Далі -i і вхідний файл. Це єдиний ключ, який показує пальцем: ось той файл, який я читаю.

Фільтри й кодеки — це вже про те, що зробити з картинкою. Накласти титр, згасити кінець. І вибрати, чим стискати відео і звук на виході.

Вихідний файл завжди останній, і ключа перед ним немає взагалі. Що лишилося в кінці рядка — те ffmpeg і запише.

ffmpeg програма -hide_banner -y глобальні опції (діють на все) -ss 00:00:12 звідки читати вхід -t 3 скільки секунд -i source.mp4 вхідний файл -vf drawtext=... фільтр: що зробити з картинкою -c:v libx264 кодувальник відео -c:a aac кодувальник звуку part1.mp4 вихідний файл завжди останній, без ключа читається зліва направо, як речення усе, що стоїть перед -i, стосується читання вхідного файлу усе, що після, — записування вихідного
Та сама опція, поставлена до -i і після нього, робить різні речі. Це не примха: ffmpeg уміє читати кілька входів одразу й писати кілька виходів, тому кожна опція має «прилипати» до конкретного файлу.
Дві опції, які варто ставити завжди -hide_banner прибирає десяток рядків про версію й конфігурацію збірки — щоб у виводі було видно саме твої помилки. -y дозволяє одразу перезаписати вихідний файл. Без нього ffmpeg спитає «файл існує, перезаписати?» і зупиниться, поки ти не введеш y.
Питання

Ти написав ffmpeg -i source.mp4 -ss 30 -t 5 part.mp4. Команда відпрацювала правильно, але думала 40 секунд — хоча вирізала всього 5. Чому так довго?

Крок 3

Обрізання: -ss, -t, -to

Три ключі, якими з довгого джерела дістають потрібні секунди

КлючЩо означаєПриклад
-ssпозиція, з якої починати (seek start)-ss 12 або -ss 00:00:12.5
-tтривалість у секундах — скільки взяти-t 3 — три секунди
-toпозиція кінця, а не тривалість-ss 12 -to 15 — теж три секунди

-t і -to разом не вживають. Якщо вкажеш обидва, ffmpeg послухається -t. Обери щось одне і тримайся його в усіх трьох фрагментах. Інакше через п'ять хвилин сам не згадаєш: 15 — це секунда кінця чи довжина шматка?

Чому -ss ставлять до -i

Відео не можна «розгорнути» на потрібній секунді, як книжку. Кадри залежать один від одного. Більшість кадрів зберігає лише різницю з попереднім — це P- і B-кадри з уроку 9. Щоб показати кадр на 30-й секунді, програма шукає найближчий попередній ключовий кадр і розкодовує все від нього.

Копіювати чи перекодовувати

Обрізати можна двома способами. Різниця між ними — як між «вирвати сторінки» і «переписати від руки».

-c copy — без перекодуванняперекодування
Що робитьпереписує вже стиснені дані в новий файлрозтискає кожен кадр і стискає наново
Швидкістьчастка секундисекунди й хвилини, кулер шумить
Якістьжодних втрат — байти ті самітрохи гірша: стиснення з втратами повторюється
Точність різутільки по ключових кадрах — початок «поїде» на 0—2 срівно там, де просив
Коли бративирізати рекламу з середини, склеїти однакові шматкиколи потрібен точний різ або треба зрівняти параметри

Сьогодні ми ріжемо з перекодуванням. Не заради точності. Заради того, щоб усі три фрагменти вийшли з однаковими параметрами. Це й є умова, за якої спрацює склейка.

вирізаємо фрагмент — той самий шаблон для всіх трьох
$ ffmpeg -hide_banner -y -ss 3 -t 4 -i source.mp4 -s 1280x720 -r 30 -c:v libx264 -preset veryfast -crf 20 -c:a aac -b:a 128k -ar 48000 -ac 2 part1.mp4
ЧастинаНавіщо вона тут
-ss 3 -t 4беремо 4 секунди починаючи з третьої
-s 1280x720 -r 30жорстко фіксуємо розмір кадру і fps — щоб у трьох фрагментів вони збіглися
-c:v libx264 -crf 20кодувальник H.264; -crf — якість, менше число = краще й важче
-preset veryfastшвидкість кодування; на уроці важливіше не чекати
-c:a aac -b:a 128k -ar 48000 -ac 2звук теж однаковий у всіх: кодек, бітрейт, частота, два канали
джерело source.mp4 — 45 с 3 → 7 с 18 → 21 с 31 → 34 с -ss 3 -t 4 -ss 18 -t 3 -ss 31 -t 3 final.mp4 — 10 с part1 · 4,0 с part2 · 3,0 с part3 · 3,0 с стик стик титр: enable=between(t,0,3) трикутники по краях — fade, рівень «+» 0 с 4 с 7 с 10 с
Дві шкали різні: угорі 45 секунд джерела, унизу 10 секунд результату. Один і той самий фрагмент займає вгорі вузьку смужку, а внизу — майже половину ролика.
Фрагменти беруться з різних місць джерела Це вимога здачі, і вона перевіряється: у монтажному листі мають бути щонайменше дві різні часові позначки джерела. Три шматки поспіль з однієї сцени — не монтаж, а просто обрізане відео.
Питання

Ти вирізав фрагмент командою з -c copy. Просив початок рівно на 12,0 с — а ролик починається з 10,5 с. Файл не пошкоджений, команда без помилок. Що сталося?

Крок 4

Склейка: concat

Два різні інструменти з однаковою назвою — і половина проблем саме через це

У ffmpeg є демюксер concat і фільтр concat. Обидва з'єднують шматки один за одним. Але працюють вони на різних рівнях і вимагають різного. Плутанина між ними дає більшість скарг «у мене concat не працює».

демюксер -f concatфільтр concat=
Як задаються шматкитекстовий список файлів list.txtусі файли через окремі -i
Рівень роботипотік байтів: дані навіть не розтискаютьсякадри: усе декодується й кодується наново
Перекодуванняне потрібне — -c copyзавжди
Швидкість на трьох шматкахчастка секундисекунди, з навантаженням на процесор
Вимоги до шматківоднакові кодеки, роздільна здатність, fps, параметри звукуоднакова роздільна здатність і формат пікселів; кодеки можуть бути різні
Коли братишматки вирізані з одного джерела однією командоюджерела різні: телефон + камера + запис екрана

Нам підходить демюксер. Усі три фрагменти ми щойно вирізали з одного джерела. Шаблон команди був той самий, тож і параметри в них однакові.

Крок 1: список файлів

Демюксер читає звичайний текстовий файл. Кожен рядок — слово file, пробіл і ім'я в одинарних лапках. Порядок рядків = порядок у ролику.

list.txt
file 'part1.mp4' file 'part2.mp4' file 'part3.mp4'

Створити його можна будь-яким редактором. У терміналі — так:

macOS / Linux / Git Bash
$ printf "file 'part1.mp4'\nfile 'part2.mp4'\nfile 'part3.mp4'\n" > list.txt
Windows PowerShell
$ "file 'part1.mp4'","file 'part2.mp4'","file 'part3.mp4'" | Set-Content -Encoding ascii list.txt
Чому саме ascii, а не utf8 Windows PowerShell 5.1 з ключем -Encoding utf8 ставить на початок файлу службову позначку BOM (три невидимі байти). ffmpeg читає перший рядок разом із нею й не впізнає в ньому директиву file. Імена файлів у нас латиницею, тому ascii достатньо — і жодних невидимих байтів. Це той самий підводний камінь, що й з probe.txt на уроці 9, тільки навпаки.

Крок 2: сама склейка

твій термінал, тека media/lesson-05
$ ffmpeg -hide_banner -y -f concat -safe 0 -i list.txt -c copy merged.mp4
ЧастинаЩо робить
-f concatкаже: наступний вхід — не відео, а список файлів. Без цього ключа ffmpeg спробує програти сам list.txt
-safe 0дозволяє імена з шляхами й символами, які демюксер вважає «небезпечними». Без нього шляхи з дискової літери або з / відхиляються
-i list.txtсам список
-c copyнічого не перекодовувати — просто перекласти готові дані в один файл

Чому склейка вимагає однакових параметрів

З -c copy ffmpeg не дивиться на картинку. Він бере стиснені порції даних і кладе їх у новий контейнер одну за одною. Час дописує на ходу. У заголовку доріжки написано «1280×720, 30 кадрів, H.264». Написано один раз на весь файл. Якщо в другому шматку насправді 640×360, переписати заголовок посеред доріжки нікуди.

так падає part1 1280×720 · 30 fps h264 · aac 48 кГц part2 640×360 · 25 fps h264 · aac 44,1 кГц роздільна здатність частота кадрів частота звуку кодек ✕ різна ✕ різна ✕ різна ✓ однаковий заголовок доріжки один на весь файл — переписати його посеред ролика нікуди. Плеєр застигає або сиплеться на стику. так тримає part1 1280×720 · 30 fps h264 · aac 48 кГц part2 1280×720 · 30 fps h264 · aac 48 кГц роздільна здатність частота кадрів частота звуку кодек ✓ однакова ✓ однакова ✓ однакова ✓ однаковий параметри збігаються, бо обидва фрагменти вирізані з одного джерела одним і тим самим шаблоном команди.
Найнадійніший спосіб уникнути лівої половини картинки — не «лагодити» шматки після, а вирізати їх однаково з самого початку.
Найпідступніше — коли помилки немає Демюксер із -c copy часто не падає на різних параметрах. Він спокійно збирає файл, а плеєр після стику показує застиглу картинку зі звуком або сиплеться квадратами. У виводі при цьому видно рядок про Non-monotonic DTS — і його дуже легко проґавити.
Питання

Ти склеїв два кліпи. У другому фрагменті голос відстає від губ. Перший фрагмент грає нормально. У чому річ?

Питання

concat відпрацював без жодної помилки, файл створено. Але після стику картинка застигає, хоча звук іде далі. Що сталося і що робити?

Перевіряємо результат одразу

Не переходь до титру, поки не побачив правильну тривалість. Стик має бути видно на око: змінюється сцена.

перевірка склеєного
$ ffprobe -hide_banner -show_entries format=duration -of default=noprint_wrappers=1 merged.mp4 duration=10.048000

Цільова тривалість — 10 секунд ±0,5. Число 10,048 у прикладі вище ілюстративне. У тебе буде своє, і рівним воно майже напевно не буде. Це нормально: тривалість кратна кадрам, а не круглим секундам.

Крок 5

Титр: фільтр drawtext

Обов'язкова частина роботи. Твоє ім'я на перших секундах ролика

drawtext — це відеофільтр. Він отримує кадр, малює на ньому текст і віддає далі. Фільтр працює з розтиснутою картинкою, тому -c copy тут неможливий: відео доведеться перекодувати. Звук чіпати не треба — його якраз копіюємо.

Windows PowerShell — зверни увагу на шлях до шрифту
$ ffmpeg -hide_banner -y -i merged.mp4 -vf "drawtext=fontfile='C\:/Windows/Fonts/arial.ttf':text='Олена Петренко':fontsize=42:fontcolor=white:borderw=2:bordercolor=black:x=(w-text_w)/2:y=h-th-40:enable='between(t,0,3)'" -c:v libx264 -crf 20 -preset veryfast -c:a copy final.mp4
macOS — інший шлях до шрифту, решта та сама
$ ffmpeg -hide_banner -y -i merged.mp4 -vf "drawtext=fontfile='/System/Library/Fonts/Supplemental/Arial.ttf':text='Олена Петренко':fontsize=42:fontcolor=white:borderw=2:bordercolor=black:x=(w-text_w)/2:y=h-th-40:enable='between(t,0,3)'" -c:v libx264 -crf 20 -preset veryfast -c:a copy final.mp4
Параметр фільтраЩо задає
fontfileповний шлях до файлу шрифту. Не назва шрифту, а саме файл .ttf
textщо написати
fontsizeвисота літер у пікселях кадру. Для 720p 36—48 — читабельно
fontcolorколір: назва (white) або 0xRRGGBB
borderw, bordercolorобведення. Без нього білий титр зникає на світлому кадрі
x, yкоординати. Тут вирази: w, h — розмір кадру, text_w, th — розмір напису
enableколи титр видно. between(t,0,3) — з 0-ї по 3-тю секунду

Вираз x=(w-text_w)/2 ставить напис по центру. Ширину літер рахує сам ffmpeg, тому довжина тексту не має значення. y=h-th-40 притискає титр до низу кадру. Відступ — 40 пікселів.

Чому фільтру потрібен шлях до шрифту

ffmpeg — не текстовий редактор. Списку шрифтів системи він не бачить. Малює літери він лише через бібліотеку FreeType. А їй треба дати конкретний файл із контурами літер. Тому fontfile — це шлях, а не назва. «Arial» для ffmpeg порожній звук, а C:/Windows/Fonts/arial.ttf — файл, який лежить на диску.

Двокрапку у шляху Windows треба екранувати Усередині фільтра : розділяє параметри. Тому диск пишеться як C\:/Windows/Fonts/arial.ttf — зі зворотною скісною перед двокрапкою. І скісні — прямі: зворотні \ фільтр читає як екранування. Це пункт, на якому щороку застрягає пів класу.
Шрифт має містити кирилицю arial.ttf, Arial.ttf і DejaVuSans.ttf її мають. Якщо взяти шрифт без кирилиці, титр вийде порожнім або з квадратиками — і це не помилка команди, команда відпрацює успішно.
СистемаРобочий шлях до шрифту
WindowsC\:/Windows/Fonts/arial.ttf
macOS/System/Library/Fonts/Supplemental/Arial.ttf
Linux/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf
Питання

На Windows ти написав у фільтрі fontfile=C:/Windows/Fonts/arial.ttf і отримав скаргу на розбір фільтра. Що саме треба виправити?

Кадр-постер

З готового ролика витягуємо одну картинку — її вчитель дивиться поруч із відео. Беремо кадр із першої секунди, де вже видно титр.

один кадр у JPEG
$ ffmpeg -hide_banner -y -ss 1 -i final.mp4 -frames:v 1 poster.jpg

-frames:v 1 означає «записати рівно один відеокадр і зупинитися». У старих прикладах з інтернету цей ключ пишуть як -vframes 1. Це його давня назва, вона працює й досі.

Крок 6

Згасання fadeрівень «+»

Необов'язково. Береться тільки тоді, коли склейка й титр уже готові

Прочитай перед тим, як братися Обов'язкові сьогодні дві речі: склейка і титр. Згасання — приємний додаток, який дає бали рівня «+». Якщо часу лишилося мало, краще нормально оформити report.csv і монтажний лист, ніж кинути незібраний fade.

Фільтр fade плавно виводить картинку з чорного і зводить у чорне. Він теж працює з кадрами. Тому ставиться в той самий -vf, через кому, після drawtext. Фільтри виконуються ланцюжком зліва направо.

ПараметрЩо задає
t=in / t=outпоява з чорного чи згасання в чорне
st=секунда, на якій ефект починається
d=скільки секунд він триває

Для 10-секундного ролика: поява з 0-ї секунди тривалістю 1 с. Згасання — з 9-ї, теж на секунду. Секунду початку згасання рахують від кінця: тривалість мінус довжина ефекту.

титр і згасання одним ланцюжком фільтрів
$ ffmpeg -hide_banner -y -i merged.mp4 -vf "drawtext=fontfile='C\:/Windows/Fonts/arial.ttf':text='Олена Петренко':fontsize=42:fontcolor=white:borderw=2:bordercolor=black:x=(w-text_w)/2:y=h-th-40:enable='between(t,0,3)',fade=t=in:st=0:d=1,fade=t=out:st=9:d=1" -c:v libx264 -crf 20 -preset veryfast -c:a copy final.mp4
Порядок фільтрів у ланцюжку має значення drawtext потім fade — титр згасає разом із картинкою. Навпаки — fade потім drawtext — титр залишиться яскравим на чорному тлі, бо його домалюють уже після згасання. Обидва варіанти робочі, але виглядають вони по-різному, і на здачі варто знати, який ти обрав.
Питання

Ролик триває 10 с. Ти написав fade=t=out:st=10:d=1 — і жодного згасання не побачив, хоча помилки теж не було. Чому?

Крок 7

Конструктор монтажу

Збери ролик мишею — сторінка напише команду. Її й копіюєш у термінал

Тут монтаж із голови перетворюється на команди. Перетягни фрагменти в потрібному порядку. Постав час обрізки й текст титру. Команди внизу перезбираються одразу.

Тягни за або тисни стрілки — це змінює порядок рядків у list.txt, а не самі фрагменти. Час обрізки — секунди джерела.

0 скінець
list.txt — створи файл із таким вмістом
твій термінал, тека media/lesson-05
Кнопка «копіювати» бере лише команди Рядки-коментарі, що починаються з #, у буфер не потрапляють — копіюється те, що можна одразу вставити в термінал. Ці самі рядки ти дублюєш у cmd.txt: він поїде на сервер і саме за ним учитель питатиме, який ключ за що відповідав.
Питання

Ти поміняв фрагменти місцями в конструкторі. Які команди через це доведеться перезапустити?

Крок 8

Помилки ffmpeg і що з ними робити

Три тексти, які сьогодні побачить майже кожен. Помилка — це не поразка, а адреса

ffmpeg друкує багато. Головне правило: дивись перший рядок зі словом помилки, а не останній. Далі часто йде відлуння тієї самої проблеми на іншому рівні.

1. Unknown encoder 'libx264'

що пише ffmpeg
$ ffmpeg -i part1.mp4 -c:v libx264 out.mp4 [vost#0:0/libx264 @ 000001d2] Unknown encoder 'libx264' Error opening output file out.mp4. Error opening output files: Encoder not found

Причина. Твою збірку ffmpeg зібрали без бібліотеки x264. Такі «полегшені» збірки трапляються в системних репозиторіях і старих портативних архівах. Сам ffmpeg є, а кодувальника H.264 у ньому немає. Файл читати він уміє, створювати — ні.

Що робити. Спершу перевір, що саме є в твоїй збірці:

перевірка кодувальників
$ ffmpeg -encoders | grep 264 V....D libx264 libx264 H.264 / AVC / MPEG-4 AVC

Якщо рядка немає — потрібна повна збірка. У класі вона лежить у мережевій теці. Щоб не стояти, є запасний варіант: кодувальник -c:v mpeg4. Він є в будь-якій збірці. Якість гірша, файл важчий — зате урок рухається далі. У монтажному листі це чесно записуємо.

2. No such filter: 'drawtext'

що пише ffmpeg
[AVFilterGraph @ 0x5581f2] No such filter: 'drawtext' Error initializing complex filters. Filter not found

Причина. Цю збірку зібрали без бібліотеки шрифтів (--enable-libfreetype). Малювати літери в ній немає чим, тому й фільтра з такою назвою всередині просто немає. Перевіряється це двома командами:

чи є фільтр і чи є freetype у збірці
$ ffmpeg -filters | grep drawtext $ ffmpeg -version | grep enable-libfreetype

Що робити. Узяти повну збірку: ключем цей фільтр не ввімкнути. У Windows бери збірку з gyan.dev або BtbN. У macOS — brew install ffmpeg. У Linux — пакет ffmpeg зі звичайного репозиторію.

Сусідня помилка з тим самим фільтром виглядає інакше — і означає інше:

фільтр є, шрифт не знайдено
[Parsed_drawtext_0 @ 0x7f9c] Could not load font "arial.ttf": cannot open resource [AVFilterGraph @ 0x7f9c] Error initializing filter 'drawtext' Error initializing complex filters. Invalid argument

Тут фільтр на місці, а от файлу шрифту за вказаним шляхом немає. Найчастіше тому, що написали назву шрифту замість шляху. Або забули екранувати двокрапку диска: правильно 'C\:/Windows/Fonts/arial.ttf'.

3. Невідповідність параметрів у concat

що пише ffmpeg при склейці фільтром
[Parsed_concat_0 @ 0x561a] Input link in1:v0 parameters (size 640x360, SAR 1:1) do not match the corresponding output link in0:v0 parameters (size 1280x720, SAR 1:1) [Parsed_concat_0 @ 0x561a] Failed to configure output pad on Parsed_concat_0 Error reinitializing filters!

Причина. Фільтр concat вимагає однакового розміру кадру в усіх входів. Тут перший вхід 1280×720, а другий 640×360. З'єднати їх у одну доріжку неможливо.

У тому ж рядку помилки стоїть SAR 1:1. Зазвичай піксель квадратний, але буває й витягнутий — тоді картинку розтягують уже при показі. Форма самого пікселя й зветься SAR. Одиниця до одиниці означає «квадратний», і в обох наших фрагментах вона однакова.

Що робити. Не лагодь склейку — зрівняй джерела. Перевирізай обидва фрагменти з однаковими -s і -r, як у нашому шаблоні. Якщо джерела справді різні (телефон і камера), зведи їх до спільного розміру фільтром scale перед склейкою.

що пише демюксер, коли шляхи йому не подобаються
[concat @ 0x55f3] Unsafe file name 'C:/media/lesson-05/part1.mp4' list.txt: Operation not permitted

Це вже не про параметри, а про безпеку. Демюксер за замовчуванням не пускає абсолютні шляхи. Лікується це ключем -safe 0. Або тим, що ти працюєш у тій самій теці й пишеш у списку прості імена.

Коротко: текст помилки → діагноз

Що пишеЩо це насправдіДія
Unknown encoder 'libx264'у збірці немає H.264-кодувальникаповна збірка або тимчасово -c:v mpeg4
No such filter: 'drawtext'збірка без libfreetypeповна збірка
Could not load font ... cannot open resourceнеправильний шлях до .ttfповний шлях, двокрапка як \:
Input link in1:v0 parameters ... do not matchу фрагментів різні розміри кадруперевирізати з однаковими -s і -r
Unsafe file nameабсолютний шлях у list.txtдодати -safe 0
Non-monotonic DTS in output streamсклеїли різне з -c copy; помилки немає, але картинка застигнезрівняти параметри й склеїти наново
list.txt: Invalid data found when processing inputзабули -f concatffmpeg намагається програти сам списокдодати -f concat перед -i
File 'final.mp4' already exists. Overwrite?це не помилка, а питання; команда чекає на відповідьдодати -y

Тексти помилок наведені так, як їх друкують збірки ffmpeg 6—7. У давніших версіях формулювання коротші. Шістнадцяткові адреси в дужках щоразу свої — на них не зважай.

Титр вийшов кракозябрами — це Windows, а не ffmpeg PowerShell 5.1 передає програмі аргументи в кодуванні консолі, і кирилиця всередині -vf може дійти спотвореною. Надійний обхід: покласти текст у файл title.txt (кодування UTF-8) і замінити text='…' на textfile='title.txt'. Фільтр прочитає файл сам, повз консоль.
Питання

Команда з drawtext відпрацювала без помилок. Жодного червоного рядка у виводі. Але в ролику титру немає взагалі. Що перевіряти першим?

Крок 9

Чотири легкі файли

Ролик лишається в тебе. На VPS їде тільки текст про нього

ФайлЩо всерединіКуди
cmd.txtусі команди ffmpeg, які ти справді виконав, по рядку на командусервер
probe.txtтекстовий вивід ffprobe по final.mp4сервер
report.csvтаблиця про чотири файли: розмір кадру, fps, кодек, вагасервер
index.htmlсторінка з монтажним листомсервер
final.mp4, merged.mp4, part1–3.mp4саме відеолишається локально
poster.jpgкадр із титромлишається локально — учитель дивиться його на твоєму екрані

probe.txt — паспорт готового ролика

macOS / Linux / Git Bash
$ ffprobe -hide_banner -show_streams -show_format final.mp4 > probe.txt 2>&1
Windows PowerShell — інакше вийде UTF-16
$ ffprobe -hide_banner -show_streams -show_format final.mp4 2>&1 | Out-File -Encoding utf8 probe.txt
Той самий підводний камінь, що й на уроці 9 У Windows PowerShell 5.1 звичайне > probe.txt записує файл у UTF-16. Чекер читає його як UTF-8, не знаходить жодного рядка [STREAM] і дає червоний пункт — хоча ти все зробив правильно.

Двох файлів для звіту ще немає

У report.csv чотири рядки, а зроблено поки два. Це v720p30.mp4 з уроку 9 і сьогоднішній final.mp4. Бракує зменшеної копії й варіанта в іншому контейнері — це два запуски.

640×360 при 15 fps
$ ffmpeg -hide_banner -y -i source.mp4 -s 640x360 -r 15 -c:v libx264 -preset veryfast -crf 24 -c:a aac -b:a 96k v360p15.mp4
той самий матеріал у WebM з кодеком VP9
$ ffmpeg -hide_banner -y -i v360p15.mp4 -c:v libvpx-vp9 -crf 40 -b:v 0 -c:a libopus -b:a 96k v.webm

VP9 кодує помітно повільніше за H.264, тому беремо вже зменшений файл, а не джерело. -b:v 0 тут обов'язковий. Без нього -crf у VP9 працює інакше: бітрейт лишається обмеженим зверху.

report.csv — чотири рядки даних

Перший рядок — заголовок, далі по рядку на файл. Числа беруться з ffprobe, а не з голови. Чекер перерахує їх сам і звірить.

report.csv — приклад заповнення, числа будуть свої
file,width,height,fps,codec,bytes v720p30,1280,720,30,h264,11885625 v360p15,640,360,15,h264,3375000 v.webm,640,360,15,vp9,2362500 final,1280,720,30,h264,3015000

Числа в прикладі ілюстративні, але не випадкові: вони сходяться з формулою. v720p30 — 45 с при 2113 кбіт/с (це той самий файл, що ти зробив на уроці 9), final — 10,05 с при 2400 кбіт/с. У тебе будуть свої, і вони теж мають сходитися.

Вагу у байтах бере команда нижче. Списувати з провідника Windows не варто: він показує МіБ і округлює.

розмір файлу в байтах
$ ffprobe -v error -show_entries format=size,duration,bit_rate -of default=noprint_wrappers=1 final.mp4

Чекер дивиться, чи не суперечать числа одне одному. Для кожного рядка має сходитися вага ≈ бітрейт × тривалість ÷ 8 (±20%). v360p15 має важити менше за v720p30. А рядок final — збігатися з width, height і duration у probe.txt. Це і є доказ, що ролик справді зібрано.

Монтажний лист

Монтажний лист — це опис свого монтажу словами: звідки взято кожен шматок і що з ним зробили. За таким описом ролик збирають заново навіть тоді, коли чернетки вже стерли.

Пиши його на своїй сторінці index.html, у блоці з іменем edit-log. Потрібно від 200 символів власного тексту і щонайменше дві різні позначки часу джерела. Позначки й доводять, що фрагменти взяті з різних місць.

Що має бути в монтажному листі Про кожен фрагмент напиши, звідки він узятий: позначка часу в джерелі і чому саме цей момент. Потім — у якому порядку фрагменти йдуть і чому саме так. Про титр: що в ньому написано, де він стоїть і скільки тримається. Наприкінці — чи є fade і яка вийшла тривалість. Три-чотири речення своїми словами — не список команд, команди вже є в cmd.txt.
Питання

final.mp4 (3 МБ) і poster.jpg (180 КБ) готові. Ліміт на зображення — 500 КБ, тобто постер під нього формально проходить. Що з цих двох поїде по FTP?

Крок 10

Практика: від джерела до ролика

Кроки 1—11 — у твоєму терміналі, кроки 12—14 — на сервері. Галочки зберігаються, сторінку можна закрити.

Що нікуди не завантажується source.mp4, part1–3.mp4, merged.mp4, final.mp4, v720p30.mp4, v360p15.mp4, v.webm і poster.jpg лишаються в локальній теці media/lesson-05/. FTP-приймальня відхиляє відео автоматично, на рівні сервера. Ролик учитель дивиться очно, на твоєму екрані.
Якщо не встигаєш Порядок пріоритетів такий: склейка → титр → cmd.txt і report.csv → монтажний лист → і тільки потім fade. Згасання — рівень «+», без нього урок зараховується.
Крок 11

Автоперевірка

Чекер бачить лише чотири легкі файли — і звіряє їх один з одним. Спроби не обмежені.

Демонстраційний режим: результат згенеровано для показу. На сервері ця кнопка викликає POST /api/check, який запускає check 05 від імені учня.

Що вчитель дивиться на екрані

Крок 12

Шкала виконання

Це те, що бачить учитель, коли виставляє оцінку.

СкладникВагаРезультат
Виконано
0%
Рекомендований бал за 12-бальною

Три речі, які треба винести з уроку

  1. Опція діє на той файл, що йде після неї. -ss до -i — швидкий стрибок по джерелу; -ss після -i — те саме, але через декодування всього початку.
  2. concat нічого не вирівнює. Він тільки складає шматки встик. Однаковими їх маєш зробити ти — вирізавши з одного джерела одним шаблоном команди.
  3. Монтаж — це текст. Ролик учитель побачить один раз, а cmd.txt лишається: за ним роботу можна повторити з нуля.

Домашнє завдання

Дописати в монтажний лист один абзац. Тема — під яку платформу ти експортував би цей ролик. Назви роздільну здатність, fps і співвідношення сторін. Поясни, чому саме такі. Числа бери з таблиці якостей із ДЗ уроку 9 і з калькулятора ваги на тій самій сторінці.

Джерела

Звідки взяті команди й тексти помилок

Усі ключі, синтаксис фільтрів і формулювання помилок — з офіційної документації та коду ffmpeg. Перевіряти дозволено й корисно.

Повний список із поясненнями, що саме звідки взято, — у файлі urok-10-джерела.md поруч із цією сторінкою.