nlve/src/uProgressForm.pas

186 lines
6.8 KiB
ObjectPascal
Raw Normal View History

Нелинейный видеоредактор без перекодирования Куски видео вырезаются и склеиваются копированием потока: сборка ролика занимает время копирования файла, а не время рендера. Композитинга нет принципиально — при перекрытии побеждает клип с верхней дорожки целиком, и картинкой, и звуком. Именно это ограничение и делает сборку копированием возможной. Что внутри: - монтажный стол со своей отрисовкой: дорожки, масштаб, прилипание, схлопывание, громкость на клипе; - предпросмотр прямо с монтажа через libmpv и виртуальный список кусков, без промежуточных файлов; - сборка через ffmpeg с точными резами: перекодируется только огрызок от реза до ближайшего опорного кадра, остальное копируется; - разбор заголовка MP4 для поиска опорных кадров — в 500 раз быстрее опроса ffprobe; - перепаковка контейнеров, кадрирование и поворот, сведения о проекте; - свои цвета всего окна: системные элементы под Windows цвет не берут, поэтому кнопки, полоса меню, журнал и полосы прокрутки нарисованы сами; - окно зависимостей: недостающие ffmpeg, ffprobe и libmpv скачиваются с официальных источников; - кросс-сборка под Windows и работа под Wine. Первый коммит: до этого история не велась.
2026-08-19 18:36:16 +03:00
{
uProgressForm — окно хода долгой операции.
Показывается модально, пока работает рабочий поток. Поток шлёт сюда
состояние через Synchronize, поэтому все методы этого окна вызываются
из потока интерфейса и никакой защиты не требуют.
Кнопка одна и меняет назначение: пока идёт работа — «Отмена», после
завершения — «Закрыть». Так окно нельзя закрыть, не остановив работу,
и не приходится гадать, что стало с процессом.
}
unit uProgressForm;
{$mode objfpc}{$H+}
interface
uses
Затухания видны и настраиваются, сборка с перекодированием, свой журнал в окне сборки Затухания. Механика была написана давно и работала в сборке, но увидеть или задать её было нечем. Теперь у клипа два верхних угла — ручки: левая тянет появление, правая уход. Взятое затухание рисуется срезанным углом, так это устроено в монтажных программах. Ручки перехватывают нажатие раньше растягивания за край: они мелкие, промахнуться мимо них легче, а взяться за край можно ниже. Перекрытие двух клипов одной дорожки — это переход, и он теперь помечен косым крестом во всю высоту. Раньше о нём можно было узнать только по предупреждению перед сборкой. Сборка с перекодированием. Отдельный пункт меню и отдельное окно: размер кадра от 720p до 4K, поток в килобитах, кодек HEVC или H.264. Перекодирование идёт одним проходом на весь ролик — пересобирать куски по отдельности нельзя, на стыках была бы видна смена качества. Кодирование на видеокарте, и распаковка тоже: замерено на паре кусков 2688x1512 — 9.18 с на процессоре против 1.77 с с аппаратной распаковкой, впятеро. Полностью карточный путь через scale_cuda оказался медленнее (5.74 с) и не взят. Если аппаратная распаковка не пойдёт, сборка повторяется без неё: медленно лучше, чем никак. Окно честно предупреждает, когда аппаратного кодировщика в ffmpeg нет вовсе. Журнал в окне сборки заменён на свой: у системного поля оставались светлые полосы прокрутки и не работала прокрутка вбок с Shift. Это было последнее такое место.
2026-08-21 18:11:59 +03:00
Classes, SysUtils, Forms, Controls, Graphics, ComCtrls, StdCtrls, ExtCtrls,
uTheme, uLogView;
Нелинейный видеоредактор без перекодирования Куски видео вырезаются и склеиваются копированием потока: сборка ролика занимает время копирования файла, а не время рендера. Композитинга нет принципиально — при перекрытии побеждает клип с верхней дорожки целиком, и картинкой, и звуком. Именно это ограничение и делает сборку копированием возможной. Что внутри: - монтажный стол со своей отрисовкой: дорожки, масштаб, прилипание, схлопывание, громкость на клипе; - предпросмотр прямо с монтажа через libmpv и виртуальный список кусков, без промежуточных файлов; - сборка через ffmpeg с точными резами: перекодируется только огрызок от реза до ближайшего опорного кадра, остальное копируется; - разбор заголовка MP4 для поиска опорных кадров — в 500 раз быстрее опроса ffprobe; - перепаковка контейнеров, кадрирование и поворот, сведения о проекте; - свои цвета всего окна: системные элементы под Windows цвет не берут, поэтому кнопки, полоса меню, журнал и полосы прокрутки нарисованы сами; - окно зависимостей: недостающие ffmpeg, ffprobe и libmpv скачиваются с официальных источников; - кросс-сборка под Windows и работа под Wine. Первый коммит: до этого история не велась.
2026-08-19 18:36:16 +03:00
type
{ TProgressForm }
TProgressForm = class(TForm)
btnAction: TThemedButton;
lblStage: TLabel;
Свойства клипа, порядок дорожек, оценка времени и продолжение сборки Копирование оформления: Ctrl+Shift+C берёт с выделенного клипа кадрирование, поворот, увеличение, смещение, прозрачность, ключ, затухания и громкость, Ctrl+Shift+V применяет их ко всем выделенным. Вид клипа и текст не переносятся: свойства копируют между разными клипами. Порядок дорожек: слева в заголовке две стрелки, у крайних дорожек соответствующая нарисована тускло и не нажимается. Двойной щелчок по названию переименовывает дорожку — на монтаже из десятка дорожек «карта» и «титры» читаются лучше, чем V1 и Т1. То же есть и в меню по правому щелчку. Ввод имени — своим тёмным окном: системный InputQuery выглядел бы белым пятном. Окно сборки показывает, сколько прошло и сколько примерно осталось. Оценка по пройденной доле; скорость на деле меняется, поэтому «примерно» и пересчёт на каждом шаге. Прерванная сборка продолжается с готовых кусков. Каждый доведённый до конца кусок помечается в списке рядом с ними: одного наличия файла мало — сборку могли прервать посреди записи. Первая строка списка — отпечаток плана; не совпал, значит монтаж менялся, и всё собирается заново. Проверено: четыре куска взяты готовыми, два пересобраны, склейка не потеряла ни одного кадра; при изменённом монтаже готовые куски отвергнуты.
2026-08-31 14:55:19 +03:00
lblEta: TLabel;
Затухания видны и настраиваются, сборка с перекодированием, свой журнал в окне сборки Затухания. Механика была написана давно и работала в сборке, но увидеть или задать её было нечем. Теперь у клипа два верхних угла — ручки: левая тянет появление, правая уход. Взятое затухание рисуется срезанным углом, так это устроено в монтажных программах. Ручки перехватывают нажатие раньше растягивания за край: они мелкие, промахнуться мимо них легче, а взяться за край можно ниже. Перекрытие двух клипов одной дорожки — это переход, и он теперь помечен косым крестом во всю высоту. Раньше о нём можно было узнать только по предупреждению перед сборкой. Сборка с перекодированием. Отдельный пункт меню и отдельное окно: размер кадра от 720p до 4K, поток в килобитах, кодек HEVC или H.264. Перекодирование идёт одним проходом на весь ролик — пересобирать куски по отдельности нельзя, на стыках была бы видна смена качества. Кодирование на видеокарте, и распаковка тоже: замерено на паре кусков 2688x1512 — 9.18 с на процессоре против 1.77 с с аппаратной распаковкой, впятеро. Полностью карточный путь через scale_cuda оказался медленнее (5.74 с) и не взят. Если аппаратная распаковка не пойдёт, сборка повторяется без неё: медленно лучше, чем никак. Окно честно предупреждает, когда аппаратного кодировщика в ffmpeg нет вовсе. Журнал в окне сборки заменён на свой: у системного поля оставались светлые полосы прокрутки и не работала прокрутка вбок с Shift. Это было последнее такое место.
2026-08-21 18:11:59 +03:00
memoLog: TLogView;
Показатель работы: число и полоса показывают одно и то же Полоса ползла по догадке, а подпись показывала замер — и человек видел полосу, заполненную на девять десятых, рядом с нулём процентов. Что в этот момент происходит, по такой паре понять нельзя. Теперь доля одна на обоих. Берётся она у самого ffmpeg: сборка участка с затуханием идёт минуту и дольше, а «кусок 1 из 1» всё это время не меняется, поэтому ffmpeg спрашивают ключом -progress, докуда он дошёл. Пока он не ответил ни разу, полоса трогается с места на пару процентов и там стоит — пустая полоса и есть правда о только что начатой работе. Догадка заодно перестала закрывать промежуток до вехи целиком: предел — девять десятых, остаток виден глазом. Проверка на это добавлена в tests/progress. Полоса в окне сборки была системной, и под gtk2 заполнялась ступенями по восемь кусков на ширину. Теперь там та же своя полоса, что и внизу главного окна, — заполняется сплошь. Чтобы она читалась из файла формы, у неё опубликованы Anchors, Align и Visible: читатель формы берёт только опубликованные свойства, и без этого окно падало при открытии. Проверено глазами на невидимом экране: «Собираю наложение 1 из 1 — 2%» при полосе в 2%, через четыре секунды 69% при полосе в 69%.
2026-10-01 15:50:10 +03:00
{ Полоса своя, а не системная: TProgressBar под gtk2 рисуется
ступеньками, по восемь кусков на всю ширину, и ход работы в ней
виден рывками. Эта заполняется сплошь, как та, что внизу главного
окна. }
pbBar: TThemedProgress;
Нелинейный видеоредактор без перекодирования Куски видео вырезаются и склеиваются копированием потока: сборка ролика занимает время копирования файла, а не время рендера. Композитинга нет принципиально — при перекрытии побеждает клип с верхней дорожки целиком, и картинкой, и звуком. Именно это ограничение и делает сборку копированием возможной. Что внутри: - монтажный стол со своей отрисовкой: дорожки, масштаб, прилипание, схлопывание, громкость на клипе; - предпросмотр прямо с монтажа через libmpv и виртуальный список кусков, без промежуточных файлов; - сборка через ffmpeg с точными резами: перекодируется только огрызок от реза до ближайшего опорного кадра, остальное копируется; - разбор заголовка MP4 для поиска опорных кадров — в 500 раз быстрее опроса ffprobe; - перепаковка контейнеров, кадрирование и поворот, сведения о проекте; - свои цвета всего окна: системные элементы под Windows цвет не берут, поэтому кнопки, полоса меню, журнал и полосы прокрутки нарисованы сами; - окно зависимостей: недостающие ffmpeg, ffprobe и libmpv скачиваются с официальных источников; - кросс-сборка под Windows и работа под Wine. Первый коммит: до этого история не велась.
2026-08-19 18:36:16 +03:00
pnlTop: TPanel;
procedure btnActionClick(Sender: TObject);
procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
procedure FormCreate(Sender: TObject);
private
FFinished: Boolean;
FCancelRequested: Boolean;
FOnCancelRequest: TNotifyEvent;
Свойства клипа, порядок дорожек, оценка времени и продолжение сборки Копирование оформления: Ctrl+Shift+C берёт с выделенного клипа кадрирование, поворот, увеличение, смещение, прозрачность, ключ, затухания и громкость, Ctrl+Shift+V применяет их ко всем выделенным. Вид клипа и текст не переносятся: свойства копируют между разными клипами. Порядок дорожек: слева в заголовке две стрелки, у крайних дорожек соответствующая нарисована тускло и не нажимается. Двойной щелчок по названию переименовывает дорожку — на монтаже из десятка дорожек «карта» и «титры» читаются лучше, чем V1 и Т1. То же есть и в меню по правому щелчку. Ввод имени — своим тёмным окном: системный InputQuery выглядел бы белым пятном. Окно сборки показывает, сколько прошло и сколько примерно осталось. Оценка по пройденной доле; скорость на деле меняется, поэтому «примерно» и пересчёт на каждом шаге. Прерванная сборка продолжается с готовых кусков. Каждый доведённый до конца кусок помечается в списке рядом с ними: одного наличия файла мало — сборку могли прервать посреди записи. Первая строка списка — отпечаток плана; не совпал, значит монтаж менялся, и всё собирается заново. Проверено: четыре куска взяты готовыми, два пересобраны, склейка не потеряла ни одного кадра; при изменённом монтаже готовые куски отвергнуты.
2026-08-31 14:55:19 +03:00
{ Когда началась работа и какую долю показывали в прошлый раз: по ним
считается, сколько осталось. }
FStartedAt: TDateTime;
FLastFraction: Double;
function FormatSpan(const ASeconds: Double): string;
Нелинейный видеоредактор без перекодирования Куски видео вырезаются и склеиваются копированием потока: сборка ролика занимает время копирования файла, а не время рендера. Композитинга нет принципиально — при перекрытии побеждает клип с верхней дорожки целиком, и картинкой, и звуком. Именно это ограничение и делает сборку копированием возможной. Что внутри: - монтажный стол со своей отрисовкой: дорожки, масштаб, прилипание, схлопывание, громкость на клипе; - предпросмотр прямо с монтажа через libmpv и виртуальный список кусков, без промежуточных файлов; - сборка через ffmpeg с точными резами: перекодируется только огрызок от реза до ближайшего опорного кадра, остальное копируется; - разбор заголовка MP4 для поиска опорных кадров — в 500 раз быстрее опроса ffprobe; - перепаковка контейнеров, кадрирование и поворот, сведения о проекте; - свои цвета всего окна: системные элементы под Windows цвет не берут, поэтому кнопки, полоса меню, журнал и полосы прокрутки нарисованы сами; - окно зависимостей: недостающие ffmpeg, ffprobe и libmpv скачиваются с официальных источников; - кросс-сборка под Windows и работа под Wine. Первый коммит: до этого история не велась.
2026-08-19 18:36:16 +03:00
public
procedure SetStage(const AText: string);
procedure SetFraction(AValue: Double);
procedure AddLog(const AText: string);
{ Переводит окно в завершённое состояние: прогресс на месте, кнопка
становится «Закрыть». }
procedure Finish(ASuccess: Boolean; const AMessage: string);
property Finished: Boolean read FFinished;
property OnCancelRequest: TNotifyEvent read FOnCancelRequest
write FOnCancelRequest;
end;
implementation
{$R *.lfm}
{ TProgressForm }
procedure TProgressForm.FormCreate(Sender: TObject);
begin
{ Цвета задаём сами: системная тема может быть светлой, и тогда
тёмный таймлайн оказался бы в белой рамке. }
ApplyDarkTheme(Self);
Показатель работы: число и полоса показывают одно и то же Полоса ползла по догадке, а подпись показывала замер — и человек видел полосу, заполненную на девять десятых, рядом с нулём процентов. Что в этот момент происходит, по такой паре понять нельзя. Теперь доля одна на обоих. Берётся она у самого ffmpeg: сборка участка с затуханием идёт минуту и дольше, а «кусок 1 из 1» всё это время не меняется, поэтому ffmpeg спрашивают ключом -progress, докуда он дошёл. Пока он не ответил ни разу, полоса трогается с места на пару процентов и там стоит — пустая полоса и есть правда о только что начатой работе. Догадка заодно перестала закрывать промежуток до вехи целиком: предел — девять десятых, остаток виден глазом. Проверка на это добавлена в tests/progress. Полоса в окне сборки была системной, и под gtk2 заполнялась ступенями по восемь кусков на ширину. Теперь там та же своя полоса, что и внизу главного окна, — заполняется сплошь. Чтобы она читалась из файла формы, у неё опубликованы Anchors, Align и Visible: читатель формы берёт только опубликованные свойства, и без этого окно падало при открытии. Проверено глазами на невидимом экране: «Собираю наложение 1 из 1 — 2%» при полосе в 2%, через четыре секунды 69% при полосе в 69%.
2026-10-01 15:50:10 +03:00
pbBar.Fraction := 0;
Нелинейный видеоредактор без перекодирования Куски видео вырезаются и склеиваются копированием потока: сборка ролика занимает время копирования файла, а не время рендера. Композитинга нет принципиально — при перекрытии побеждает клип с верхней дорожки целиком, и картинкой, и звуком. Именно это ограничение и делает сборку копированием возможной. Что внутри: - монтажный стол со своей отрисовкой: дорожки, масштаб, прилипание, схлопывание, громкость на клипе; - предпросмотр прямо с монтажа через libmpv и виртуальный список кусков, без промежуточных файлов; - сборка через ffmpeg с точными резами: перекодируется только огрызок от реза до ближайшего опорного кадра, остальное копируется; - разбор заголовка MP4 для поиска опорных кадров — в 500 раз быстрее опроса ffprobe; - перепаковка контейнеров, кадрирование и поворот, сведения о проекте; - свои цвета всего окна: системные элементы под Windows цвет не берут, поэтому кнопки, полоса меню, журнал и полосы прокрутки нарисованы сами; - окно зависимостей: недостающие ffmpeg, ffprobe и libmpv скачиваются с официальных источников; - кросс-сборка под Windows и работа под Wine. Первый коммит: до этого история не велась.
2026-08-19 18:36:16 +03:00
memoLog.Clear;
btnAction.Caption := 'Отмена';
Свойства клипа, порядок дорожек, оценка времени и продолжение сборки Копирование оформления: Ctrl+Shift+C берёт с выделенного клипа кадрирование, поворот, увеличение, смещение, прозрачность, ключ, затухания и громкость, Ctrl+Shift+V применяет их ко всем выделенным. Вид клипа и текст не переносятся: свойства копируют между разными клипами. Порядок дорожек: слева в заголовке две стрелки, у крайних дорожек соответствующая нарисована тускло и не нажимается. Двойной щелчок по названию переименовывает дорожку — на монтаже из десятка дорожек «карта» и «титры» читаются лучше, чем V1 и Т1. То же есть и в меню по правому щелчку. Ввод имени — своим тёмным окном: системный InputQuery выглядел бы белым пятном. Окно сборки показывает, сколько прошло и сколько примерно осталось. Оценка по пройденной доле; скорость на деле меняется, поэтому «примерно» и пересчёт на каждом шаге. Прерванная сборка продолжается с готовых кусков. Каждый доведённый до конца кусок помечается в списке рядом с ними: одного наличия файла мало — сборку могли прервать посреди записи. Первая строка списка — отпечаток плана; не совпал, значит монтаж менялся, и всё собирается заново. Проверено: четыре куска взяты готовыми, два пересобраны, склейка не потеряла ни одного кадра; при изменённом монтаже готовые куски отвергнуты.
2026-08-31 14:55:19 +03:00
FStartedAt := Now;
FLastFraction := 0;
lblEta.Caption := '';
Нелинейный видеоредактор без перекодирования Куски видео вырезаются и склеиваются копированием потока: сборка ролика занимает время копирования файла, а не время рендера. Композитинга нет принципиально — при перекрытии побеждает клип с верхней дорожки целиком, и картинкой, и звуком. Именно это ограничение и делает сборку копированием возможной. Что внутри: - монтажный стол со своей отрисовкой: дорожки, масштаб, прилипание, схлопывание, громкость на клипе; - предпросмотр прямо с монтажа через libmpv и виртуальный список кусков, без промежуточных файлов; - сборка через ffmpeg с точными резами: перекодируется только огрызок от реза до ближайшего опорного кадра, остальное копируется; - разбор заголовка MP4 для поиска опорных кадров — в 500 раз быстрее опроса ffprobe; - перепаковка контейнеров, кадрирование и поворот, сведения о проекте; - свои цвета всего окна: системные элементы под Windows цвет не берут, поэтому кнопки, полоса меню, журнал и полосы прокрутки нарисованы сами; - окно зависимостей: недостающие ffmpeg, ffprobe и libmpv скачиваются с официальных источников; - кросс-сборка под Windows и работа под Wine. Первый коммит: до этого история не велась.
2026-08-19 18:36:16 +03:00
end;
procedure TProgressForm.SetStage(const AText: string);
begin
lblStage.Caption := AText;
end;
Свойства клипа, порядок дорожек, оценка времени и продолжение сборки Копирование оформления: Ctrl+Shift+C берёт с выделенного клипа кадрирование, поворот, увеличение, смещение, прозрачность, ключ, затухания и громкость, Ctrl+Shift+V применяет их ко всем выделенным. Вид клипа и текст не переносятся: свойства копируют между разными клипами. Порядок дорожек: слева в заголовке две стрелки, у крайних дорожек соответствующая нарисована тускло и не нажимается. Двойной щелчок по названию переименовывает дорожку — на монтаже из десятка дорожек «карта» и «титры» читаются лучше, чем V1 и Т1. То же есть и в меню по правому щелчку. Ввод имени — своим тёмным окном: системный InputQuery выглядел бы белым пятном. Окно сборки показывает, сколько прошло и сколько примерно осталось. Оценка по пройденной доле; скорость на деле меняется, поэтому «примерно» и пересчёт на каждом шаге. Прерванная сборка продолжается с готовых кусков. Каждый доведённый до конца кусок помечается в списке рядом с ними: одного наличия файла мало — сборку могли прервать посреди записи. Первая строка списка — отпечаток плана; не совпал, значит монтаж менялся, и всё собирается заново. Проверено: четыре куска взяты готовыми, два пересобраны, склейка не потеряла ни одного кадра; при изменённом монтаже готовые куски отвергнуты.
2026-08-31 14:55:19 +03:00
{ Время в виде «3 мин 20 с»: секунды сотнями человек не читает. }
function TProgressForm.FormatSpan(const ASeconds: Double): string;
var
Total, M, S: Integer;
begin
Total := Round(ASeconds);
if Total < 0 then
Total := 0;
M := Total div 60;
S := Total mod 60;
if M >= 60 then
Result := Format('%d ч %d мин', [M div 60, M mod 60])
else if M > 0 then
Result := Format('%d мин %d с', [M, S])
else
Result := Format('%d с', [S]);
end;
{ Сколько прошло и сколько осталось.
Осталось считается по простому правилу: если четверть пути заняла
минуту, весь путь займёт четыре. На деле скорость меняется — куски,
которые копируются, идут мгновенно, а те, что пересобираются,
медленно, — поэтому число называется «примерно» и пересчитывается на
каждом шаге. Даже такая оценка отвечает на главный вопрос: успею ли я
сходить за чаем. }
Нелинейный видеоредактор без перекодирования Куски видео вырезаются и склеиваются копированием потока: сборка ролика занимает время копирования файла, а не время рендера. Композитинга нет принципиально — при перекрытии побеждает клип с верхней дорожки целиком, и картинкой, и звуком. Именно это ограничение и делает сборку копированием возможной. Что внутри: - монтажный стол со своей отрисовкой: дорожки, масштаб, прилипание, схлопывание, громкость на клипе; - предпросмотр прямо с монтажа через libmpv и виртуальный список кусков, без промежуточных файлов; - сборка через ffmpeg с точными резами: перекодируется только огрызок от реза до ближайшего опорного кадра, остальное копируется; - разбор заголовка MP4 для поиска опорных кадров — в 500 раз быстрее опроса ffprobe; - перепаковка контейнеров, кадрирование и поворот, сведения о проекте; - свои цвета всего окна: системные элементы под Windows цвет не берут, поэтому кнопки, полоса меню, журнал и полосы прокрутки нарисованы сами; - окно зависимостей: недостающие ffmpeg, ffprobe и libmpv скачиваются с официальных источников; - кросс-сборка под Windows и работа под Wine. Первый коммит: до этого история не велась.
2026-08-19 18:36:16 +03:00
procedure TProgressForm.SetFraction(AValue: Double);
Свойства клипа, порядок дорожек, оценка времени и продолжение сборки Копирование оформления: Ctrl+Shift+C берёт с выделенного клипа кадрирование, поворот, увеличение, смещение, прозрачность, ключ, затухания и громкость, Ctrl+Shift+V применяет их ко всем выделенным. Вид клипа и текст не переносятся: свойства копируют между разными клипами. Порядок дорожек: слева в заголовке две стрелки, у крайних дорожек соответствующая нарисована тускло и не нажимается. Двойной щелчок по названию переименовывает дорожку — на монтаже из десятка дорожек «карта» и «титры» читаются лучше, чем V1 и Т1. То же есть и в меню по правому щелчку. Ввод имени — своим тёмным окном: системный InputQuery выглядел бы белым пятном. Окно сборки показывает, сколько прошло и сколько примерно осталось. Оценка по пройденной доле; скорость на деле меняется, поэтому «примерно» и пересчёт на каждом шаге. Прерванная сборка продолжается с готовых кусков. Каждый доведённый до конца кусок помечается в списке рядом с ними: одного наличия файла мало — сборку могли прервать посреди записи. Первая строка списка — отпечаток плана; не совпал, значит монтаж менялся, и всё собирается заново. Проверено: четыре куска взяты готовыми, два пересобраны, склейка не потеряла ни одного кадра; при изменённом монтаже готовые куски отвергнуты.
2026-08-31 14:55:19 +03:00
var
{ Не Left: так называется свойство формы. }
Elapsed, Remain: Double;
Нелинейный видеоредактор без перекодирования Куски видео вырезаются и склеиваются копированием потока: сборка ролика занимает время копирования файла, а не время рендера. Композитинга нет принципиально — при перекрытии побеждает клип с верхней дорожки целиком, и картинкой, и звуком. Именно это ограничение и делает сборку копированием возможной. Что внутри: - монтажный стол со своей отрисовкой: дорожки, масштаб, прилипание, схлопывание, громкость на клипе; - предпросмотр прямо с монтажа через libmpv и виртуальный список кусков, без промежуточных файлов; - сборка через ffmpeg с точными резами: перекодируется только огрызок от реза до ближайшего опорного кадра, остальное копируется; - разбор заголовка MP4 для поиска опорных кадров — в 500 раз быстрее опроса ffprobe; - перепаковка контейнеров, кадрирование и поворот, сведения о проекте; - свои цвета всего окна: системные элементы под Windows цвет не берут, поэтому кнопки, полоса меню, журнал и полосы прокрутки нарисованы сами; - окно зависимостей: недостающие ffmpeg, ffprobe и libmpv скачиваются с официальных источников; - кросс-сборка под Windows и работа под Wine. Первый коммит: до этого история не велась.
2026-08-19 18:36:16 +03:00
begin
if AValue < 0 then
AValue := 0;
if AValue > 1 then
AValue := 1;
Показатель работы: число и полоса показывают одно и то же Полоса ползла по догадке, а подпись показывала замер — и человек видел полосу, заполненную на девять десятых, рядом с нулём процентов. Что в этот момент происходит, по такой паре понять нельзя. Теперь доля одна на обоих. Берётся она у самого ffmpeg: сборка участка с затуханием идёт минуту и дольше, а «кусок 1 из 1» всё это время не меняется, поэтому ffmpeg спрашивают ключом -progress, докуда он дошёл. Пока он не ответил ни разу, полоса трогается с места на пару процентов и там стоит — пустая полоса и есть правда о только что начатой работе. Догадка заодно перестала закрывать промежуток до вехи целиком: предел — девять десятых, остаток виден глазом. Проверка на это добавлена в tests/progress. Полоса в окне сборки была системной, и под gtk2 заполнялась ступенями по восемь кусков на ширину. Теперь там та же своя полоса, что и внизу главного окна, — заполняется сплошь. Чтобы она читалась из файла формы, у неё опубликованы Anchors, Align и Visible: читатель формы берёт только опубликованные свойства, и без этого окно падало при открытии. Проверено глазами на невидимом экране: «Собираю наложение 1 из 1 — 2%» при полосе в 2%, через четыре секунды 69% при полосе в 69%.
2026-10-01 15:50:10 +03:00
pbBar.Fraction := AValue;
Свойства клипа, порядок дорожек, оценка времени и продолжение сборки Копирование оформления: Ctrl+Shift+C берёт с выделенного клипа кадрирование, поворот, увеличение, смещение, прозрачность, ключ, затухания и громкость, Ctrl+Shift+V применяет их ко всем выделенным. Вид клипа и текст не переносятся: свойства копируют между разными клипами. Порядок дорожек: слева в заголовке две стрелки, у крайних дорожек соответствующая нарисована тускло и не нажимается. Двойной щелчок по названию переименовывает дорожку — на монтаже из десятка дорожек «карта» и «титры» читаются лучше, чем V1 и Т1. То же есть и в меню по правому щелчку. Ввод имени — своим тёмным окном: системный InputQuery выглядел бы белым пятном. Окно сборки показывает, сколько прошло и сколько примерно осталось. Оценка по пройденной доле; скорость на деле меняется, поэтому «примерно» и пересчёт на каждом шаге. Прерванная сборка продолжается с готовых кусков. Каждый доведённый до конца кусок помечается в списке рядом с ними: одного наличия файла мало — сборку могли прервать посреди записи. Первая строка списка — отпечаток плана; не совпал, значит монтаж менялся, и всё собирается заново. Проверено: четыре куска взяты готовыми, два пересобраны, склейка не потеряла ни одного кадра; при изменённом монтаже готовые куски отвергнуты.
2026-08-31 14:55:19 +03:00
FLastFraction := AValue;
Elapsed := (Now - FStartedAt) * SecsPerDay;
{ Пока сделано меньше сотой доли, оценка была бы гаданием: первые
секунды уходят на запуск ffmpeg, а не на работу. }
if (AValue > 0.01) and (Elapsed > 1) then
begin
Remain := Elapsed * (1 - AValue) / AValue;
lblEta.Caption := Format('Прошло %s, осталось примерно %s (%d%%)',
[FormatSpan(Elapsed), FormatSpan(Remain), Round(AValue * 100)]);
end
else
lblEta.Caption := 'Прошло ' + FormatSpan(Elapsed);
Нелинейный видеоредактор без перекодирования Куски видео вырезаются и склеиваются копированием потока: сборка ролика занимает время копирования файла, а не время рендера. Композитинга нет принципиально — при перекрытии побеждает клип с верхней дорожки целиком, и картинкой, и звуком. Именно это ограничение и делает сборку копированием возможной. Что внутри: - монтажный стол со своей отрисовкой: дорожки, масштаб, прилипание, схлопывание, громкость на клипе; - предпросмотр прямо с монтажа через libmpv и виртуальный список кусков, без промежуточных файлов; - сборка через ffmpeg с точными резами: перекодируется только огрызок от реза до ближайшего опорного кадра, остальное копируется; - разбор заголовка MP4 для поиска опорных кадров — в 500 раз быстрее опроса ffprobe; - перепаковка контейнеров, кадрирование и поворот, сведения о проекте; - свои цвета всего окна: системные элементы под Windows цвет не берут, поэтому кнопки, полоса меню, журнал и полосы прокрутки нарисованы сами; - окно зависимостей: недостающие ffmpeg, ffprobe и libmpv скачиваются с официальных источников; - кросс-сборка под Windows и работа под Wine. Первый коммит: до этого история не велась.
2026-08-19 18:36:16 +03:00
end;
procedure TProgressForm.AddLog(const AText: string);
begin
Затухания видны и настраиваются, сборка с перекодированием, свой журнал в окне сборки Затухания. Механика была написана давно и работала в сборке, но увидеть или задать её было нечем. Теперь у клипа два верхних угла — ручки: левая тянет появление, правая уход. Взятое затухание рисуется срезанным углом, так это устроено в монтажных программах. Ручки перехватывают нажатие раньше растягивания за край: они мелкие, промахнуться мимо них легче, а взяться за край можно ниже. Перекрытие двух клипов одной дорожки — это переход, и он теперь помечен косым крестом во всю высоту. Раньше о нём можно было узнать только по предупреждению перед сборкой. Сборка с перекодированием. Отдельный пункт меню и отдельное окно: размер кадра от 720p до 4K, поток в килобитах, кодек HEVC или H.264. Перекодирование идёт одним проходом на весь ролик — пересобирать куски по отдельности нельзя, на стыках была бы видна смена качества. Кодирование на видеокарте, и распаковка тоже: замерено на паре кусков 2688x1512 — 9.18 с на процессоре против 1.77 с с аппаратной распаковкой, впятеро. Полностью карточный путь через scale_cuda оказался медленнее (5.74 с) и не взят. Если аппаратная распаковка не пойдёт, сборка повторяется без неё: медленно лучше, чем никак. Окно честно предупреждает, когда аппаратного кодировщика в ffmpeg нет вовсе. Журнал в окне сборки заменён на свой: у системного поля оставались светлые полосы прокрутки и не работала прокрутка вбок с Shift. Это было последнее такое место.
2026-08-21 18:11:59 +03:00
{ Свой журнал сам держится конца, пока пользователь не отмотал назад, и
сам обрезает старые строки. }
memoLog.Add(AText);
Нелинейный видеоредактор без перекодирования Куски видео вырезаются и склеиваются копированием потока: сборка ролика занимает время копирования файла, а не время рендера. Композитинга нет принципиально — при перекрытии побеждает клип с верхней дорожки целиком, и картинкой, и звуком. Именно это ограничение и делает сборку копированием возможной. Что внутри: - монтажный стол со своей отрисовкой: дорожки, масштаб, прилипание, схлопывание, громкость на клипе; - предпросмотр прямо с монтажа через libmpv и виртуальный список кусков, без промежуточных файлов; - сборка через ffmpeg с точными резами: перекодируется только огрызок от реза до ближайшего опорного кадра, остальное копируется; - разбор заголовка MP4 для поиска опорных кадров — в 500 раз быстрее опроса ffprobe; - перепаковка контейнеров, кадрирование и поворот, сведения о проекте; - свои цвета всего окна: системные элементы под Windows цвет не берут, поэтому кнопки, полоса меню, журнал и полосы прокрутки нарисованы сами; - окно зависимостей: недостающие ffmpeg, ffprobe и libmpv скачиваются с официальных источников; - кросс-сборка под Windows и работа под Wine. Первый коммит: до этого история не велась.
2026-08-19 18:36:16 +03:00
end;
procedure TProgressForm.Finish(ASuccess: Boolean; const AMessage: string);
begin
FFinished := True;
btnAction.Caption := 'Закрыть';
lblStage.Caption := AMessage;
Свойства клипа, порядок дорожек, оценка времени и продолжение сборки Копирование оформления: Ctrl+Shift+C берёт с выделенного клипа кадрирование, поворот, увеличение, смещение, прозрачность, ключ, затухания и громкость, Ctrl+Shift+V применяет их ко всем выделенным. Вид клипа и текст не переносятся: свойства копируют между разными клипами. Порядок дорожек: слева в заголовке две стрелки, у крайних дорожек соответствующая нарисована тускло и не нажимается. Двойной щелчок по названию переименовывает дорожку — на монтаже из десятка дорожек «карта» и «титры» читаются лучше, чем V1 и Т1. То же есть и в меню по правому щелчку. Ввод имени — своим тёмным окном: системный InputQuery выглядел бы белым пятном. Окно сборки показывает, сколько прошло и сколько примерно осталось. Оценка по пройденной доле; скорость на деле меняется, поэтому «примерно» и пересчёт на каждом шаге. Прерванная сборка продолжается с готовых кусков. Каждый доведённый до конца кусок помечается в списке рядом с ними: одного наличия файла мало — сборку могли прервать посреди записи. Первая строка списка — отпечаток плана; не совпал, значит монтаж менялся, и всё собирается заново. Проверено: четыре куска взяты готовыми, два пересобраны, склейка не потеряла ни одного кадра; при изменённом монтаже готовые куски отвергнуты.
2026-08-31 14:55:19 +03:00
{ На месте оценки — итог: сколько всё это заняло. }
lblEta.Caption := 'Заняло ' + FormatSpan((Now - FStartedAt) * SecsPerDay);
Нелинейный видеоредактор без перекодирования Куски видео вырезаются и склеиваются копированием потока: сборка ролика занимает время копирования файла, а не время рендера. Композитинга нет принципиально — при перекрытии побеждает клип с верхней дорожки целиком, и картинкой, и звуком. Именно это ограничение и делает сборку копированием возможной. Что внутри: - монтажный стол со своей отрисовкой: дорожки, масштаб, прилипание, схлопывание, громкость на клипе; - предпросмотр прямо с монтажа через libmpv и виртуальный список кусков, без промежуточных файлов; - сборка через ffmpeg с точными резами: перекодируется только огрызок от реза до ближайшего опорного кадра, остальное копируется; - разбор заголовка MP4 для поиска опорных кадров — в 500 раз быстрее опроса ffprobe; - перепаковка контейнеров, кадрирование и поворот, сведения о проекте; - свои цвета всего окна: системные элементы под Windows цвет не берут, поэтому кнопки, полоса меню, журнал и полосы прокрутки нарисованы сами; - окно зависимостей: недостающие ffmpeg, ffprobe и libmpv скачиваются с официальных источников; - кросс-сборка под Windows и работа под Wine. Первый коммит: до этого история не велась.
2026-08-19 18:36:16 +03:00
if ASuccess then
lblStage.Font.Color := clDefault
else
lblStage.Font.Color := clRed;
end;
procedure TProgressForm.btnActionClick(Sender: TObject);
begin
if FFinished then
begin
Close;
Exit;
end;
{ Повторное нажатие ничего не даёт: остановка не мгновенна, надо
дождаться, пока ffmpeg завершится. }
if FCancelRequested then
Exit;
FCancelRequested := True;
btnAction.Enabled := False;
lblStage.Caption := 'Останавливаю...';
if Assigned(FOnCancelRequest) then
FOnCancelRequest(Self);
end;
procedure TProgressForm.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
{ Пока работа идёт, закрытие окна означало бы оставить ffmpeg работать
без всякого присмотра. Вместо этого запрашиваем остановку. }
CanClose := FFinished;
if not CanClose then
btnActionClick(nil);
end;
end.