Implement extend to previous / next subtitle with chaining gap

This commit is contained in:
Martijn van Berkel (Flitskikker) 2023-07-12 20:05:59 +02:00
parent 9763fcf1bf
commit 0890efa91b
3 changed files with 134 additions and 25 deletions

View File

@ -1,9 +1,11 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using Nikse.SubtitleEdit.Core.Forms;
using Nikse.SubtitleEdit.Core.SubtitleFormats;
namespace Nikse.SubtitleEdit.Core.Common
{
@ -99,5 +101,40 @@ namespace Nikse.SubtitleEdit.Core.Common
{
return GetNextShotChangeInMs(shotChanges, currentTime) - TimeCodesBeautifierUtils.GetOutCuesGapMs();
}
public static double? GetClosestShotChangeInMs(List<double> shotChanges, TimeCode currentTime)
{
try
{
return shotChanges.Aggregate((x, y) => Math.Abs(x - currentTime.TotalSeconds) < Math.Abs(y - currentTime.TotalSeconds) ? x : y);
}
catch (InvalidOperationException)
{
return null;
}
}
public static bool IsCueOnShotChange(List<double> shotChanges, TimeCode currentTime, bool isInCue)
{
var closestShotChange = GetClosestShotChangeInMs(shotChanges, currentTime);
if (closestShotChange != null)
{
var currentFrame = SubtitleFormat.MillisecondsToFrames(currentTime.TotalSeconds * 1000);
var closestShotChangeFrame = SubtitleFormat.MillisecondsToFrames(closestShotChange.Value * 1000);
if (isInCue)
{
return currentFrame >= closestShotChangeFrame && currentFrame <= closestShotChangeFrame + Configuration.Settings.BeautifyTimeCodes.Profile.InCuesGap;
}
else
{
return currentFrame <= closestShotChangeFrame && currentFrame >= closestShotChangeFrame - Configuration.Settings.BeautifyTimeCodes.Profile.OutCuesGap;
}
}
else
{
return false;
}
}
}
}

View File

@ -487,26 +487,6 @@ namespace Nikse.SubtitleEdit.Core.Forms
return true;
}
private bool IsCueOnShotChange(int cueFrame, bool isInCue)
{
var closestShotChangeFrame = GetClosestShotChangeFrame(cueFrame);
if (closestShotChangeFrame != null)
{
if (isInCue)
{
return cueFrame >= closestShotChangeFrame.Value && cueFrame <= closestShotChangeFrame.Value + Configuration.Settings.BeautifyTimeCodes.Profile.InCuesGap;
}
else
{
return cueFrame <= closestShotChangeFrame.Value && cueFrame >= closestShotChangeFrame.Value - Configuration.Settings.BeautifyTimeCodes.Profile.OutCuesGap;
}
}
else
{
return false;
}
}
private int? GetFixedChainableSubtitlesLeftOutCueFrameGeneral(int leftOutCueFrame, int rightInCueFrame, Paragraph leftParagraph = null, Paragraph rightParagraph = null)
{
// Check if zones are being used
@ -852,6 +832,26 @@ namespace Nikse.SubtitleEdit.Core.Forms
}
}
private bool IsCueOnShotChange(int cueFrame, bool isInCue)
{
var closestShotChangeFrame = GetClosestShotChangeFrame(cueFrame);
if (closestShotChangeFrame != null)
{
if (isInCue)
{
return cueFrame >= closestShotChangeFrame.Value && cueFrame <= closestShotChangeFrame.Value + Configuration.Settings.BeautifyTimeCodes.Profile.InCuesGap;
}
else
{
return cueFrame <= closestShotChangeFrame.Value && cueFrame >= closestShotChangeFrame.Value - Configuration.Settings.BeautifyTimeCodes.Profile.OutCuesGap;
}
}
else
{
return false;
}
}
// Delegates

View File

@ -18369,6 +18369,32 @@ namespace Nikse.SubtitleEdit.Forms
private void ExtendSelectedLinesToNextLine(bool minusChainingGap = false)
{
double GetNextStartTimeMinusChainingGap(Paragraph next)
{
if (ShotChangeHelper.IsCueOnShotChange(audioVisualizer.ShotChanges, next.StartTime, true))
{
if (Configuration.Settings.BeautifyTimeCodes.Profile.ChainingInCueOnShotUseZones)
{
return next.StartTime.TotalMilliseconds - SubtitleFormat.FramesToMilliseconds(Configuration.Settings.BeautifyTimeCodes.Profile.ChainingInCueOnShotLeftGreenZone);
}
else
{
return next.StartTime.TotalMilliseconds - Configuration.Settings.BeautifyTimeCodes.Profile.ChainingInCueOnShotMaxGap;
}
}
else
{
if (Configuration.Settings.BeautifyTimeCodes.Profile.ChainingGeneralUseZones)
{
return next.StartTime.TotalMilliseconds - SubtitleFormat.FramesToMilliseconds(Configuration.Settings.BeautifyTimeCodes.Profile.ChainingGeneralLeftGreenZone);
}
else
{
return next.StartTime.TotalMilliseconds - Configuration.Settings.BeautifyTimeCodes.Profile.ChainingGeneralMaxGap;
}
}
}
var historyAdded = false;
foreach (ListViewItem selectedItem in SubtitleListview1.SelectedItems)
{
@ -18385,12 +18411,17 @@ namespace Nikse.SubtitleEdit.Forms
if (minusChainingGap)
{
// TODO chaining gap
p.EndTime.TotalMilliseconds = GetNextStartTimeMinusChainingGap(next);
}
else
{
p.EndTime.TotalMilliseconds = next.StartTime.TotalMilliseconds - MinGapBetweenLines;
}
if (p.Duration.TotalMilliseconds < 0)
{
p.EndTime.TotalMilliseconds = p.StartTime.TotalMilliseconds;
}
}
if (IsOriginalEditable)
@ -18409,12 +18440,17 @@ namespace Nikse.SubtitleEdit.Forms
if (minusChainingGap)
{
// TODO chaining gap
original.EndTime.TotalMilliseconds = GetNextStartTimeMinusChainingGap(originalNext);
}
else
{
original.EndTime.TotalMilliseconds = originalNext.StartTime.TotalMilliseconds - MinGapBetweenLines;
}
if (original.Duration.TotalMilliseconds < 0)
{
original.EndTime.TotalMilliseconds = original.StartTime.TotalMilliseconds;
}
}
}
}
@ -18425,6 +18461,32 @@ namespace Nikse.SubtitleEdit.Forms
private void ExtendSelectedLinesToPreviousLine(bool minusChainingGap = false)
{
double GetPreviousEndTimePlusChainingGap(Paragraph previous)
{
if (ShotChangeHelper.IsCueOnShotChange(audioVisualizer.ShotChanges, previous.EndTime, false))
{
if (Configuration.Settings.BeautifyTimeCodes.Profile.ChainingOutCueOnShotUseZones)
{
return previous.EndTime.TotalMilliseconds + SubtitleFormat.FramesToMilliseconds(Configuration.Settings.BeautifyTimeCodes.Profile.ChainingOutCueOnShotRightGreenZone);
}
else
{
return previous.EndTime.TotalMilliseconds + Configuration.Settings.BeautifyTimeCodes.Profile.ChainingOutCueOnShotMaxGap;
}
}
else
{
if (Configuration.Settings.BeautifyTimeCodes.Profile.ChainingGeneralUseZones)
{
return previous.EndTime.TotalMilliseconds + SubtitleFormat.FramesToMilliseconds(Configuration.Settings.BeautifyTimeCodes.Profile.ChainingGeneralLeftGreenZone);
}
else
{
return previous.EndTime.TotalMilliseconds + Configuration.Settings.BeautifyTimeCodes.Profile.ChainingGeneralMaxGap;
}
}
}
var historyAdded = false;
foreach (ListViewItem selectedItem in SubtitleListview1.SelectedItems)
{
@ -18449,12 +18511,17 @@ namespace Nikse.SubtitleEdit.Forms
if (minusChainingGap)
{
// TODO chaining gap
original.StartTime.TotalMilliseconds = GetPreviousEndTimePlusChainingGap(originalPrevious);
}
else
{
original.StartTime.TotalMilliseconds = originalPrevious.EndTime.TotalMilliseconds + MinGapBetweenLines;
}
if (original.Duration.TotalMilliseconds < 0)
{
original.StartTime.TotalMilliseconds = original.EndTime.TotalMilliseconds;
}
}
}
}
@ -18467,12 +18534,17 @@ namespace Nikse.SubtitleEdit.Forms
if (minusChainingGap)
{
// TODO chaining gap
p.StartTime.TotalMilliseconds = GetPreviousEndTimePlusChainingGap(previous);
}
else
{
p.StartTime.TotalMilliseconds = previous.EndTime.TotalMilliseconds + MinGapBetweenLines;
}
if (p.Duration.TotalMilliseconds < 0)
{
p.StartTime.TotalMilliseconds = p.EndTime.TotalMilliseconds;
}
}
RefreshSelectedParagraphs();