Вставки тишины для звука делаются без картинки
Звук пропадал кусками, и причина оказалась не в громкости и не в раскладке дорожек: обе были верны. Дыры на звуковой дорожке заполнялись тем же чёрным клипом, что и дыры на видеодорожке, а опорные кадры в нём стоят через 4.171 с. Перемотка внутри такой вставки откатывается к ближайшему опорному кадру, дорожка начинает отдавать звук на несколько секунд раньше соседних, смешивание равняется по ней — и содержимое соседней дорожки в это окно не попадает. Замерено на файле, без запуска окна. Смешивание трёх дорожек проекта: старт 0 с: -23.3 dB старт 24 с: -91.0 dB (полная тишина) старт 12 с: -10.1 dB старт 30 с: -18.0 dB При этом та же дорожка A2 отдельно на 24-й секунде даёт -11.7 dB, то есть содержимое на месте. Смешивание A2 с A4 работает, A1 с A2 — нет: у A1 в этой точке идёт длинная чёрная вставка, и перемотка в ней откатывается на 3.1 с назад. Теперь у звуковых дорожек своя вставка — anullsrc в звуковом кодеке проекта, без видеопотока. В звуке опорным является каждый кадр, и отката нет. После правки во всех проверенных точках звук есть: 0 с -24.1 7 с -19.0 12 с -11.9 18 с -17.5 24 с -11.7 25 с -9.6 30 с -9.5 40 с -15.6 60 с -19.5 72 с -15.9 Сборка ролика от этого не страдает: она декодирует куски в отсчёты, и файл без картинки ей подходит так же. Заодно в служебную программу добавлена команда audio: раскладка звуковых дорожек проекта на куски вместе со строками edl://. Ею это и было найдено.
This commit is contained in:
parent
11075d6b52
commit
ad88683e8b
4 changed files with 141 additions and 2 deletions
|
|
@ -23,6 +23,9 @@
|
|||
render <проект.nlve> <выход>
|
||||
уплотить проект, создать вставки, собрать ролик
|
||||
и сверить число кадров
|
||||
audio <проект.nlve>
|
||||
разложить звуковые дорожки проекта на куски и
|
||||
напечатать их вместе со строками edl://
|
||||
buildcut <проект.nlve> <видео>
|
||||
проект из одного файла с точным резом в заведомо
|
||||
неопорной точке
|
||||
|
|
@ -858,6 +861,85 @@ begin
|
|||
WriteLn(' ', FThread.PendingLog);
|
||||
end;
|
||||
|
||||
|
||||
{ Раскладка звуковых дорожек.
|
||||
|
||||
Нужна потому, что «звука нет вот здесь» глазами не разобрать: громкость
|
||||
может быть верной, а кусок в этом месте — ссылаться не туда. Здесь
|
||||
печатается ровно то, что уходит в плеер: место на монтаже, файл, место
|
||||
в файле, длина. }
|
||||
procedure CmdAudio;
|
||||
var
|
||||
Proj: TProject;
|
||||
Segs: TFlatSegmentArray;
|
||||
Missing: TGenRequests;
|
||||
Err: string;
|
||||
I, J: Integer;
|
||||
Total, At: Double;
|
||||
Kind: string;
|
||||
begin
|
||||
Proj := TProject.Create;
|
||||
try
|
||||
if not Proj.LoadFromFile(ExpandFileName(ParamStr(2)), Err) then
|
||||
begin
|
||||
WriteLn('Не удалось прочитать проект: ', Err);
|
||||
Halt(1);
|
||||
end;
|
||||
|
||||
Total := Max(AudibleEnd(Proj, tkVideo), AudibleEnd(Proj, tkAudio));
|
||||
WriteLn('проект: ', Proj.FileName);
|
||||
WriteLn('длина слышимого: ', SecondsToStr(Total), ' с');
|
||||
WriteLn;
|
||||
|
||||
for I := 0 to Proj.TrackCount - 1 do
|
||||
begin
|
||||
if Proj.Tracks[I].Kind <> tkAudio then
|
||||
Continue;
|
||||
WriteLn('=== ', Proj.Tracks[I].Name, ' ===');
|
||||
if not Proj.TrackAudible(Proj.Tracks[I]) then
|
||||
begin
|
||||
WriteLn(' не слышна (заглушена или пуста)');
|
||||
WriteLn;
|
||||
Continue;
|
||||
end;
|
||||
if Proj.Tracks[I].Count = 0 then
|
||||
begin
|
||||
WriteLn(' клипов нет');
|
||||
WriteLn;
|
||||
Continue;
|
||||
end;
|
||||
if not FlattenAudioTrack(Proj, Proj.Tracks[I], Total, Segs, Missing) then
|
||||
begin
|
||||
WriteLn(' разложить не удалось');
|
||||
WriteLn;
|
||||
Continue;
|
||||
end;
|
||||
|
||||
At := 0;
|
||||
for J := 0 to High(Segs) do
|
||||
begin
|
||||
if Segs[J].Kind = skBlack then
|
||||
Kind := 'тишина'
|
||||
else
|
||||
Kind := 'звук ';
|
||||
WriteLn(Format(' [%2d] %s монтаж %8s..%8s длина %8s из %8s %s',
|
||||
[J, Kind, SecondsToStr(At), SecondsToStr(At + Segs[J].Duration),
|
||||
SecondsToStr(Segs[J].Duration), SecondsToStr(Segs[J].SrcStart),
|
||||
ExtractFileName(Segs[J].FilePath)]));
|
||||
if (Segs[J].Kind = skBlack) and (not FileExists(Segs[J].FilePath)) then
|
||||
WriteLn(' ВНИМАНИЕ: вставки тишины нет на диске');
|
||||
At := At + Segs[J].Duration;
|
||||
end;
|
||||
WriteLn(' всего по дорожке: ', SecondsToStr(At), ' с');
|
||||
WriteLn;
|
||||
WriteLn(' ', BuildEdlUri(Segs));
|
||||
WriteLn;
|
||||
end;
|
||||
finally
|
||||
Proj.Free;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure CmdRender;
|
||||
var
|
||||
Proj: TProject;
|
||||
|
|
@ -999,6 +1081,8 @@ begin
|
|||
CmdBuild
|
||||
else if (Cmd = 'buildcut') and (ParamCount >= 3) then
|
||||
CmdBuildCut
|
||||
else if (Cmd = 'audio') and (ParamCount >= 2) then
|
||||
CmdAudio
|
||||
else if (Cmd = 'render') and (ParamCount >= 3) then
|
||||
CmdRender
|
||||
else
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue