You are on page 1of 81

МІНІСТЕРСТВО ОСВІТИ І НАУКИ УКРАЇНИ

КИЇВСЬКИЙ НАЦІОНАЛЬНИЙ УНІВЕРСИТЕТ


ІМЕНІ ТАРАСА ШЕВЧЕНКА
Факультет інформаційних технологій
Кафедра інтелектуальних технологій

ВИПУСКНА КВАЛІФІКАЦІЙНА РОБОТА


БАКАЛАВРА
НА ТЕМУ
Назва теми випускної кваліфікаційної роботи бакалавра

Галузь знань 12 «Інформаційні технології»


Спеціальність 122 «Комп’ютерні науки»
Освітня програма «Комп’ютерні науки»
Освітній рівень: бакалавр

Виконав: студент 4 курсу, групи КН- 42

Смирнов Олександр Олександрович


(прізвище та ініціали)

Керівник ___________________________
(прізвище та ініціали)
___________________________
(науковий ступінь, звання)

Випускна кваліфікаційна робота бакалавра допущена до захисту


рішенням кафедри інтелектуальних технологій
Протокол № від р.
зав. кафедри_________________ доц. Іларіонов О.Є.

Київ - 2021
1

Анотація

Смирнов Олександр Олександрович виконав випускну кваліфікаційну


роботу на тему «Програмний модуль обробки відео-файлів із застосуванням
візуальних ефектів» за спеціальністю 122 - «Комп’ютерні науки».
У випускній кваліфікаційній роботі проведено аналіз сучасних
систем з відео кодування та відео редагування, розроблено програмне
забезпечення , яке відповідає заданим показникам, що виконує відео обробку
відеоматеріалу в заданих умовах використання.
Ключові слова: візуальне, програмне, інтерактивне.
2

Summary

The degree project: «Software module for processing video files and
freezing of production files» has completed by Smyrnov Oleksandr specialty 122 -
«Computer Sciences».
In the final qualifying work, the analysis of modern systems on video
coding and video editing is carried out, the software which corresponds to the set
indicators which carries out video processing of video material in the set conditions
of use is developed.

Keywords: visual, software, web.


3

ЗМІСТ
ВСТУП..........................................................................................................................3
1. АНАЛІТИЧНИЙ ОГЛЯД.......................................................................................5
1.1. Історія відеоредагування..................................................................................5
1.2. Робота з відеоматеріалами................................................................................6
1.3 Захоплення цифрового зображення..................................................................6
1.4. Частота кадрів....................................................................................................7
1.5. Програми відтворення відео.............................................................................8
1.6. Програми обробки відео...................................................................................9
1.7. Відео кодинг......................................................................................................9
1.8. Інтеркодування................................................................................................12
1.9. Принцип кодування.........................................................................................17
1.10. Постановка задачі..........................................................................................18
2. ПОСТАНОВКА ЗАДАЧІ......................................................................................20
2.1. Завдання системи............................................................................................20
2.2. Сценарії застосування.....................................................................................22
2.2.1. Відео програвач.........................................................................................22
2.2.2 Перегляд властивостей відеоматеріалу....................................................23
2.2.3. Відео редактор...........................................................................................24
2.2.4. Відео форматування..................................................................................24
2.2.5. Веб застосунок...........................................................................................25
2.3. Методи роботи лінійності застосунку...........................................................25
2.3.1. Метод лінійного монтажу відео...............................................................25
2.3.2. Метод нелінійного монтажу відео...........................................................27
2.4 Структура роботи функцій з файлами...........................................................28
3. РЕАЛІЗАЦІЯ ТА ТЕСТУВАННЯ........................................................................33
3.1 Структура програмного застосунку...............................................................33
3.2 Графічний інтерфейс........................................................................................39
ВИСНОВОК...............................................................................................................50
ВИКОРИСТАНІ ДЖЕРЕЛА.....................................................................................51
ДОДАТКИ..................................................................................................................53
4

ВСТУП
Обробка відео – це, напевно, один із найбільш вимогливих завдань з тих,
які узагалі можна виконувати на персональному комп'ютері. Процес об’єднання
відеокліпів, зображень та звуків для створення відеоматеріалу y наш час це
робиться на комп’ютері з фантастичними програмами для редагування відео,
які називаються нелінійними редакторами або NLE. Це означає, що з цим
встановленим середовищем можена переглядати, вирізати та упорядковувати
цифрове відео у будь-якому порядку без необхідності дивитися весь
відеоматеріал.
Монтування відео є актуальним та використовується в багатьох сферах
життя. Насправді багато для відеомонтажу перенесено з давніх часів розрізання
фільмів. Наприклад, файлові системи організації в цифровому редакторі
називаються контейнерами, оскільки каністри для фільмів колись зберігалися в
контейнерах під час процесу редагування. Відеоредактор зазвичай передбачає
створення проєкту для роботи з відео. Проєкт, у даному випадку, це сукупність
всіх налаштувань і змін, які записуються в окремому файлі проєкту. У проєкті
зберігаються дані про всі зміни кліпів, розміщених на відео- і звукових
доріжках, застосованих ефектах і фільтрах, а також список усіх медіафайлів, які
були використані при монтажі. Файл проєкту можна відкрити для подальшого
монтажу, при цьому всі раніше використовувані медіафайли повинні бути
доступні за допомогою посилань, які були збережені в проєкті.
Мета і завдання роботи є створення прототипу програмного забеспечення
для його подальшого використання online без необхідності установлення
програмного забеспечення. Щоб додаток дозволяв абсолютно любому
користувачу відредагувати відеоматеріал без додаткових знань та інших
ускладнювальних процессів. Результатом розробки дипломнох роботи маємо
отримати прототип веб застосунку з відеоредагування та застосування базисних
відео ефеків.
5

1. АНАЛІТИЧНИЙ ОГЛЯД

1.1. Історія відеоредагування


Монтаж відео - це трудомісткий процес і дуже недооцінений аспект
процесу виробництва відео. Більшість режисерів погодяться, що за кожну
годину відео, яке вони знімають, вони отримують від однієї до п’яти хвилин
корисних кадрів. І це з усіма досягненнями сучасної епохи. Можна уявити яким
довгим і нудним був процес редагування відео, коли він вперше
використовувався. Протягом перших вісімдесяти років редагування
здійснювалось лінійним методом. Лінійний метод редагування передбачає
впорядкування зображень і звуків по порядку.
На початку це передбачало використання ножиць для зрощування
відеоматеріалів, а потім використання стрічки для кріплення у правильному
порядку. Такі методи використовувались до 1920-х років, коли була винайдена
перша машина для редагування, що отримала назву Moviola. Moviola був
важливим для еволюції відеомонтажу, оскільки це була перша машина, де
редактори змогли побачити фільм, визначаючи, де буде найкраща точка зрізу.
Це допомогло отримати чіткіші, краще змонтовані фільми.
У 1956 році корпорація AMPEX дебютувала перший відеомагнітофон.
VTR був першим пристроєм, який використовував магнітну стрічку для запису
відео. Відео було записано за допомогою технології поперечного сканування.
Використання даного методу означало, що відео буде записано по всій ширині
стрічки, а не лише по центру, як це було до цього моменту. Це дозволило
зберігати на стрічці набагато більше даних, тим самим знижуючи швидкість
стрічки, необхідну для запису.
Першою системою нелінійного редагування відео була CMX 600. Вона
представила світ нелінійному монтажу і вимагала стільки місця на диску, що
використовувані ним дисководи могли бути розміром з домашню пральну
машину. Нелінійне редагування - надзвичайно важливе просування послуги з
виробництва відео, оскільки воно зовсім не вимагає модифікації оригінального
6

вмісту. Натомість шматки, які ви хочете відредагувати, дозволяється виймати


та розміщувати на альтернативній шкалі часу, зберігаючи оригінал. Починаючи
з кінця 1980-х / початку 1990-х років, стало доступним програмне забезпечення
для цифрового монтажу, і такі компанії, як Avid і презентували світ відео
редагування яким ми знаємо його сьогодні.

1.2. Робота з відеоматеріалами


Обробка відео - процес редагування відеофайлів на комп’ютері за
допомогою спеціальної програми - відеоредакторів. Весь процес обробки
комп'ютерного відео складається з трьох послідовних і взаємопов'язаних етапів:
1. Захоплення відео
2. Редагування
3. Експорт
Монтаж - загальна назва технологій у кіно, телебаченні та відеоіграх, які
зазвичай використовуються для створення безперервних сцен. Наприклад, при
випуску кінцевого відеоматеріалу вам може знадобитися виправити окремі
частини відео, вимкнути звук, додати додаткові звукові доріжки, або
прикрасити відео спеціальними ефектами. Спеціальні ефекти
використовуються для покращення або редагування попередньо записаного
відео (наприклад, розміщення карти погоди як основи для телеведучого для
повідомлення прогнозів погоди), також спецефекти часто використовуються,
коли традиційна сценічна зйомка дорожча порівняно зі спецефектами
(наприклад, зйомка великого вибуху)..
Робота з стрічками поділяється на чотири основні етапи: перехід від
джерела до комп'ютера, редагування у відеоредакторі, огляд готового
зображення та експортування готового відеоматеріалу.

1.3 Захоплення цифрового зображення


Коли камера вловлює світло з фізичного світу і перетворює фізичні дані в
цифрові дані, вона повинна виконати два основні етапи цифрово-аналогового
7

перетворення сигналу: вибірку та квантування. Світло у фізичному світі може


приймати нескінченну або незліченну кількість значень. Вибірка зменшує
безперервний сигнал до незліченної кількості дискретних дискретизацій або
пікселів. Квантування відображає кожен із цих зразків у кінцевий набір значень
пікселів. Дійсну функцію xdt [n] можна квантувати як цілочисельну функцію xˆ
[n] з кінцевими можливими значеннями за допомогою
x dt [n ]
^x [ n ] =α∗round ( )
β
де β визначає рівні квантування, а α - коефіцієнт масштабування.

Оскільки частина сигналу відкидається в процесі вибірки та квантування,


сприйнята точність отриманого цифрового зображення залежить від обох
етапів. Збільшення точності можна досягти за допомогою вищих частот
дискретизації (більше вибірки) або більшого набору дозволених значень
пікселів. Відео створюється швидким відображенням послідовних зображень
або картинок. Якщо зображення відображаються з достатньою швидкістю, вони
створюють ілюзію руху. Час між відображенням наступних знімків повинен
бути достатньо малим, щоб уникнути видимого спалаху або мерехтіння.
Телепрограма, що відповідає стандарту Національного комітету телебачення
(NTSC), оновлюється зі швидкістю 30 знімків у секунду.

1.4. Частота кадрів


Аспект стиснення відео, який легко упустити - частота кадрів відео, що
кодується. Це швидкість, з якою записуються унікальні зображення, і часто
вимірюється як кадри в секунду. Значення полягає у його взаємозв'язку з HVS.
Зміни частоти кадрів можуть вплинути на плавність, швидкість і швидкість
передачі відео. Зі збільшенням частоти кадрів кількість необроблених даних
збільшується, а різниця між кадрами зменшується. Це може бути корисним для
швидких темпів руху, таких як спорт. Для повільної сцени розмови двох людей
8

користувач, швидше за все, не міг визначити між собою 30 і 60 кадрів в


секунду.

1.5. Програми відтворення відео


Програмне забезпечення програвача, яке знаходиться на ПК глядача,
відповідає за прийняття вхідного потоку та перетворення його у видиме
зображення. Окрім простого відтворення мультимедіа, найінтенсивнішою
роботою програмного забезпечення програвача є декомпресія вхідного сигналу
та створення зображення для відображення. Все, що робить програвач,
буферизує пакети даних, переконуючись у правильному порядку, а потім
розпаковує пакети даних, розкодуючи цифрове навантаження. Необхідна
кількість обробки залежить від розміру зображення та способу стиснення.
Програвач переконується, що дані продовжують надходити з джерела до
візуального представлення, якщо цілісність перервана, програвач вживає
коригувальних дій, таких як пауза, повторення кадрів або ребуфер. У системі
Windows вже вмонтований потужний програвач, але вимогливі користувачі
хочуть використовувати і інші, що мають більше настройок, кращі у швидкодії,
відкривають більше форматів. З безкоштовних особливої уваги заслуговують.
VLC media player - мультимедійний плеєр із відкритим вихідним кодом.
Цей інструмент може відтворювати CD, VCD та DVD. Є функція переглядати
360-градусні відеозаписи (тип відеозапису, де кожен напрямок записується за
допомогою камер) з роздільною здатністю 8K. Це один з найкращих
медіаплеєрів, який підтримує широкий спектр методів стиснення відео.
GOM Media Player - являється відкритою для редагування программою.
Це програмне забезпечення підтримує численні формати файлів, включаючи
MKV, MPG, FLV, AVI. Є функція переглядати відео 360.
MediaMonkey - програмне забезпечення, яке допомагає користувачам
упорядковувати свої відео. Підтримує розширення функціональністі за
допомогою плагінів.
9

MPV - інструмент медіаплеєра. Це безкоштовна програма з відкритим


кодом. Цей інструмент підтримує відеоформати MPV та MPEG-2. Це необхідна
функція для сучасного користувача.

1.6. Програми обробки відео


З професійних відеоредакторов що особливо цікавлять любителя, першим
стоїть - Adobe Premier. За історичних причин він став майже настільки ж
загальним ім'ям для відеоредактора, як Word для текстового редактора. Серед
редакторів, за задумом творців виділені на любителів. Її впевнено очолює
VideoProc
VideoProc - Це платне програмне забезпечення, що виходить за
можливості автономного редактору, програма дозволяє конвертувати,
записувати та завантажувати відео з мінімальними затратами зі сторони
персонального комп'ютера, в одночас будучи дуже інтуїтивним у використанні
навіть для початківця. VideoProc має безліч функцій редагування. За його
допомогою можна вирізати, обрізати, об’єднювати кілька файлів (у різних
форматах та на різних пристроях), обертати та додавати субтитри з ефектами. Є
підтримка повного апаратного прискорення графічного процесора, яке
забезпечує швидке та безперешкодне редагування.
Також існують комплексні відео редактори, їх потенціал на дуже
високому рівні, вони за статусом є професіональні, як приклад можно привести
Autodesk Smoke.
Autodesk Smoke - це програмне забезпечення для редагування відео, яке
виділяється завдяки компонуванню на основі вузлів (node-based).
Відеоредактор досягає вищого рівня складності порівняно з іншим популярним
програмним забезпеченням. Найсильніша його сторона полягає в
редакторських та обробних функціях. Autodesk Smoke є лідером в реалізації
3D-ефектів та можливісті бездоганно використовувати 3D-анімацію та
моделювання в двовимірному просторі, з найвищим ступінем стабільності.
10

1.7. Відео кодинг


Стиснення відео забезпечує зменшення розмірів відеофайлів з мінімальними
втратами в якості зображення, що служить для багатьох цілей, таких як
зберігання чи трансляція. Відповідно, відеокодек - це комбінація алгоритмів,
яка дозволяє стиснути та розпакувати файл відеоданих за допомогою кодера та
декодера відповідно. Профілі та рівні можна визначити для кодеків. Профілі
обмежують використовувані методи, тоді як рівні обмежують значення значень
параметрів кодування. З моменту введення першого кодека, приблизно 30 років
тому, відбувалося постійне вдосконалення, що означало значне збільшення
швидкості стиснення та якості розпакованого відео. Однак існує компроміс,
який слід дотримуватись, який включає не лише ступінь стиснення та кінцеву
якість відео, але й пов'язану з цим обчислювальну складність, як показано на
малюнку 1.1.

Рисунок 1.1 Компроміс щодо розвитку кодеків.


11

Високоефективне відеокодування (HEVC) - це останній стандарт


відеокодування, спільний проект Групи експертів з кодування відео ITU-T
(VCEG) та організацій стандартизації ISO / IEC Moving Picture Experts Group
(MPEG), які були співпрацюючи у партнерстві, відомому як Спільна спільна
команда з кодування відео (JCT-VC). Його попередником було H.264 / MPEG-4
Advanced Video Coding (AVC), за допомогою якого HEVC поділяє багато
методів та функціональних можливостей. Тому приклади з цими двома
кодеками повинні бути найбільш підходящим способом продемонструвати
поточний стан зображених блоків та останній розвиток, який вони пройшли. На
тому ж рівні якості відео, HEVC може подвоїти ступінь стиснення даних свого
попередника, значне покращення, яке є результатом суми різних невеликих
удосконалень на декількох блоках.
Методи стиснення можна класифікувати як з втратою чи без втрат. Що розділяє
ці два - це кількість даних, яку можна втратити (можливо, це призведе до
погіршення якості декодованого відео). У процесі без втрат усі оригінальні дані
можна відновити, коли відео стиснене. На відміну від цього, хоча певна
інформація назавжди усувається в процесі збитків, така втрата, як правило, є
надлишковими даними, які мають незначний або зовсім не впливають на якість
відео для людського ока. Як правило, кодек складається з процесів із втратами
та без втрат, тому існує баланс між швидкістю стиснення та досяжною якістю
відео. На рисунку 1.2 показана блок-схема типового кодера. У наступних
підрозділах буде представлено короткий опис основних модулів кодера, щоб
полегшити презентацію запропонованого варіанту реалізації.
12

Рисунок 1.2 Типова блок-схема кодера.


1.8. Інтеркодування
Враховуючи дві послідовні картинки у відеопослідовності,
передбачається, що картинки співвідносяться від одного зображення до
наступного. Замість кодування нової картини, інтеркодування використовує цю
тимчасову надмірність, формуючи прогноз зображення із зображенням, яке вже
було закодовано в макроблоках де кожен зріз складається з макроблоків.
Макроблоки мають розмір 16 × 16 пікселів.
13

Рисунок 1.3 Схема де кожен зріз складається з фрагментів макроблоків


По-перше, поточне зображення, що кодується, розділено на макроблоки.
Потім еталонне зображення використовується для створення прогнозу
поточного зображення. Кодер шукає найкращі макроблоки в раніше
переданому зображенні, щоб створити оцінку поточного зображення. Кодер
може використовувати помилку передбачення як метрику для визначення
найкращих макроблоків. Загальні показники похибки прогнозу включають
мінімальну середньоквадратичну похибку (minimum mean square error MSE) та
мінімальну абсолютну різницю суми (minimum sum absolute difference SAD).
Враховуючи два дискретні двовимірні сигнали xij та yij розміром M × N, SAD
(x, y) визначається як
n n
1
SAD ( x , y )= ∗∑ ∑ ¿|x ij − y ij|
MN i=0 i=0
MSE між двома сигналами x та y визначається як

M N
1
MSE ( x , y )= ∑ ∑ ¿¿¿
MN i=1 j=1
14

Кодер пов'язує вектор руху з кожним макроблоком для опису


просторового розташування кожного макроблока в опорному зображенні щодо
поточного зображення. Процес створення найкращого прогнозу для поточної
картини відома як оцінка руху. Невеликі зміни від одного зображення до
іншого, як це видно на малюнку 1.7. Використання лише попередньо
відображеного зображення відоме як пряме передбачення. Використання як
попередньої, так і майбутньої картини відоме як двонаправлене передбачення.
Обидва типи прогностичних зображень проілюстровані на рисунку 1.8. Після
того, як зображення прогнозу з компенсацією руху створюється для поточного
зображення, залишок між передбаченням лише руху та фактичним
зображенням кодується за допомогою внутрішнього кодування. Для кожного
інтеркодованого зображення потрібно передавати вектори руху та інкодований
залишковий сигнал.
15

Рисунок 1.4 Два послідовні знімки з послідовності «мобільний».


Зображення внизу показує різницю між двома зображеннями. Дуже мало змін
спостерігається між двома послідовними знімками.
16

Рисунок 1.5 Різні типи передбачувальних зображень. Стрілки вказують


від опорного зображення до зображення передбачення.
Можливо виконати стиснення даних без втрат через надмірність даних.
Оскільки апріорі відомо, що деякі елементи у закодованому відео, або елементи
синтаксису, трапляються частіше, ніж інші, ефективніше використовувати
коротший символ для елементів з високою ймовірністю, а довший символ для
елементів з нижчим ймовірність. Шеннон показав нижню межу середньої
довжини кодового слова для багатьох кодованих елементів. Добре відомий
метод побудови коду, що наближається до цієї нижньої межі, описав Хаффман.
Оскільки кожен символ у таких кодах має різну довжину, вони належать до
класу кодів, відомих як коди змінної довжини (VLC). Інший тип VLC - це
експоненціальний код Голомба, який широко використовується в H.264. Для
ілюстрації, частина таблиці векторних кодів руху у стандарті MPEG-2 показана
в таблиці 1.4. Передбачається, що менші переміщення руху частіше
переважають більші переміщення руху. Отже, меншим переміщенням руху
присвоюються коротші кодові слова. Нульовий рух застосовуватиметься до
будь-якого статичного об'єкта у відеопослідовності, наприклад, до нерухомого
фону. Інший клас ефективних кодів - це арифметичні коди. Арифметичні коди
можуть ближче підійти до нижньої межі Шеннона, присвоївши кожному
кодовому слову нецілу кількість символів, що неможливо для VLC.
17

Рисунок 1.6 Структурна схема, що окреслює кроки від кодування відео до


декодування відео

1.9. Принцип кодування


Принцип кодування - загальна архітектура, яка була адаптована всіма
алгоритмами стиснення з втратами, і вона описує процес кодування та
декодування вхідного сигналу. Цей вхідний сигнал f може бути аудіо,
зображенням або відео, що є першим перетворений у більш стислий формат.
Дискретне вейвлет-перетворення (DWT), дискретне косинусне перетворення
(DCT), дискретне перетворення синусоїди (DST) та Фур'є - це деякі з
перетворень, які використовувались в алгоритмах стиснення. Результат цього
перетворення ідентифікується квантором, щоб вирішити, яка інформація є
надлишковою для видалення. Квантування є єдиною відповідальністю за
введення спотворень. Як результат, при стисненні без втрат не відбувається
квантування. Ентропійне кодування - це функція без втрат, яка перетворює
квантовану інтенсивність сигналу в кодові слова, довжина яких змінюється
обернено до частоти появи. Після того, як вхідний сигнал був закодований, він
зберігається або надсилається через канал зв'язку приймачу, якому потрібно
використовувати цей код для реконструкції вхідного сигналу. Це процес
декодування, який складається з декодування ентропії, деквантування та
зворотного перетворення.
18

Рисунок 1.7 Принцип кодування


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

1.10. Постановка задачі


Необхідно щоб на вхід подавались підтримувані відеоформати, а на вихід
формат .mp4.
Технічні вимоги до продукта наступні:
1. програмний продукт повинен функціонувати на персональних комп’ютерах без
додаткових програмних застосунків
2. забезпечувати високу швидкість відтворення даних
3. забезпечувати зручність і простоту взаємодії з користувачем або з розробником
програмного забезпечення у випадку використовування його як модуля
4. передбачати мінімальні витрати на впровадження програмного продукту
19

Рис. 1.8 Контекстна діаграма процесу відеоредактору у нотації IDEF0


В загальному якщо систему визначити як чорну скриньку то до вхідних
даних можемо віднести вхідні відео матеріали, а на виході обробленний
відеоматеріал.
20

2. ПОСТАНОВКА ЗАДАЧІ

2.1. Завдання системи


Суть задачі: створення алгоритмів декодування і рендерінгу медіа файлів,
з подальшим використанням цього функціоналу в кінцевому програмному
продукті; (новий формат внутрішнього представлення медіа при обробці в
програмному продукті, оптимізація роботи з внутрішнім представленням медіа)
Особливості задачі: для даної задачі потрібно сформувати
представлення відео у форматі який можна буде редагувати на абстрактному
рівні, реалізувати демоверсію та протестувати її.

Рисунок 2.1 BPMN діаграма роботи системи


21

Якщо візуалізувати дані діаграми, то можна їх використовувати для


детального пояснення всіх етапів певного процесу з метою контролю або
покращення ефективності його функціонування. Завдяки нотаціям EPC у
подальшій розробці ІС буде затрачено набагато менше часу на її розробку та
кращого розуміння для розробників.
Опис профілів зацікавлених сторін
Внутрішні зацікавлені сторони:
-Програміст;
-Оператори;
-Лектори (Онлайн занять);
-Будь які користувачі для досягнення своїх цілей при використанні данної
технології;
2. Зовнішні зацікавлені сторони:
-Виробники відеокарт
-Конкурентні застосунки;
2.2 Подання об'єкта у вигляді системи
1. Визначити надсистему, в рамках якої функціонує система, виділити
підсистеми першого і другого рівнів з їх елементами вказавши з якої точки зору
виконується аналіз.
2. Визначити зовнішні зв'язки системи з надсистемою.
3. Скласти повний перелік всіх підсистем.
4. Скласти перелік елементів для кожної підсистеми.
5. Подати у вигляді системи процес функціонування обраної системи.
6. Визначити підпроцеси як елементи системи.
7. Визначити надсистему для процесу і зовнішні зв'язки з нею.
Система існуватиме у вигляді desktop додатку який буде звертатися до
підсистем для виконання поставлених задач.
Підсистемами є потік, який виконує функцію провідника до системи.
Raff буде працювати з локальними файлами, репрезентуючи кожне відео
у локальному вигляді відеоматеріалу.
22

Сутність відео файлів:


1. Загальна інформація про відео
2. Довжина відео
Сутність відеоматеріалу:
3. Дані про кожен кадр
4. Потік звуку

2.2. Сценарії застосування

2.2.1. Відео програвач


Дане програмне забезпечення дозволяє "відтворювати" аудіо, відео чи
анімаційнії файли на комп'ютерному пристрої. Він надає всі необхідні функції
для комфортного відтворення відео та повним його ознайомленням. Одна із
переваг є завантаження та відображення декількох відеоматеріалів для
перегляду декількох відеоматеріалів в послідовності завантаження. Користувачі
можуть відтворювати аудіо з відео без необхідності перегляду всього
відеоматеріалу завдяки лінійному повзунку, за допомогою якого, можно
керувати моментом відтворення відео а також лінійному принципу дії доріжки
відеоматеріалу що дає можливість даного використання.
В даному застосунку є функції що дозворяють керувати відтворюване
відео за допомогю реалізованих функцій. Функція прискореного перегляду,
надає можливість продивитися відеоматеріал в уповільненому або
прискореному режимі відтворення. Ця функція є унікальною серед інших
відеоредакторів що не мають даної властивості. В цьому відеоредакторі мається
можливість зупинити поточний момент відтворення відео з його подальшим
його відображенням у вікні відтворення відео, після чого також буде
можливість продовжити зображення відеоматеріалу. За окремою зміни гучності
на самому обладнанні, що відтворює аудіоконтент в застосунку передбачена
функція редагування рівня гучності за допомогою інтерактивного повзунку.
23

2.2.2 Перегляд властивостей відеоматеріалу


За допомогою даного програмного застосунку можна отримати
передбачення щодо надання детальної (усієї необхідної) інформації про файл
мультимедійного характеру, саме цей процес дозволятиме розробити візуальне
відображення з точними показниками у графічному інтерфейсі користувача
програмного застосунку.
Знаходження повзунку має інформацію щодо відтворення відео на
таймлайні, що виражається у годинах, секундах та мілесекундах. Ця функція
конвертує поточні фрейми у більш звичні часові метрики, вона відображує
точне знаходження моменту відтворення на доріжці рахуючи з початку відео,
також реалізований перегляд загальної довжини часу відео. Функція
інтерактивна, під час відтворення відео або кофзанні повзунку інформація щодо
моменту відтворення змінюється динамічно. Коли керують відеоматеріалом
прискорюючи або уповільнюючи час, дані по відео також змінюються в
залежності від вибранного значення зміни швидкості, тому тут передбачена
динамічна зміна загального часу відтворення на уповільнення, прискорення та
обрізання відео.
Часні властивості відеоматеріалу в проекті надають можливість
динамічного визначення кількості кадрів за секунду та часу відтворення на
одне відео. Час на відтворення одного відео є інтерактивним на якого може
впливати такі зміни як зміна часу, та обрізання, тому він змінює свої показники
разом з проведеними змінами. Метрика кількості кадрів в секунду - це простий
акт вимірювання, скільки відеокадрів фіксує камера спостереження за секунду
відео. 30 кадрів в секунду означає, що камера зафіксувала 30 кадрів за одну
секунду відео; чим вище кадри, тим плавнішим буде відео. Менша частота
кадрів може призвести до поривчастого або поламаного руху. Для плавного
запису руху буде мінімум потрібно 30 кадрів в секунду. Частота кадрів також
впливає на розмір ваших відеофайлів. Більш висока частота кадрів, у 60 кадрів
в секунду призводить до збільшення кількості кадрів, тому відеофайл буде
більшим. У системи яка має великий обсяг пам’яті та пропускну здатність, є
24

можливість відтворювати чіткіше відео зі швидким рухом. У 15 кадрів в


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

2.2.3. Відео редактор


Різні типи відео мають різні вимоги. При створенні згрупованих моментів
таких матеріалів як відео з сімейних канікул, де потрібно лише вирізати довгі
записані сегменти на ваші улюблені моменти та поєднати їх, створення влогу
YouTube, поєднуючи кадри голови, що розповідає, з пояснювальними
роликами, повнометражний документальний фільм із годинними кадрами для
сортування, комп’ютерною графікою, яку потрібно створити, та спеціальними
ефектами для додавання. Кожна програма для редагування відео має якусь
криву навчання, і є пряме співвідношення між кількістю функцій, які має
програмне забезпечення, і тим, що необхідно знати, щоб використовувати
програмний застосунок. Всі відеомонтажі будуть виконуватися на комп'ютері,
як слід чим складніші функції додаються до відео (наприклад, спеціальні
ефекти, створені комп’ютером), тим потужніше комп’ютерне обладнання
знадобиться.
Тут реалізовані функції обрізання, групування та прискорення відео,
застосунок дозволяє проводити необхідні моменти редагування для отримання
базисно скомпонованого відео матеріалу. Для обрізання у відео є монтажна
доріжка, що надає можливість вибору участку відтинання відео. Компонування
декількох відеоматеріалів в один проект дозволить згрупувати файли в
необхідній послідовності редагування та відтворення. Прискорення відео та
зміни гучності є базисним та необхідним відеоефектом у відеоредакторах. Ці
функції застосовуютсья персонально до кожного файлу з проекту
індивідуально.
25

2.2.4. Відео форматування


Контейнер і кодек - це два компоненти будь-якого відеофайлу.
Відеоформат - це контейнер, в якому зберігаються аудіо, відео, субтитри та
будь-які інші метадані. Кодек кодує та декодує мультимедійні дані, такі як
аудіо та відео. Створюючи відео, відеокодек кодує та стискає відео, тоді як
аудіокодек робить те саме зі звуком. Потім закодовані відео та аудіо
синхронізуються та зберігаються у мультимедійному контейнері - форматі
файлу.
Застосунок дозволяє форматувати webm, flv, avi та mp4 у файл
відеоредактору, для подальших змін, усі формати здатні на однаковий набір дій
з ними. Відеоредактор робить можливим декодувати відео файли у звичний та
найбільш адаптований фомат mp4.
Mp4 - це загальний «формат контейнера» для відеофайлів, який дозволяє
зберігати багато відео- та аудіоінформації у меншому розмірі. Він є
найросповсюдженішим форматом з відеофайлами. Як і будь-який формат
відеофайлу, MP4 має свої переваги та недоліки залежно від того, як і чому він
використовується.

2.2.5. Веб застосунок


Даний застосунок є інтерактивним відеопрогравачем HTML5, що
дозволяє відтворювати відео безпосередньо у веб-браузері без використання
додаткових плагінів. Відеоплеєри HTML5 пропонують простий спосіб
інтеграції відеоплеєрів на веб-сайт. Відеоплеєри HTML5 потрібні щоб
використовувати елемент відео.
Більшість сучасних браузерів зараз підтримують відео HTML5, тому
даний застосунок може бути адаптований та використаний для великої
кількості веб-сторінок.

2.3. Методи роботи лінійності застосунку


26

2.3.1. Метод лінійного монтажу відео


Лінійне відеомонтаж - це процес вибору, упорядкування та модифікації
зображень та звуку у заздалегідь визначеній, упорядкованій послідовності - від
початку до кінця. Лінійне редагування найчастіше використовується при роботі
з відеокасетою. На відміну від фільму, відеокасету не можна фізично розрізати
на шматки, щоб з’єднати, щоб створити новий порядок. Натомість редактор
повинен дублювати або записувати кожен потрібний відеокліп на головну
стрічку. Наприклад, скажімо, у редактора є три вихідні стрічки; A, B і C, і він
вирішив, що спочатку буде використовувати стрічку C, B другу і A третю.
Потім він починав з розрізання стрічки C до початку кліпу, який він хоче
використати, тоді, коли він відтворює стрічку C, це також одночасно
записувало б кліп на головну стрічку. Коли потрібний кліп із стрічки C
зроблено, запис припиняється. Потім весь процес повторюють із стрічками B і
A.
Є кілька недоліків, які можна зустріти при використанні методу лінійного
монтажу відео. По-перше, неможливо вставити або видалити сцени з головної
стрічки без повторного копіювання всіх наступних сцен. Оскільки кожен
фрагмент відеокліпу повинен бути викладений у режимі реального часу, ви не
зможете повернутися, щоб внести зміни, не перередагувавши все після зміни.
Через накладення, яке має відбутися, якщо ви хочете замінити поточний
кліп новим, два кліпи повинні мати абсолютно однакову довжину. Якщо новий
кліп занадто короткий, кінець старого кліпу все одно відображатиметься на
головній стрічці. Якщо він занадто довгий, тоді він перейде до наступної сцени.
Рішення полягає в тому, щоб або зробити новий кліп відповідним поточному,
або відновити проект від редагування до кінця, що не дуже приємно. Тим часом
все це накладення також призводить до погіршення якості зображення.
Однак лінійне редагування все ж має деякі переваги:
Це просто. Дуже мало ускладнень із форматами, апаратними конфліктами
тощо.
27

Для деяких робіт краще лінійне редагування. Наприклад, якщо все, що ви


хочете зробити, це додати два розділи відео разом, набагато швидше і простіше
відредагувати стрічку до стрічки, ніж захоплювати та редагувати на жорсткому
диску.

2.3.2. Метод нелінійного монтажу відео


Метод нелінійного редагування відео - це спосіб редагування довільного
доступу, що означає миттєвий доступ до будь-якого кліпу, коли ви цього
захочете. Отже, замість того, щоб переходити у встановленому порядку, ви
можете працювати над будь-яким сегментом проекту в будь-який час і в будь-
якому порядку, який вам заманеться. При нелінійному редагуванні відео
оригінальні вихідні файли не втрачаються та не змінюються під час
редагування. Це робиться за допомогою списку рішень про редагування (EDL),
який фіксує рішення редактора, а також може бути замінений іншими
інструментами редагування. Таким чином, багато варіантів вихідних вихідних
файлів можуть вийти без необхідності зберігати багато різних копій, що
дозволяє дуже гнучке редагування. Також легко змінити скорочення та
скасувати попередні рішення, просто редагуючи EDL, без необхідності
дублювати фактичні дані фільму. Втрати якості відео також уникається через
відсутність необхідності повторного перекодування даних, коли
застосовуються різні ефекти.
Нелінійне редагування відрізняється від лінійного редагування кількома
способами.
Спочатку відеозапис із джерел записується на жорсткий диск комп'ютера,
що редагує, або в масив RAID до початку сеансу редагування.
Далі, замість того, щоб покласти відео на рекордер у послідовних знімках,
сегменти збираються за допомогою програми для редагування відео. Сегменти
можна переміщати за власним бажанням за допомогою перетягування.
28

Між сегментами можна розміщувати переходи. Крім того, більшість


програм для редагування відео мають якусь функцію CG або генератор
символів, вбудовану для нижчих третин чи назв.
Незавершене виробництво можна переглянути в будь-який час під час
редагування в режимі реального часу. Після завершення редагування воно
остаточно передається на відео.
Нелінійне редагування відео знімає необхідність розміщувати відео в
режимі реального часу. Це також дозволяє людині, яка редагує, вносити зміни в
будь-який момент, не впливаючи на решту редагування.
Нелінійна система відеомонтажу має багато переваг. По-перше, це
дозволяє отримати доступ до будь-якого кадру, сцени або навіть групи сцен у
будь-який час. Крім того, оскільки оригінальні відеоматеріали залишаються
незмінними під час редагування, ви можете повернутися до оригінального
знімка, коли завгодно. По-друге, нелінійні системи відеомонтажу пропонують
гнучкість монтажу. Ви можете передумати свою думку сто разів, а також зміни
можна зробити сто разів, не починаючи все спочатку з кожною зміною. Також
можна дуже швидко редагувати якісні відеофільми як із стандартною
роздільною здатністю, так і з високою роздільною здатністю на звичайних ПК,
які не мають можливості повноцінно обробляти величезні повноякісні дані
високої роздільної здатності.

2.4 Структура роботи функцій з файлами


Даний програмний продукт має виконувати різні функції з роботи з
файлами, в цьому пункті були продемонстровані загальні представлення таких
структур.
Функції імпортування:
1. Перевірка роботоспроможності самого додатку.
2. Перевірка наявності встановлених застосунків.
3. Перевірка версій встановлених застосунків.
4. Перевірка читаємого файлу.
29

5. Створення локального вигляду відеофайлу.


6. Відображення відео на інтерфейсі додатку.

Рисунок 2.2 Функція імпорту

Функції експорту:
1. Формування інструкцій щодо обробки файлу.
2. Створення копії вивантажуємого файлу.
3. Застосування інструкцій щодо обробки файлу.
4. Створення нового файлу з сформованого відеоматеріалу .
5. Отримання згрупованої інформації.
6. Збереження відповіді.
30

Рисунок 2.3 Функція експорту

Функції роботи з відеоматеріалом:


1. Створення інструкцій щодо обробки файлу.
2. Формування файлу інструкцій щодо обробки файлу.
3. Створення копії вивантажуємого файлу.
4. Застосування інструкцій щодо обробки файлу.
5. Створення тимчасового файлу з сформованого відеоматеріалу .
6. Отримання згрупованої інформації.
31

7. Відображення відеоматеріалу.

Рисунок 2.4 Функція роботи з відеоматеріалом

2.5. Практична цінність розробки


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

Проект можна вдосконалити та адаптувати під використання в веб


браузерах для вільного застосування. Що дозолить швидко монтувати
відеоматеріал без додаткових застосунків. В даному проекті можливо
впровадити роботу з фільтрами та розширити функціонал з відеоефектами.
Також розробити можливість вивантаження готового проекту на youtube канал.
Основне завдання даного застосунку – скомпілювати декілька відео
файлів, вирізати лишні частини відео, відрегулювати швидкість програвання і
гучність звуку. Це дозволить полегшити роботу з медіафайлами рядовим
користувачам.
33

3. РЕАЛІЗАЦІЯ ТА ТЕСТУВАННЯ

3.1 Структура програмного застосунку


В данному розділі представлена інформація щодо принципу роботи
програми по її функціям з описом використаних бібліотек у проекті. Загалом
проект складається з функціональних модулів по обробці, імпорту, експорту
підкачки необхідних версій бібліотек та інтерфейсу. Загальний вигляд коду
програми в корневій папці проекту складається з розділених по задачам папок з
функціями та елементами інтерфейсу. В папці “renderer” знаходиться увесь
зміст програми, самої роботи застосунку на рівні роботи з користувачем. У
папці “node” знаходяться модулі що відповідають за перетворення коду у
вигляд окремого виконуваного файлу, даний пункт дозволяє створювати файл
типу .exe для даного застосунку. Папка “class” відповідна за реалізацію
проекту, тут містяться функції що відповідають за роботу самої програми. У
папці “Commands” містяться контрукори команд виконуємих функцій.

Рисунок 3.1 - узагальнений вигляд програми у корневій папці проекту


34

У кореневій папці знаходяться файли що верифікують наявність


використовуємих бібліотек у проекті
Файл main.js – виконує запрос на наявність встановленої Node.js, за
допомогою Node.js була реалізована можливість вигруження файлів до проетку,
визначити тип читаємого файлу.
Node.js - це середовище виконання з відкритим вихідним кодом, яке
дозволяє розробникам створювати всі види серверних інструментів та додатків
у JavaScript. Час виконання призначений для використання поза контекстом
браузера. Таким чином, середовище опускає специфічні для браузера API-
інтерфейси JavaScript і додає підтримку більш традиційних API-інтерфейсів
ОС, включаючи HTTP та бібліотеки файлової системи. В даному проекті був
вибраний Node завдяки тому що Node має чудову продуктивність. Він був
розроблений для оптимізації пропускної здатності та масштабованості веб-
додатків і є хорошим рішенням для багатьох загальних проблем веб-розробки
(наприклад, веб-додатків у режимі реального часу). Також Node.js портативний.
Він доступний в ОС Microsoft Windows, macOS, Linux, Solaris, FreeBSD,
OpenBSD, WebOS та NonStop. Крім того, він добре підтримується багатьма
провайдерами веб-хостингу, які часто надають певну інфраструктуру та
документацію для розміщення сайтів Node.
Файл packege.json – файл є відповідальним за виконання перевірки на
наявність встановлених на персональному комп’ютері бібліотек та застосунків,
що є необхідними для корректної роботи програмного додатку. Ця функція
використовує середовище виконання Node.js.
Файл packege-lock.json – автоматично згенерована функція що дозволяє
перевірити версію бібліотек та застосунків, для її генерації був використаний
менеджер пакетів вузлів (NPM), він забезпечує доступ до більшості
багаторазових пакетів. Він має найкращу роздільну здатність залежностей, а
також може бути використаний бля автоматизації більшості ланцюжків
інструментів побудови.
35

У папці “node” знаходяться модулі що відповідають за перетворення коду


у вигляд окремого виконуваного файлу який буде представлений у вигляді .exe
файлу котрий не потребує ніяких додатково встановлених додатків.
Файл main.js – програмний файл задає параметри в розширення electron,
для визначення інтерфейсу та внутрінніх налаштувань вікна, після чого записує
на абстрактний носій виконуваний файл формату .exe. Electron.js - це
середовище виконання, яке дозволяє користувачеві створювати додатки для
робочого столу з HTML5, CSS та JavaScript. Це проект з відкритим кодом,
започаткований Ченгом Чжао, інженером GitHub. Будь-яка написана веб-
програма може працювати на Electron.js. Подібним чином будь-яка програма
Node.JS може використовувати цю технологію. Electron JS використовує веб-
технології, такі як прості HTML, CSS та JavaScript. Для створення невеликих
проектів не потрібне глибоке знання. Він може бути розроблений для одного
браузера. Його файлова система належить до API Node.js і працює на всіх
платформах.
Файл ffmpeg.js – функція що відповідає за роботу з файлами на
комп’ютері. Визначає розмір файлу та створює сам файл як абстрактний носій
для його подальшого форматування у виконуваний файл.
В папці “renderer” знаходиться увесь зміст програми. Вона містить в собі
папку з реалізацію робочих функцій проекту, папку з файлами бібліотек та
інтерфейс з реалізацією інтерактиву з користувачем.
Файл index.html – код що відповідає за структурування та відображення
веб-сторінки разом з її контентом. Він написаний на HTML, що не є мовою
програмування, адже це мова розмітки, і використовується щоб повідомляти
браузеру, як відображати веб-сторінки, на яких даний код знаходиться. HTML
складається з ряду елементів, щоб вкладати або обертати різні частини
контенту, щоб змусити контент відображатися або діяти певним чином.
Файл script.js – функція що містить у собі код, який відповідає за надання
можливості взаємодії користувача з робочою програмою. Дана функція виконує
36

задачу щодо надання елементів управління в застосунку для користувача


програми.
Файл style.css – програмний файл що є каскадною таблицею стилів (CSS),
написанний на мові ієрархічних правил таблиць стилів, використовуваний для
подання зовнішнього вигляду документа, який використовується в HTML
даного проекту. CSS описує, яким чином елемент повинен відображатися на
екрані, на папері, голосом або з використанням інших медіа засобів.
Папка “class” відповідна за реалізацію проекту, тут містяться функції що
відповідають за роботу самої програми, в наявності є папка з виконуваними
командами проекту, функції імопорту та експорту, створення уявного
репрезентування відео у самому застосунку.
Файл ExportConfig.js – задає параметри необхідні для експорту відеоряду
з готового проекту
Файл FFMPEG.js – конвертує надісланний відеоматеріал, задаючи
інформацію по розміру файлу, довжині імпортованого відеоряду, наданні
данних по поточному кадру в момент часу відтворення. Взагалі представляє
вивантажуємий відеофайл у вигляді кадрів які знаходяться у масиві об’єктів з
потоковим звуком. Для конвертації нового відеофайлу у проекті
використовувався FFmpeg. Це необхідний елемент для правильного
відображення відео. FFmpeg - це провідний мультимедійний фреймворк,
здатний декодувати, кодувати, перекодувати, мультиплексувати,
демультиплексувати, транслювати, фільтрувати та відтворювати майже все. Він
підтримує стародавні формати аж до переднього краю. Незалежно від того, чи
були вони розроблені якимсь комітетом зі стандартів, громадою чи
корпорацією. Він також надзвичайно портативний: FFmpeg компілює, запускає
та передає нашу тестову інфраструктуру FATE у Linux, Mac OS X, Microsoft
Windows, BSD, Solaris тощо в широкому діапазоні середовищ збірки,
архітектур машин та конфігурацій. Проект FFmpeg надає найкраще технічно
можливе рішення для розробників додатків та кінцевих користувачів. Тут
37

поєднуються найкращі доступні варіанти безкоштовного програмного


забезпечення. Тому я і вибрав дане рішення для використання у відеоредакторі.
Файл FFMPEGCommand.js – є методом, що створює новий масив з
результатом виклику зазначеної функції для кожного елемента.
Файл Main.js – конструктор відповідний за контейнер відео, тут
створюється кожний вивантажений відеофайл новим елементом.
Файл Video.js – містить у собі всі необхідні функції для роботи з відео у
самому застосунку, такі як його програвання, переключення між різними
фрагментами, керуванням відофрагментами, їх створення та видалення. Надає
дані пов’язані з відео матеріалом та кожним окремим файлом, такі як час,
момент в часі на повзунку, кількість кадрів у секунду, з чого можливо отримати
надання детальної (усієї необхідної) інформації про файл мультимедійного
характеру для точного відображення на інтерфейсі користувача.
Файл VideoFragment.js – відповідає за кожне вигружене у проект відео у
програмний застосунок.
У папці “Commands” містяться контрукори команд виконуємих функцій у
проекті.
Файл “AddFragment.js” – являється конструкором який відповідає за
додавання нового фрагменту відеофайлу до відеоматеріалу у виконуваному
файлі проекту.
Файл “Command.js” – являється конструкором який відповідає за
відстеження дій з відеоматеріалом при використанні застосунку у
виконуваному файлі проекту.
Файл “DeleteFragment.js” – являється конструкором який відповідає за
видалення обраного відеофайлу з відеоматеріалу проекту з подальшим
відображенням цієї дії у виконуваному файлі проекту.
Файл “MoveFragment.js” – являється конструкором у виконуваному файлі
проекту, який відповідає за зміну послідовності відеофайлів у відеоматеріалі
проекту з відображенням на інтерфейсі застосунку з яким взаємодіє
користувач.
38

Файл “SetEndPoint.js” – являється конструкором який відповідає за


установлення кінечної точки на моменті програвання відео, що виконує дію
обрізання відеофайлу у проекті.
Файл “SetPlaybackSpeed.js” – являється конструкором який відповідає за
установку швидкості програвання вибраного відеофайлу у виконуваному файлі
проекту
Файл “SetStartPoint.js” – являється конструкором який відповідає за
установлення початкової точки на моменті програвання відео, що виконує дію
обрізання відеофайлу у проекті.
Файл “SetVolume.js” – являється конструкором який відповідає за
установку ріню гучності вибраного відеофайлу у виконуваному файлі проекту.
Файл “SplitVideo.js” – являється конструкором який відповідає за
установлення середньої точки на моменті програвання відео, що виконує дію
обрізання відеофайлу на дві частини у проекті. Поки що дана функція
знаходиться на етапі розробки.
Файл “UndoStack.js” – являється конструкором який відповідає за відміну
змін дій з відеоматеріалом при використанні застосунку у виконуваному файлі
проекту.
Папка “lib” відповідна за зберігання готових бібліотечних файлів, функції
яких використовуються у застосунку. Тут знаходяться бібліотеки Materialize,
Hammer та Jquery.
Material Design - це мова дизайну, створена Google. В основному
матеріальний дизайн прагне поєднати класичні принципи гарного дизайну з
інноваціями та можливостями технологій та науки. Materialize - це адаптивна
бібліотека компонентів інтерфейсу, подібна до Bootstrap. Він пропонує все, що
може запропонувати Bootstrap, але відмінність полягає в тому, що Materialize
відповідає принципам дизайну матеріалів. Вона спрямована на розробку єдиної
базової системи, яка забезпечує уніфікований підхід використання на різних
платформах та розмірах пристроїв. Material Design забезпечує безперебійну
роботу користувачів на всіх пристроях. Чуйні переходи та анімація, а також
39

ефекти підбивки та глибини, такі як тіні та блискавки, роблять його відчутним


елегантним та зручним для користувача. Як приклад можна навести Google, що
використовує Material Design майже у всіх своїх додатках (таких як Keep і
Календар).
jQuery - це швидка, невелика та багатофункціональна бібліотека
JavaScript. Це робить такі речі, як обхід та маніпулювання документами HTML,
обробка подій, анімація та Ajax набагато простішими за допомогою простого у
використанні API, який працює в багатьох браузерах. Завдяки поєднанню
універсальності та розширюваності jQuery змінив спосіб написання JavaScript
мільйонами людей.
AJAX - це скорочення від асинхронного Javascript. Він оновлює лише
певні частини сторінки, тому не буде необхідності кожен раз оновлювати всю
сторінку. Технологія AJAX в основному використовується для створення
асинхронних запрошень до серверів. Асинхронний запрос - це така пропозиція,
яка виконується у фоновому режимі і не забезпечує користувальницького
взаємодії з іншими сторонами.
Hammer.js - це невелика автономна бібліотека javascript, яка дозволяє
здійснювати жести drag and drop в даному проекті. Hammer - це бібліотека з
відкритим кодом, яка може розпізнавати жести, зроблені дотиком, мишею та
покажчиком подій. Він не має ніяких залежностей від інших бібліотек.

3.2 Графічний інтерфейс


Інтерфейс був описаний на мові javascript, HTML та CSS. Після запуску
з’являється вікно з наступним вмістом.
Дане вікно програмного інтерфейсу застосунку користувача було
розроблено за допомогою додатку для мови програмування Java – Materialize,
це відкритий для використання фреймворк який використовується для розробки
мультиплатформенних додатків який реалізує власний дизайн та стиль в
незалежності від платформи.
40

Рисунок 3.2 Інтерфейс програмного застосунку

У відритому вікні інтерфейсу програмного застосунку можна побачити


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

Рисунок 3.3 Вікно вибору файла


Також, за допомогою Hammer.js, невеликої автономної бібліотеки
javascript, була реалізована можливість drag and drop, для її використання
41

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

Рисунок 3.4 Можливість drag and drop в застосунку

Рисунок 3.5 Результат вивантаження файлів різними способами


42

Таким чином відеофайли імпортуються в проект. Зліва знаходиться


повноцінний плеєр відеоредактору, він може робити відтворення вигруженних
відеофайлів до програмного застосунку, це стало можливим за допомогою
мультимедійного фреймворку FFmpeg. Під зображенням відеоплеєру можна
побачити повзунок для швикої навігації у відеоматеріалі що знаходиться у
відеоредакторі, відеоряд програє обидва відео як одне, без паузи та переходу,
адже ця частина є візуалізацією відео яке буде доступно після рендерингу. Біля
доріжки, справа росташована інформація щодо вибраного відео, а саме час на
моменті відтворення доріжки відео та загальний час усього відеоматеріалу.
Одразу ж біля часу ще правіше розашована кнопка у вигляді білої рамки, вона
відповідає за можливість перемикатися між повноекранним та укороченим
режимом перегляду.
Знизу вікна програмного застосунку є ще одна сіра лінія, що подібна до
верхньої, її ціль відокремлювати видиму інформацію що стосується самого
вибраного відео. Там представлена довжина часу відео яке було виділино та
кількість частоти зображень на кожну секунду того ж відео.
43

Рисунок 3.6 Відеоплеєр з відображеною інформацією

Справа знаходиться інша однолінійнадоріжка.

Рисунок 3.7 Однолінійна доріжка редагування


44

Вона була створена для перегляду та редагування відеофайлів в проекті. Ця


доріжка дозволяє обрізати відео, та орієнтувантися серед відеофайлів, також за
допомогою повзунку Zoom можна змінювати масштаб відтворення
відеоматеріалів.

Рисунок 3.8 Інтерфейс зміни масштабу відтворення


45

Рисунок 3.9 Результат зміни масштабу відтворення

Реалізована функція зміни швидкості відтворення та зміни гучності


вибранного відео.

Рисунок 3.10 Інтерактивний об’єкт для зміни швидкості відтворення та


зміни гучності вибраного відео

Змінений матеріал буде впливати на довжину правої доріжки оскільки він


прискорений, а інформація про довжину проекту під плеєром зміниться на
нову.
46

Рисунок 3.11 Результат зміни швидкості

Для розрізання відео необхідно натиснути правою кнопкою миші на


моменті відеодоріжки.

Рисунок 3.12 Задання точки обрізання


47

Для вибору проміжутку треба задати дві точки між якими знаходиться
бажаний відеоматеріал, це можна зробити натиснувши Set start point на його
початку

Рисунок 3.13 Задання початкової точки обрізання

і Set end point на його кінці.

Рисунок 3.14 Задання кінечної точки обрізання

Як результат відео на правій доріжці зменшиться, а на інформації під


плеєром зміняться дані про довжину проекту
48

Рисунок 3.15 Результат обрізання відео

Для видалення вибранного відеоматеріалу з проекту необхідно натиснути


клавішу Del

Рисунок 3.16 Результат видалення відеоматеріалу

Щоб експортувати відео необхідно вибрати Export,


49

Рисунок 3.17 Вибір функції експортування

а наступному вікні вибрати місце зберігання та ім’я файлу.

Рисунок 3.18 Вибір місця зберігання та ім’я файлу

Експортоване відео буде у форматі .mp4


50

ВИСНОВОК
В ході виконання випускної кваліфікаційної роботи, було спроектовано та
розроблено настільний застосунок для персонального комп’ютеру. Наприкінці
розробки отримано веб-адаптивний застосунок для монтування відео.
Застосунок має поле для відтворення та попереднього перегляду відео файлів, з
можливістю паралельно відредаговувати відеоматеріали за допомогою
інтерактивної доріжки на інтерфейсі користувача. Мається можливість
завантаження та перегляду одразу ж декількой медіафайлів у різних форматах
для створення відеоматеріалу у прогрманому продукті. На виході отримуємо
відредаговане відео у форматі .mp4.
В першому розділі нами було досліджено поняття систем
відеоредагування та розглянуто загальне становище даної теми. З першого
розділу визначається принципи кодування та форматування відео у сучасних
форматах.
У другому розділі нами було описано складові елементи системи та її
завдання, сценарії застосуванная застосунку для рядового користувача. Описані
методи лінійності відеоредактору в застосунку, скадені функції роботи з
файлами всередені розробленої системи.
В третьому розділі описуються програмна складова по функціям та
файлам програми з описом використаних бібліотек для розширення
функціоналу. Описується інтерфейс програмного застосунку та наводиться
приклад його застосування.
51

ВИКОРИСТАНІ ДЖЕРЕЛА
1. Боссен, Ф., Бросс, Б., член, С., Карстен, С. та Флін, Д. (2013).
HEVC Аналіз складності та впровадження. Схеми та системи для відеотехніки,
IEEE Transactions, 22(12):1685–1696.
2. Чунг, N.-m., Фан, X., Au, O. C., і Кунг, M.-c. (2010).
Відеокодуванняна багатоядерних графічних процесорах. Журнал обробки
сигналів, IEEE, (March):79–89.
3. Chi, C. C., Alvarez-mesa, M., Juurlink, B., Member, S., Clare, G., та
Ширіл, T. (2012). Паралельна масштабованість та ефективність підходів до
паралелізації HEVC. Схеми та системи для відеотехніки, IEEE Transactions,
22(12):1827–1838.
4. Cisco Systems, I. (2016). Індекс візуальних мереж Cisco - прогноз та
методологія.
5. Грінгал, П. (2012). big.LITTLE Обробка за допомогою ARM Cortex-
A15 і Cortex-A7. ARM, (вересень 2011 р.): 1–8. Він, Ю., Кунстнер, М.,
Гудумасу, С., Рю, Є. С., Є, Ю. та Сіу, X. (2013). Потужність. Трансляція HEVC
для мобільних пристроїв. У візуальних комунікаціях та обробці зображень
(VCIP), 2013, pages 1–5.
6. Holmbacka, S., Nogues, E., Pelcat, M., Lafond, S., and Lilius, J. (2014).
Енергоефективність та управління продуктивністю паралельних додатків
потоку даних. У „Дизайн та архітектура для обробки сигналів та зображень”
(DASIP), конференція 2014 р., Сторінки 1–8. 73 Бібліографія Джефф, B. (2012).
Досягнення технології big.LITTLE для енергозбереження та енергозбереження.
ARM, (вересень): 1–11.
7. Лі, В. Ю. (2012). Енергоефективне планування періодичних
завдань у режимі реального часу на легко завантажених багатоядерних
процесорах. Транзакції IEEE щодо паралельних та розподілених систем, 23 (3):
530–537.
8. Лі, В. Ю., Ко, Ю. В., Лі, Х. та Кім, Х. (2009). Енергоефективне
52

планування завдання в реальному часі на багатоядерних процесорах із


підтримкою dvfs. У матеріалах Міжнародної конференції з гібридних
інформаційних технологій 2009 року, ICHIT ’09, сторінки 273–277. ACM.
9. Момчиловіч, С., Іліч, А., Рома, Н. та Соуза, Л. (2014). Динамічне
балансування навантаження для кодування відео в режимі реального часу на
неоднорідних системах CPU + GPU. Мультимедіа, транзакції IEEE, 16 (1): 108–
121.
53

ДОДАТКИ
Додаток А. Функція Video.js
class Video {
constructor({
PlayerVideo,
ContainVid,
thumbcontain,
searchprogress,
lookThumb,
Timestam,
Play,
FPSelement,
DurationOf,
ControllingFrags,
BoostSpeed,
VolumePref,
BoostIn,
VolIn
}) {
fragments = [];
PlayerVideo = PlayerVideo;
ContainVid = ContainVid;
thumbcontain = thumbcontain;
searchprogress = searchprogress;
lookThumb = lookThumb;
Timestam = Timestam;
Play = Play;
FPSelement = FPSelement;
DurationOf = DurationOf;
ControllingFrags = ControllingFrags;
54

BoostSpeed = BoostSpeed;
Volumepref = Volumepref;
BoostIn = BoostIn;
VolIn = VolIn;

document.addEventListener('mousemove', e => onMouseMove(e));


document.addEventListener('mouseup', () => {
seeking = false;
});
seeking = false;
shouldShowContextMenu = false;
thumbnailZoom = 3;

createContextMenu();
}
createContextMenu() {
require('electron-context-menu')({
prepend: (params, browserWindow) => [{
label: "Set start point",
click: () => {
console.log("Setting start point", activeFragment.currentPoint,
activeFragment.duration);
new SetStartPoint(activeFragment,
activeFragment.currentPoint).execute();
}
}, {
label: "Set end point",
click: () => {
new SetEndPoint(activeFragment,
activeFragment.currentPoint).execute();
55

}
}, {
label: "Split video",
click: () => {
new SplitVideo(this, activeFragment,
activeFragment.currentPoint).execute();
}
}],
shouldShowMenu: (e, params) => {
let value = shouldShowContextMenu;
shouldShowContextMenu = false;
return value;
},
showInspectElement: false
});
}

addFragment(fragment, index = false) {


fragment.thumbnailSeeker.addEventListener('mousedown', e => {
if (e.button === 2) {
shouldShowContextMenu = true;
} else if (e.button === 0) {
seeking = true;
onMouseMove(e);
}
});
fragment.thumbnailElement.addEventListener('mouseenter', () =>
hoveringFragment = fragment);

fragment.thumbnailElement.addEventListener('mouseup', () => {
56

if (!seeking) {
if (activeFragment && fragment !== activeFragment) {
activeFragment.currentTime = 0;
activeFragment = fragment;
pause();
updateTime();
fragment.addEventListener('loadedData', () => {
updateTime();
});
fragment.pause();
}
}
});

fragment.addEventListener('loadedMetadata', () => {
if (++loaded === toLoad) {
if (!activeFragment) {
currentTime = 0;
}
}
updateTime();
});

fragment.addEventListener('timeChange', () => updateTime());

if (index !== false) {


moveFragment(fragment, index);
} else {
ContainVid.appendChild(fragment.element);
thumbcontain.appendChild(fragment.thumbnailElement);
57

fragments.push(fragment);
}

activeFragment = fragment;

showPlayer();
}

get playerIsVisible() {
return PlayerVideo.style.display !== "none" && PlayerVideo.style.display !==
"";
}

showPlayer() {
if (!playerIsVisible) {
PlayerVideo.style.display = "block";
ControllingFrags.style.display = "block";
}
}

hidePlayer() {
if (playerIsVisible) {
PlayerVideo.style.display = "none";
ControllingFrags.style.display = "none";
}
}

removeFragment(fragment) {
fragment.pause();
58

if (fragment.element.parentNode)
fragment.element.parentNode.removeChild(fragment.element);

if (fragment.thumbnailElement.parentNode)
fragment.thumbnailElement.parentNode.removeChild(fragment.thumbnailEle
ment);

let foundIndex = fragments.indexOf(fragment);


if (foundIndex !== -1)
fragments.splice(foundIndex, 1);

if (activeFragment === fragment && fragments.length > 0) {


activeFragment = fragments[Math.max(foundIndex - 1, 0)];
console.log(1);
}

if (fragments.length === 0) {
hidePlayer();
video.activeFragment = undefined;
} else {
updateTime();
}
}

static insertNodeAt(parent, newChild, desiredIndex) {


let children = parent.children;
if (desiredIndex === children.length) {
parent.appendChild(newChild);
} else {
parent.insertBefore(newChild, children[desiredIndex]);
59

}
}

moveFragment(fragment, index) {
removeFragment(fragment);
Video.insertNodeAt(thumbcontain, fragment.thumbnailElement, index);
Video.insertNodeAt(ContainVid, fragment.element, index);
fragments.splice(index, 0, fragment);
// updateTime();
}

split(fragment, timePercent = 0.5) {


console.log(currentTime);
let time = currentTime;
let index = fragments.indexOf(fragment);

let newFragment = new VideoFragment(fragment.file, thumbnailZoom);


newFragment.playbackSpeed = fragment.playbackSpeed;
newFragment.endPoint = fragment.endPoint;
newFragment.volume = fragment.volume;

console.log('new splitted fragment index: ', index);


addFragment(newFragment, index + 1);

newFragment.startPoint = timePercent;
fragment.endPoint = timePercent;

// activeFragment = newFragment;
newFragment.addEventListener("loadedData", () => {
currentTime = time;
60

updateTime();
});

return newFragment;
}

onMouseMove(e) {
if (seeking && hoveringFragment) {
let offset = hoveringFragment.thumbnailElement.getBoundingClientRect();
let x = e.pageX - offset.left;
let width = hoveringFragment.thumbnailElement.offsetWidth;

x = x < 0 ? 0 : x;
x = x > width ? width : x;

let startTime = 0;
for (let fragment of fragments) {
if (fragment === hoveringFragment) {
break;
}
startTime += fragment.duration;
}
currentTime = startTime + hoveringFragment.duration * x / width;
}
}

set currentTime(value) {
if (value >= 0 && value <= duration) {
let prevFragment = activeFragment;
let originalValue = value;
61

for (let fragment of fragments) {


if (value < fragment.duration) {
fragment.currentTime = value;
activeFragment = fragment;
break;
} else {
value -= fragment.duration;
}
}

if (activeFragment !== prevFragment) {


for (let fragment of fragments) {
if (activeFragment === fragment && playing)
fragment.play();
else
fragment.pause();
}
}

updateTime(originalValue);
}
}

playLoop() {
updateTime(currentTime);

if (activeFragment.currentTime + 1 / activeFragment.fps >


activeFragment.duration) {
let currentIndex = fragments.indexOf(activeFragment);
62

if (currentIndex + 1 >= fragments.length) {


pause();
} else {
activeFragment.pause();
activeFragment = fragments[currentIndex + 1];

activeFragment.play(0);
updateTime();
}
}
}

play() {
if (!playing) {
Play.innerText = "pause";

playing = self.setInterval(() => playLoop(), 1000 / 60);


activeFragment.play();
}
}

pause() {
if (playing) {
Play.innerText = "play_arrow";

clearInterval(playing);
activeFragment.pause();
delete playing;
}
}
63

updateTime(value) {
if (value === undefined)
value = currentTime;

let duration = duration;


let percentage = value / duration * 100;

lookThumb.style.left = `calc(${percentage}% - 7px)`;


searchprogress.style.width = percentage + '%';

Timestam.innerText = Video.secondsToHms(value) + ' / ' +


Video.secondsToHms(duration);

if (activeFragment) {
let thumbPercentage = activeFragment.currentTime / activeFragment.duration
* 100;
activeFragment.thumbnailSeeker.style.left = `calc(${thumbPercentage}% -
2px)`;

BoostIn.value = activeFragment.playbackSpeed;
VolIn.value = activeFragment.volume * 100;
}

updateBottomInfo();
}

static secondsToHms(seconds) {
let stamp = new Date();
stamp.setTime(seconds * 1000);
64

let h = stamp.getHours();

let m = stamp.getMinutes();
m = m < 10 ? '0' + m : m;

let s = stamp.getSeconds();
s = s < 10 ? '0' + s : s;

let cs = Math.floor(stamp.getMilliseconds() / 10);


cs = cs < 10 ? '0' + cs : cs;

let hms = `${m}:${s}.${cs}`;


if (h === "0")
hms = h + hms;

return hms;
}

static hmsToSeconds(hms) {
let [h, m, s] = hms.split(':');
return Number(h) * 3600 + Number(m) * 60 + Number(s);
}

get duration() {
let duration = 0;
for (let fragment of fragments) {
duration += fragment.duration;
}
return duration;
65

addFragments(...files) {
if (files[0] instanceof FileList)
files = files[0];

loaded = 0;
toLoad = files.length;

for (let file of files) {


addFragmentByPath(file.path);
}
}

isValidPath(path) {
let allowed = ['mp4', 'avi', 'webm', 'flv'];
for (let format of allowed)
if (path.toLowerCase().includes(format))
return true;
return false;
}

addFragmentByPath(path) {
if (!isValidPath(path))
return console.error("Path is not a valid video file");
let fragment = new VideoFragment(path, thumbnailZoom);
new AddFragment(this, fragment).execute();
}
set thumbnailZoom(value) {
_thumbnailZoom = value;
66

for (let fragment of fragments) {


fragment.widthPerSecond = thumbnailZoom;
fragment.updateThumbnailWidth();
}
}

get thumbnailZoom() {
return _thumbnailZoom;
}

nextFrame() {
pause();
currentTime += 1 / activeFragment.fps;
}

previousFrame() {
pause();
currentTime -= 1 / activeFragment.fps;
}

get currentTime() {
let time = 0;
for (let fragment of fragments) {
if (fragment === activeFragment) {
return time + fragment.currentTime;
}
time += fragment.duration;
}
67

set activeFragment(value) {
if (value !== undefined) {
if (_activeFragment !== undefined && _activeFragment !== value)
_activeFragment.active = false;
value.active = true;
}

updateBottomInfo();
_activeFragment = value;
}

updateBottomInfo() {
if (activeFragment) {
FPSelement.innerText = "Frame rate: " + activeFragment.fps;
DurationOf.innerText = "Duration: " +
Video.secondsToHms(activeFragment.duration);
BoostSpeed.innerText = `Playback speed: $
{activeFragment.playbackSpeed}x`;
Volumepref.innerText = `Volume: ${Math.round(activeFragment.volume *
100)}%`;
}
}

get activeFragment() {
return _activeFragment;
}

upload({
68

config = ExportConfig.default,
title = 'Uploaded with VideoEditor',
description = 'https://github.com/RuurdBijlsma/Ruurd-Movie-Maker',
publicity = 'public',
onProgress = console.log
}) {
return new Promise(resolve => {
let format = 'mp4';
let tmpFile = `${tmpDir}/toUpload.${format}`;
let progress = 0;
let tokens;
Youtube.getAccessToken().then(t => {
tokens = t;
});
export({
config: config,
overwrite: true,
outputFile: tmpFile,
clearTmpDir: false,
onProgress: p => {
progress = p / 2;
onProgress(progress);
}
}).then(() => {
let startUpload = () => {
Youtube.upload({
path: tmpFile,
title: title,
description: description,
publicity: publicity,
69

onProgress: p => {
progress = 0.5 + p / 2;
onProgress(progress);
},
tokens: tokens,
}).then(e => {
resolve(e);
node.deleteDirectory(tmpDir);
});
};
if (!tokens) {
let checkUpload = self.setInterval(() => {
if (tokens) {
startUpload();
clearInterval(checkUpload);
}
console.log('Waiting for user...');
}, 100);
} else
startUpload();
});
});
}

export({
config = ExportConfig.default,
overwrite = true,
outputFile = 'output',
clearTmpDir = true,
onProgress = () => {
70

}
}) {
return new Promise(resolve => {
let i = 0;
let secondsProcessed = [];
let fragmentsToProcess = fragments.length;
let duration = duration;

node.clearDirectory(tmpDir);

for (let fragment of fragments) {


let index = false;
fragment.export({
outputFile: `${tmpDir}/${i++}.${config.format}`,
fps: config.fps,
process: seconds => {
if (index === false) {
index = secondsProcessed.length;
}
secondsProcessed[index] = seconds;
let percentage = Math.min(duration, secondsProcessed.reduce((a, b)
=> a + b)) / duration;
onProgress(percentage);
}
}).then(() => {
if (--fragmentsToProcess <= 0) {
let tempFiles = [];
for (let i = 0; i < fragments.length; i++)
tempFiles.push(`${i}.${config.format}`);
71

FFMPEG.concatFiles(tempFiles, `${outputFile}`, overwrite).then(()


=> {
if (clearTmpDir)
node.deleteDirectory(tmpDir);
resolve();
});
}
});
}
});
}
}

Додаток Б. Функція VidoFragment.js


class VideoFragment {
constructor(path, widthPerSecond = 3) {
eventListeners = {};
path = path;

element = document.createElement("video");
element.src = path;
element.load();

thumbnailElement = document.createElement("div");
thumbnailElement.setAttribute("class", "thumbnail");
thumbnailSeeker = document.createElement('div');
thumbnailSeeker.setAttribute("class", "thumbnail-seeker");
thumbnailElement.appendChild(thumbnailSeeker);
let innerSeeker = document.createElement('div');
innerSeeker.setAttribute("class", "thumbnail-inner-seeker");
72

thumbnailSeeker.appendChild(innerSeeker);

metadataLoaded = false;
element.onloadedmetadata = () => {
metadataLoaded = true;

executeEvent("loadedMetadata");
};
element.onloadeddata = () => {
executeEvent("loadedData");
widthPerSecond = widthPerSecond;
updateThumbnail(startPoint);
};

active = false;
startPoint = 0;
endPoint = 1;
playbackSpeed = 1;

updateFps();
}

timeToPoint(time) {
return startPoint + (time / durationWithoutEndTime) * (1 - startPoint);
}

get currentPoint() {
return timeToPoint(currentTime);
73

set active(value) {
_active = value;
if (value) {
element.style.zIndex = 1;
thumbnailElement.setAttribute("active", "");
executeEvent("timeChange");
} else {
element.style.zIndex = 0;
thumbnailElement.removeAttribute("active");
currentTime = 0;
pause();
}
}

get active() {
return _active;
}

addEventListener(name, action) {
if (!eventListeners[name])
eventListeners[name] = [];

eventListeners[name].push(action);
}

executeEvent(name) {
if (eventListeners.hasOwnProperty(name))
for (let action of eventListeners[name])
74

action();
}

get thumbnail() {
if (_thumbnail) {
return _thumbnail;
}
console.warn("Thumbnail hasn't loaded yet");
return null;
}

get exportStartTime() {
if (metadataLoaded) {
return startPoint * (element.duration /* / playbackSpeed*/);
}
console.warn("Video metadata hasn't loaded yet");
return 0;
}

get duration() {
if (metadataLoaded) {
return (endPoint - startPoint) * (element.duration / playbackSpeed);
}
console.warn("Video metadata hasn't loaded yet");
return 0;
}

get durationWithoutEndTime() {
if (metadataLoaded) {
return (1 - startPoint) * (element.duration / playbackSpeed);
75

}
console.warn("Video metadata hasn't loaded yet");
return 0;
}

get fps() {
return _fps * playbackSpeed;
}

updateFps() {
FFMPEG.runCommand(['-i', path]).then(info => {
let words = info.stderr.split('\n').find(line => line.includes(' fps')).split(' fps')
[0].split(' ');
_fps = Number(words[words.length - 1]);
executeEvent("loadedFps");
});
}

updateThumbnail(timePercentage = 0) {
getThumbnail(80, timePercentage).then(url => {
executeEvent("thumbnail");
thumbnailElement.style.backgroundImage = `url('${thumbnail}')`;
});
}

getThumbnail(height = 80, timePercentage = 0) {


return new Promise(resolve => {
let canvas = document.createElement('canvas');
let context = canvas.getContext('2d');
76

if (!isNaN(element.duration))
element.currentTime = timePercentage * element.duration;

element.oncanplaythrough = () => {
setTimeout(() => {
context.width = height / element.videoHeight * element.videoWidth;
context.height = height;
canvas.setAttribute("width", context.width);
canvas.setAttribute("height", context.height);

context.drawImage(element, 0, 0, context.width, context.height);

if (context.getImageData(10, 10, 1, 1).data[3] !== 0) {


_thumbnail = canvas.toDataURL();
resolve(_thumbnail);
} else {
console.warn("Could not get thumbnail")
}
}, 100);
};
});
}
get thumbnailWidth() {
return Math.round(duration * widthPerSecond);
}

updateThumbnailWidth() {
thumbnailElement.style.width = thumbnailWidth + "px";
executeEvent("timeChange");
}
77

get volume() {
return element.volume;
}

set volume(value) {
if (value < 0 || value > 1)
console.warn("Value must be within range [0-1]");
element.volume = value;
executeEvent("timeChange");
}

get playbackSpeed() {
return _playbackSpeed;
}

set playbackSpeed(value) {
_playbackSpeed = value;
element.playbackRate = value;
updateThumbnailWidth();
}

get startPoint() {
return _startTime;
}

set startPoint(value) {
if (value < 0) {
console.warn("startPoint can't be lower than 0");
return;
78

_startTime = value;
updateThumbnailWidth();
}

get endPoint() {
return _endTime;
}

set endPoint(value) {
if (value > 1) {
console.warn("endPoint can't be higher than the video duration");
return;
}

_endTime = value;

if (currentTime > duration)


currentTime = duration;

updateThumbnailWidth();
}

get widthPerSecond() {
return _widthPerSecond;
}

set widthPerSecond(value) {
_widthPerSecond = value;
79

updateThumbnailWidth();
}

play(from) {
if (from !== undefined) {
currentTime = from;
}
if (element.paused)
element.play();
}

pause() {
element.pause();
}

get currentTime() {
let point = durationWithoutEndTime * (startPoint * element.duration -
element.currentTime);
point /= (startPoint - 1) * element.duration;

return point;
}

set currentTime(value) {
let point = timeToPoint(value);
point *= element.duration;

if (!isNaN(point))
element.currentTime = point;
}
80

export({
outputFile = 'output.mp4',
fps = null,
process = s => console.log(s),
}) {
let f = new FFMPEG();

f.input = path;
f.output = outputFile;
f.startTime = exportStartTime;
console.log("Exporting", exportStartTime);
f.overwrite = true;
if (duration !== element.duration)
f.duration = duration;
if (fps !== fps && fps !== null)
f.frameRate = fps;
if (playbackSpeed !== 1)
f.playbackSpeed = playbackSpeed;
if (volume !== 1)
f.volume = volume;

console.log(f);

return f.run(i => process(Math.min(i.time, duration)));


}
}

You might also like