mirror of
https://github.com/SubtitleEdit/subtitleedit.git
synced 2024-11-22 11:12:36 +01:00
Implement adjusting functions
This commit is contained in:
parent
198954b175
commit
db6b8af630
@ -1,6 +1,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.Common
|
||||
@ -72,5 +73,15 @@ namespace Nikse.SubtitleEdit.Core.Common
|
||||
File.Delete(shotChangesFileName);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Util functions
|
||||
|
||||
public static double GetNextShotChangeMinusGapInMs(List<double> shotChanges, TimeCode currentTime)
|
||||
{
|
||||
var nextShotChangeInSeconds = shotChanges.Concat(new[] { double.MaxValue }).First(x => x >= currentTime.TotalSeconds); // will return maxValue if empty
|
||||
var outCueGapInMs = (TimeCode.BaseUnit / Configuration.Settings.General.CurrentFrameRate) * Configuration.Settings.BeautifyTimeCodes.Profile.OutCuesGap;
|
||||
return (nextShotChangeInSeconds * 1000) - outCueGapInMs;
|
||||
}
|
||||
}
|
||||
}
|
@ -393,7 +393,7 @@ namespace Nikse.SubtitleEdit.Core.Common
|
||||
}
|
||||
}
|
||||
|
||||
public void AdjustDisplayTimeUsingPercent(double percent, List<int> selectedIndexes)
|
||||
public void AdjustDisplayTimeUsingPercent(double percent, List<int> selectedIndexes, List<double> shotChanges = null)
|
||||
{
|
||||
for (int i = 0; i < Paragraphs.Count; i++)
|
||||
{
|
||||
@ -412,6 +412,15 @@ namespace Nikse.SubtitleEdit.Core.Common
|
||||
newEndMilliseconds = nextStartMilliseconds - Configuration.Settings.General.MinimumMillisecondsBetweenLines;
|
||||
}
|
||||
|
||||
if (shotChanges != null)
|
||||
{
|
||||
double nextShotChangeMilliseconds = ShotChangeHelper.GetNextShotChangeMinusGapInMs(shotChanges, Paragraphs[i].EndTime);
|
||||
if (newEndMilliseconds > nextShotChangeMilliseconds)
|
||||
{
|
||||
newEndMilliseconds = nextShotChangeMilliseconds;
|
||||
}
|
||||
}
|
||||
|
||||
if (percent > 100 && newEndMilliseconds > Paragraphs[i].EndTime.TotalMilliseconds || percent < 100)
|
||||
{
|
||||
Paragraphs[i].EndTime.TotalMilliseconds = newEndMilliseconds;
|
||||
@ -420,7 +429,7 @@ namespace Nikse.SubtitleEdit.Core.Common
|
||||
}
|
||||
}
|
||||
|
||||
public void AdjustDisplayTimeUsingSeconds(double seconds, List<int> selectedIndexes)
|
||||
public void AdjustDisplayTimeUsingSeconds(double seconds, List<int> selectedIndexes, List<double> shotChanges = null)
|
||||
{
|
||||
if (Math.Abs(seconds) < 0.001)
|
||||
{
|
||||
@ -432,19 +441,19 @@ namespace Nikse.SubtitleEdit.Core.Common
|
||||
{
|
||||
foreach (var idx in selectedIndexes)
|
||||
{
|
||||
AdjustDisplayTimeUsingMilliseconds(idx, adjustMs);
|
||||
AdjustDisplayTimeUsingMilliseconds(idx, adjustMs, shotChanges);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int idx = 0; idx < Paragraphs.Count; idx++)
|
||||
{
|
||||
AdjustDisplayTimeUsingMilliseconds(idx, adjustMs);
|
||||
AdjustDisplayTimeUsingMilliseconds(idx, adjustMs, shotChanges);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void AdjustDisplayTimeUsingMilliseconds(int idx, double ms)
|
||||
private void AdjustDisplayTimeUsingMilliseconds(int idx, double ms, List<double> shotChanges = null)
|
||||
{
|
||||
var p = Paragraphs[idx];
|
||||
var nextStartTimeInMs = double.MaxValue;
|
||||
@ -467,6 +476,12 @@ namespace Nikse.SubtitleEdit.Core.Common
|
||||
newEndTimeInMs = nextStartTimeInMs - Configuration.Settings.General.MinimumMillisecondsBetweenLines;
|
||||
}
|
||||
|
||||
// handle shot change if supplied -- keep earliest time
|
||||
if (shotChanges != null)
|
||||
{
|
||||
newEndTimeInMs = Math.Min(newEndTimeInMs, ShotChangeHelper.GetNextShotChangeMinusGapInMs(shotChanges, p.EndTime));
|
||||
}
|
||||
|
||||
// max duration
|
||||
var dur = newEndTimeInMs - p.StartTime.TotalMilliseconds;
|
||||
if (dur > Configuration.Settings.General.SubtitleMaximumDisplayMilliseconds)
|
||||
@ -482,25 +497,25 @@ namespace Nikse.SubtitleEdit.Core.Common
|
||||
p.EndTime.TotalMilliseconds = newEndTimeInMs;
|
||||
}
|
||||
|
||||
public void RecalculateDisplayTimes(double maxCharPerSec, List<int> selectedIndexes, double optimalCharPerSec, bool extendOnly = false)
|
||||
public void RecalculateDisplayTimes(double maxCharPerSec, List<int> selectedIndexes, double optimalCharPerSec, bool extendOnly = false, List<double> shotChanges = null)
|
||||
{
|
||||
if (selectedIndexes != null)
|
||||
{
|
||||
foreach (var index in selectedIndexes)
|
||||
{
|
||||
RecalculateDisplayTime(maxCharPerSec, index, optimalCharPerSec, extendOnly);
|
||||
RecalculateDisplayTime(maxCharPerSec, index, optimalCharPerSec, extendOnly, false, shotChanges);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < Paragraphs.Count; i++)
|
||||
{
|
||||
RecalculateDisplayTime(maxCharPerSec, i, optimalCharPerSec, extendOnly);
|
||||
RecalculateDisplayTime(maxCharPerSec, i, optimalCharPerSec, extendOnly, false, shotChanges);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void RecalculateDisplayTime(double maxCharactersPerSecond, int index, double optimalCharactersPerSeconds, bool extendOnly = false, bool onlyOptimal = false)
|
||||
public void RecalculateDisplayTime(double maxCharactersPerSecond, int index, double optimalCharactersPerSeconds, bool extendOnly = false, bool onlyOptimal = false, List<double> shotChanges = null)
|
||||
{
|
||||
var p = GetParagraphOrDefault(index);
|
||||
if (p == null)
|
||||
@ -524,17 +539,30 @@ namespace Nikse.SubtitleEdit.Core.Common
|
||||
}
|
||||
|
||||
var next = GetParagraphOrDefault(index + 1);
|
||||
if (next != null && p.StartTime.TotalMilliseconds + duration + Configuration.Settings.General.MinimumMillisecondsBetweenLines > next.StartTime.TotalMilliseconds)
|
||||
var wantedEndMs = p.EndTime.TotalMilliseconds;
|
||||
var bestEndMs = double.MaxValue;
|
||||
|
||||
// First check for next subtitle
|
||||
if (next != null)
|
||||
{
|
||||
p.EndTime.TotalMilliseconds = next.StartTime.TotalMilliseconds - Configuration.Settings.General.MinimumMillisecondsBetweenLines;
|
||||
if (p.Duration.TotalMilliseconds <= 0)
|
||||
{
|
||||
p.EndTime.TotalMilliseconds = p.StartTime.TotalMilliseconds + 1;
|
||||
}
|
||||
bestEndMs = next.StartTime.TotalMilliseconds - Configuration.Settings.General.MinimumMillisecondsBetweenLines;
|
||||
}
|
||||
|
||||
// Then check for next shot change (if option is checked, and if any are supplied) -- keeping earliest time
|
||||
if (shotChanges != null)
|
||||
{
|
||||
bestEndMs = Math.Min(bestEndMs, ShotChangeHelper.GetNextShotChangeMinusGapInMs(shotChanges, new TimeCode(originalEndTime)));
|
||||
}
|
||||
|
||||
p.EndTime.TotalMilliseconds = wantedEndMs <= bestEndMs ? wantedEndMs : bestEndMs;
|
||||
|
||||
if (p.Duration.TotalMilliseconds <= 0)
|
||||
{
|
||||
p.EndTime.TotalMilliseconds = p.StartTime.TotalMilliseconds + 1;
|
||||
}
|
||||
}
|
||||
|
||||
public void SetFixedDuration(List<int> selectedIndexes, double fixedDurationMilliseconds)
|
||||
public void SetFixedDuration(List<int> selectedIndexes, double fixedDurationMilliseconds, List<double> shotChanges = null)
|
||||
{
|
||||
for (int i = 0; i < Paragraphs.Count; i++)
|
||||
{
|
||||
@ -546,16 +574,27 @@ namespace Nikse.SubtitleEdit.Core.Common
|
||||
continue;
|
||||
}
|
||||
|
||||
p.EndTime.TotalMilliseconds = p.StartTime.TotalMilliseconds + fixedDurationMilliseconds;
|
||||
|
||||
var next = GetParagraphOrDefault(i + 1);
|
||||
if (next != null && p.StartTime.TotalMilliseconds + fixedDurationMilliseconds + Configuration.Settings.General.MinimumMillisecondsBetweenLines > next.StartTime.TotalMilliseconds)
|
||||
var wantedEndMs = p.StartTime.TotalMilliseconds + fixedDurationMilliseconds;
|
||||
var bestEndMs = double.MaxValue;
|
||||
|
||||
// First check for next subtitle
|
||||
if (next != null)
|
||||
{
|
||||
p.EndTime.TotalMilliseconds = next.StartTime.TotalMilliseconds - Configuration.Settings.General.MinimumMillisecondsBetweenLines;
|
||||
if (p.Duration.TotalMilliseconds <= 0)
|
||||
{
|
||||
p.EndTime.TotalMilliseconds = p.StartTime.TotalMilliseconds + 1;
|
||||
}
|
||||
bestEndMs = next.StartTime.TotalMilliseconds - Configuration.Settings.General.MinimumMillisecondsBetweenLines;
|
||||
}
|
||||
|
||||
// Then check for next shot change (if option is checked, and if any are supplied) -- keeping earliest time
|
||||
if (shotChanges != null)
|
||||
{
|
||||
bestEndMs = Math.Min(bestEndMs, ShotChangeHelper.GetNextShotChangeMinusGapInMs(shotChanges, p.EndTime));
|
||||
}
|
||||
|
||||
p.EndTime.TotalMilliseconds = wantedEndMs <= bestEndMs ? wantedEndMs : bestEndMs;
|
||||
|
||||
if (p.Duration.TotalMilliseconds <= 0)
|
||||
{
|
||||
p.EndTime.TotalMilliseconds = p.StartTime.TotalMilliseconds + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
1
src/ui/Forms/ApplyDurationLimits.Designer.cs
generated
1
src/ui/Forms/ApplyDurationLimits.Designer.cs
generated
@ -308,6 +308,7 @@
|
||||
this.checkBoxCheckShotChanges.TabIndex = 111;
|
||||
this.checkBoxCheckShotChanges.Text = "Check shot changes";
|
||||
this.checkBoxCheckShotChanges.UseVisualStyleBackColor = true;
|
||||
this.checkBoxCheckShotChanges.CheckedChanged += new System.EventHandler(this.checkBoxCheckShotChanges_CheckedChanged);
|
||||
//
|
||||
// ApplyDurationLimits
|
||||
//
|
||||
|
@ -1,7 +1,9 @@
|
||||
using Nikse.SubtitleEdit.Core.Common;
|
||||
using Nikse.SubtitleEdit.Logic;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Forms
|
||||
@ -16,6 +18,7 @@ namespace Nikse.SubtitleEdit.Forms
|
||||
private readonly Timer _refreshTimer = new Timer();
|
||||
private readonly Color _warningColor = Color.FromArgb(255, 253, 145);
|
||||
private Subtitle _unfixables = new Subtitle();
|
||||
private List<double> _shotChanges = new List<double>();
|
||||
|
||||
public ApplyDurationLimits()
|
||||
{
|
||||
@ -74,9 +77,20 @@ namespace Nikse.SubtitleEdit.Forms
|
||||
UiUtil.FixLargeFonts(this, buttonOK);
|
||||
}
|
||||
|
||||
public void Initialize(Subtitle subtitle)
|
||||
public void Initialize(Subtitle subtitle, List<double> shotChanges = null)
|
||||
{
|
||||
_subtitle = subtitle;
|
||||
|
||||
if (shotChanges != null)
|
||||
{
|
||||
_shotChanges = shotChanges;
|
||||
checkBoxCheckShotChanges.Enabled = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
checkBoxCheckShotChanges.Enabled = false;
|
||||
}
|
||||
|
||||
GeneratePreview();
|
||||
}
|
||||
|
||||
@ -154,16 +168,29 @@ namespace Nikse.SubtitleEdit.Forms
|
||||
{
|
||||
var next = _working.GetParagraphOrDefault(i + 1);
|
||||
var wantedEndMs = p.StartTime.TotalMilliseconds + minDisplayTime;
|
||||
if (next == null || wantedEndMs < next.StartTime.TotalMilliseconds - Configuration.Settings.General.MinimumMillisecondsBetweenLines)
|
||||
var bestEndMs = double.MaxValue;
|
||||
|
||||
// First check for next subtitle
|
||||
if (next != null)
|
||||
{
|
||||
bestEndMs = next.StartTime.TotalMilliseconds - Configuration.Settings.General.MinimumMillisecondsBetweenLines;
|
||||
}
|
||||
|
||||
// Then check for next shot change (if option is checked, and if any are supplied) -- keeping earliest time
|
||||
if (checkBoxCheckShotChanges.Checked && _shotChanges.Count > 0)
|
||||
{
|
||||
bestEndMs = Math.Min(bestEndMs, ShotChangeHelper.GetNextShotChangeMinusGapInMs(_shotChanges, p.EndTime));
|
||||
}
|
||||
|
||||
if (wantedEndMs <= bestEndMs)
|
||||
{
|
||||
AddFix(p, wantedEndMs, DefaultBackColor);
|
||||
}
|
||||
else
|
||||
{
|
||||
var nextBestEndMs = next.StartTime.TotalMilliseconds - Configuration.Settings.General.MinimumMillisecondsBetweenLines;
|
||||
if (nextBestEndMs > p.EndTime.TotalMilliseconds)
|
||||
if (bestEndMs > p.EndTime.TotalMilliseconds)
|
||||
{
|
||||
AddFix(p, nextBestEndMs, _warningColor);
|
||||
AddFix(p, bestEndMs, _warningColor);
|
||||
_unfixables.Paragraphs.Add(new Paragraph(p) { Extra = "Warning" });
|
||||
}
|
||||
else
|
||||
@ -327,5 +354,10 @@ namespace Nikse.SubtitleEdit.Forms
|
||||
item.Checked = !item.Checked;
|
||||
}
|
||||
}
|
||||
|
||||
private void checkBoxCheckShotChanges_CheckedChanged(object sender, EventArgs e)
|
||||
{
|
||||
GeneratePreview();
|
||||
}
|
||||
}
|
||||
}
|
@ -1943,6 +1943,7 @@ namespace Nikse.SubtitleEdit.Forms
|
||||
|
||||
if (IsActionEnabled(CommandLineConverter.BatchAction.AdjustDisplayDuration))
|
||||
{
|
||||
// TODO shot changes
|
||||
var adjustmentType = comboBoxAdjustDurationVia.Text;
|
||||
if (adjustmentType == LanguageSettings.Current.AdjustDisplayDuration.Percent)
|
||||
{
|
||||
|
@ -7470,27 +7470,29 @@ namespace Nikse.SubtitleEdit.Forms
|
||||
if (adjustDisplayTime.ShowDialog(this) == DialogResult.OK)
|
||||
{
|
||||
MakeHistoryForUndo(_language.BeforeDisplayTimeAdjustment);
|
||||
List<double> shotChanges = adjustDisplayTime.CheckShotChanges ? audioVisualizer.ShotChanges : new List<double>();
|
||||
|
||||
if (adjustDisplayTime.AdjustUsingPercent)
|
||||
{
|
||||
double percent = double.Parse(adjustDisplayTime.AdjustValue);
|
||||
_subtitle.AdjustDisplayTimeUsingPercent(percent, selectedIndices);
|
||||
_subtitle.AdjustDisplayTimeUsingPercent(percent, selectedIndices, shotChanges);
|
||||
ShowStatus(string.Format(_language.DisplayTimesAdjustedX, double.Parse(adjustDisplayTime.AdjustValue, CultureInfo.InvariantCulture) + "%"));
|
||||
}
|
||||
else if (adjustDisplayTime.AdjustUsingSeconds)
|
||||
{
|
||||
double seconds = double.Parse(adjustDisplayTime.AdjustValue, CultureInfo.InvariantCulture);
|
||||
_subtitle.AdjustDisplayTimeUsingSeconds(seconds, selectedIndices);
|
||||
_subtitle.AdjustDisplayTimeUsingSeconds(seconds, selectedIndices, shotChanges);
|
||||
ShowStatus(string.Format(_language.DisplayTimesAdjustedX, double.Parse(adjustDisplayTime.AdjustValue, CultureInfo.InvariantCulture)));
|
||||
}
|
||||
else if (adjustDisplayTime.AdjustUsingRecalc)
|
||||
{
|
||||
double maxCharSeconds = (double)(adjustDisplayTime.MaxCharactersPerSecond);
|
||||
_subtitle.RecalculateDisplayTimes(maxCharSeconds, selectedIndices, (double)adjustDisplayTime.OptimalCharactersPerSecond, adjustDisplayTime.ExtendOnly);
|
||||
_subtitle.RecalculateDisplayTimes(maxCharSeconds, selectedIndices, (double)adjustDisplayTime.OptimalCharactersPerSecond, adjustDisplayTime.ExtendOnly, shotChanges);
|
||||
ShowStatus(string.Format(_language.DisplayTimesAdjustedX, adjustDisplayTime.AdjustValue));
|
||||
}
|
||||
else
|
||||
{ // fixed duration
|
||||
_subtitle.SetFixedDuration(selectedIndices, adjustDisplayTime.FixedMilliseconds);
|
||||
_subtitle.SetFixedDuration(selectedIndices, adjustDisplayTime.FixedMilliseconds, shotChanges);
|
||||
ShowStatus(string.Format(_language.DisplayTimesAdjustedX, adjustDisplayTime.FixedMilliseconds));
|
||||
}
|
||||
|
||||
@ -30305,11 +30307,11 @@ namespace Nikse.SubtitleEdit.Forms
|
||||
selectedLines.Paragraphs.Add(_subtitle.Paragraphs[index]);
|
||||
}
|
||||
|
||||
applyDurationLimits.Initialize(selectedLines);
|
||||
applyDurationLimits.Initialize(selectedLines, audioVisualizer.ShotChanges);
|
||||
}
|
||||
else
|
||||
{
|
||||
applyDurationLimits.Initialize(_subtitle);
|
||||
applyDurationLimits.Initialize(_subtitle, audioVisualizer.ShotChanges);
|
||||
}
|
||||
|
||||
if (applyDurationLimits.ShowDialog(this) == DialogResult.OK)
|
||||
|
Loading…
Reference in New Issue
Block a user