Отмена генерации не ошибка, длинная тишина набирается повторами
Отмену вставок просили мы сами, когда правка сделала работу ненужной, а журнал сообщал «Не удалось подготовить вставки: Отменено» — неправда там, где всё шло по плану. Теперь отмена докладывается как отмена и сразу планирует пересборку предпросмотра, а не ждёт таймера. Вчерашнее дробление дыр не дошло до звуковых дорожек: они уплощаются отдельной функцией. Кусок тишины в три минуты ссылался на минутный файл, и плеер жаловался «uses 192.5 seconds, but file has only 60». Теперь длинная тишина набирается повторами, а одинаковые файлы не заказываются дважды. Проверено живьём на материале 2688x1512: отмена ловится, обе строки в журнале верные, предупреждений о коротких файлах ноль. Проверка 15 в flattest следит за дроблением тишины.
This commit is contained in:
parent
8258de7145
commit
00af5e1eec
4 changed files with 88 additions and 26 deletions
|
|
@ -119,15 +119,6 @@ NVENC, если он есть). Это разрозненно и не даёт
|
|||
неподъёмным. Пока цифры замеряны только на одной машине, у человека
|
||||
должна быть возможность выключить любую из этих трат.
|
||||
|
||||
## Отмена ненужной генерации не проверена живьём
|
||||
|
||||
Правка монтажа прекращает создание вставок, ставших ненужными, — код на
|
||||
месте и вызывается на каждой пересборке предпросмотра. Но поймать отмену
|
||||
глазами не на чем: на мелком проверочном материале минутная чёрная
|
||||
вставка делается мгновенно. Нужен прогон на настоящем материале в
|
||||
2688x1512: завести дыру, дождаться начала генерации, закрыть дыру и
|
||||
убедиться по журналу, что ffmpeg остановлен.
|
||||
|
||||
## Мелочи, до которых не дошли руки
|
||||
|
||||
**Вид дорожки не виден в её заголовке.** Дорожки картинки, звука и текста
|
||||
|
|
|
|||
|
|
@ -1043,28 +1043,54 @@ var
|
|||
Req: TGenRequest;
|
||||
Path: string;
|
||||
|
||||
{ Уже заказан ли такой файл. }
|
||||
function Requested(const APath: string): Boolean;
|
||||
var
|
||||
K: Integer;
|
||||
begin
|
||||
Result := False;
|
||||
for K := 0 to High(AMissing) do
|
||||
if AMissing[K].TargetPath = APath then
|
||||
Exit(True);
|
||||
end;
|
||||
|
||||
{ Кусок тишины. Длинный набирается повторами минутного файла — как и
|
||||
чёрные вставки: готовых длин всего две, и просить у минутного файла
|
||||
три минуты нельзя, плеер на это ругается, а звук обрывается. }
|
||||
procedure PushSilence(const ALen: Double);
|
||||
var
|
||||
Left, Take: Double;
|
||||
begin
|
||||
if ALen <= 0.0005 then
|
||||
Exit;
|
||||
Seg := Default(TFlatSegment);
|
||||
Seg.Volume := 1;
|
||||
Seg.Kind := skBlack;
|
||||
Seg.Duration := ALen;
|
||||
{ Тишина без картинки: см. пояснение у gkSilence. }
|
||||
Req.Kind := gkSilence;
|
||||
Req.SourcePath := '';
|
||||
Req.Duration := BucketFor(ALen);
|
||||
Req.TargetPath := GeneratedPath(AProject.CacheDir, Req);
|
||||
Seg.FilePath := Req.TargetPath;
|
||||
if not FileExists(Req.TargetPath) then
|
||||
|
||||
Left := ALen;
|
||||
while Left > 0.0005 do
|
||||
begin
|
||||
SetLength(AMissing, Length(AMissing) + 1);
|
||||
AMissing[High(AMissing)] := Req;
|
||||
Take := Min(MaxInsertLength, Left);
|
||||
Seg := Default(TFlatSegment);
|
||||
Seg.Volume := 1;
|
||||
Seg.Kind := skBlack;
|
||||
Seg.Duration := Take;
|
||||
{ Тишина без картинки: см. пояснение у gkSilence. }
|
||||
Req.Kind := gkSilence;
|
||||
Req.SourcePath := '';
|
||||
Req.Duration := BucketFor(Take);
|
||||
Req.TargetPath := GeneratedPath(AProject.CacheDir, Req);
|
||||
Seg.FilePath := Req.TargetPath;
|
||||
{ Один и тот же файл не заказываем дважды: длинная тишина набирается
|
||||
повторами, и без этой проверки минутный кусок делался бы столько
|
||||
раз, сколько его повторов. }
|
||||
if (not FileExists(Req.TargetPath)) and (not Requested(Req.TargetPath)) then
|
||||
begin
|
||||
SetLength(AMissing, Length(AMissing) + 1);
|
||||
AMissing[High(AMissing)] := Req;
|
||||
end;
|
||||
SetLength(ASegments, N + 1);
|
||||
ASegments[N] := Seg;
|
||||
Inc(N);
|
||||
Left := Left - Take;
|
||||
end;
|
||||
SetLength(ASegments, N + 1);
|
||||
ASegments[N] := Seg;
|
||||
Inc(N);
|
||||
end;
|
||||
|
||||
begin
|
||||
|
|
|
|||
|
|
@ -3098,14 +3098,26 @@ end;
|
|||
|
||||
procedure TMainForm.GenerateDone(Sender: TObject);
|
||||
var
|
||||
Ok: Boolean;
|
||||
Ok, WasCancelled: Boolean;
|
||||
Msg: string;
|
||||
begin
|
||||
Ok := FGenerate.Succeeded;
|
||||
WasCancelled := FGenerate.Cancelled;
|
||||
Msg := FGenerate.Message;
|
||||
FGenerate := nil;
|
||||
FGenerateBusy := False;
|
||||
|
||||
{ Отмену просили мы сами, когда правка сделала работу ненужной. Это не
|
||||
беда, и говорить «не удалось» тут нельзя: в журнале появлялась строка
|
||||
об ошибке там, где всё шло по плану. Пересобираем предпросмотр по
|
||||
свежей расстановке. }
|
||||
if WasCancelled then
|
||||
begin
|
||||
Log('Подготовка вставок прекращена: расстановка изменилась.');
|
||||
SchedulePreview;
|
||||
Exit;
|
||||
end;
|
||||
|
||||
if not Ok then
|
||||
begin
|
||||
Log('Не удалось подготовить вставки: ' + Msg);
|
||||
|
|
|
|||
|
|
@ -971,6 +971,39 @@ begin
|
|||
end;
|
||||
WriteLn;
|
||||
|
||||
{ --- 15. Длинная тишина тоже набирается повторами --- }
|
||||
WriteLn(' 15. Дыра на звуковой дорожке');
|
||||
Proj := MakeProject(1, Media);
|
||||
try
|
||||
Proj.Master := Media.Info;
|
||||
Proj.EnsureAudioTracks;
|
||||
{ Два звуковых клипа с промежутком в семьдесят секунд: он разложится
|
||||
на минуту и десять секунд, то есть на два разных файла. }
|
||||
Clip := Proj.AddClip(Proj.Tracks[1], Media, 0, 5, 0);
|
||||
Clip.Kind := ckAudio;
|
||||
Clip := Proj.AddClip(Proj.Tracks[1], Media, 10, 5, 75);
|
||||
Clip.Kind := ckAudio;
|
||||
|
||||
FlattenAudioTrack(Proj, Proj.Tracks[1], 80, Segs, Missing);
|
||||
DumpSegments(Segs);
|
||||
|
||||
N := 0;
|
||||
for I := 0 to High(Segs) do
|
||||
if Segs[I].Kind = skBlack then
|
||||
begin
|
||||
Inc(N);
|
||||
Check(Segs[I].Duration <= 60.0005,
|
||||
'кусок тишины не длиннее минуты: ' + SecondsToStr(Segs[I].Duration));
|
||||
end;
|
||||
Check(N = 2, 'тишина разложена на два куска: ' + IntToStr(N));
|
||||
Check(Length(Missing) = 2,
|
||||
'заказаны две длины, минутная и пятнадцатисекундная: ' +
|
||||
IntToStr(Length(Missing)));
|
||||
finally
|
||||
Proj.Free;
|
||||
end;
|
||||
WriteLn;
|
||||
|
||||
WriteLn;
|
||||
if FailCount = 0 then
|
||||
begin
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue