Add "Auto adjust start via volume/scene change" shortcut - thx Odaylton :)

This commit is contained in:
Nikolaj Olsson 2020-03-15 11:22:18 +01:00
parent fd1a288424
commit 87b95d9c83
10 changed files with 133 additions and 2 deletions

View File

@ -2021,6 +2021,7 @@ can edit in same subtitle file (collaboration)</Information>
<WaveformGoToPreviousSceneChange>Go to previous scene change</WaveformGoToPreviousSceneChange>
<WaveformGoToNextSceneChange>Go to next scene change</WaveformGoToNextSceneChange>
<WaveformToggleSceneChange>Toggle scene change</WaveformToggleSceneChange>
<WaveformGuessStart>Auto adjust start via volume/scene change</WaveformGuessStart>
<GoBack1Frame>One frame back</GoBack1Frame>
<GoForward1Frame>One frame forward</GoForward1Frame>
<GoBack1FrameWithPlay>One frame back (with play)</GoBack1FrameWithPlay>

View File

@ -2317,6 +2317,7 @@ can edit in same subtitle file (collaboration)",
WaveformGoToPreviousSceneChange = "Go to previous scene change",
WaveformGoToNextSceneChange = "Go to next scene change",
WaveformToggleSceneChange = "Toggle scene change",
WaveformGuessStart = "Auto adjust start via volume/scene change",
GoBack1Frame = "One frame back",
GoForward1Frame = "One frame forward",
GoBack1FrameWithPlay = "One frame back (with play)",

View File

@ -5485,6 +5485,9 @@ namespace Nikse.SubtitleEdit.Core
case "Settings/WaveformToggleSceneChange":
language.Settings.WaveformToggleSceneChange = reader.Value;
break;
case "Settings/WaveformGuessStart":
language.Settings.WaveformGuessStart = reader.Value;
break;
case "Settings/GoBack1Frame":
language.Settings.GoBack1Frame = reader.Value;
break;

View File

@ -2186,6 +2186,7 @@
public string WaveformGoToPreviousSceneChange { get; set; }
public string WaveformGoToNextSceneChange { get; set; }
public string WaveformToggleSceneChange { get; set; }
public string WaveformGuessStart { get; set; }
public string GoBack1Frame { get; set; }
public string GoForward1Frame { get; set; }
public string GoBack1FrameWithPlay { get; set; }

View File

@ -1557,6 +1557,7 @@ $HorzAlign = Center
public string WaveformGoToPreviousSceneChange { get; set; }
public string WaveformGoToNextSceneChange { get; set; }
public string WaveformToggleSceneChange { get; set; }
public string WaveformGuessStart { get; set; }
public string MainTranslateGoogleIt { get; set; }
public string MainTranslateGoogleTranslate { get; set; }
public string MainTranslateCustomSearch1 { get; set; }
@ -6103,6 +6104,12 @@ $HorzAlign = Center
settings.Shortcuts.WaveformToggleSceneChange = subNode.InnerText;
}
subNode = node.SelectSingleNode("WaveformGuessStart");
if (subNode != null)
{
settings.Shortcuts.WaveformGuessStart = subNode.InnerText;
}
subNode = node.SelectSingleNode("MainTranslateGoogleIt");
if (subNode != null)
{
@ -7109,6 +7116,7 @@ $HorzAlign = Center
textWriter.WriteElementString("WaveformGoToPreviousSceneChange", settings.Shortcuts.WaveformGoToPreviousSceneChange);
textWriter.WriteElementString("WaveformGoToNextSceneChange", settings.Shortcuts.WaveformGoToNextSceneChange);
textWriter.WriteElementString("WaveformToggleSceneChange", settings.Shortcuts.WaveformToggleSceneChange);
textWriter.WriteElementString("WaveformGuessStart", settings.Shortcuts.WaveformGuessStart);
textWriter.WriteElementString("MainTranslateGoogleIt", settings.Shortcuts.MainTranslateGoogleIt);
textWriter.WriteElementString("MainTranslateGoogleTranslate", settings.Shortcuts.MainTranslateGoogleTranslate);
textWriter.WriteElementString("MainTranslateCustomSearch1", settings.Shortcuts.MainTranslateCustomSearch1);

View File

@ -1926,6 +1926,7 @@ namespace Nikse.SubtitleEdit.Controls
return -1;
}
/// <returns>video position in seconds, -1 if not found</returns>
public double FindDataBelowThresholdBack(double thresholdPercent, double durationInSeconds)
{
int begin = SecondsToSampleIndex(_currentVideoPositionSeconds - 1);
@ -1946,7 +1947,7 @@ namespace Nikse.SubtitleEdit.Controls
if (hitCount > length)
{
double seconds = SampleIndexToSeconds(i + (length / 2));
double seconds = SampleIndexToSeconds(i + length / 2);
if (seconds >= 0)
{
StartPositionSeconds = seconds;
@ -1968,6 +1969,36 @@ namespace Nikse.SubtitleEdit.Controls
return -1;
}
/// <summary>
/// Seeks silence in volume
/// </summary>
/// <returns>video position in seconds, -1 if not found</returns>
public double FindDataBelowThresholdBackForStart(double thresholdPercent, double durationInSeconds, double startSeconds)
{
var min = SecondsToSampleIndex(startSeconds - 1);
var max = SecondsToSampleIndex(startSeconds + durationInSeconds + 0.05);
int length = SecondsToSampleIndex(durationInSeconds);
var threshold = thresholdPercent / 100.0 * _wavePeaks.HighestPeak;
int hitCount = 0;
for (int i = max; i > min; i--)
{
if (i > 0 && i < _wavePeaks.Peaks.Count && _wavePeaks.Peaks[i].Abs <= threshold)
{
hitCount++;
}
else
{
hitCount = 0;
}
if (hitCount > length)
{
return Math.Max(0, SampleIndexToSeconds(i + length) - 0.01);
}
}
return -1;
}
public void ZoomIn()
{
ZoomFactor += 0.1;

View File

@ -14245,6 +14245,11 @@ namespace Nikse.SubtitleEdit.Forms
e.SuppressKeyPress = true;
}
else if (audioVisualizer.SceneChanges != null && mediaPlayer.IsPaused && e.KeyData == _shortcuts.WaveformGuessStart)
{
AutoGuessStartTime(_subtitleListViewIndex);
e.SuppressKeyPress = true;
}
else if (audioVisualizer.Focused && e.KeyCode == Keys.Delete)
{
ToolStripMenuItemDeleteClick(null, null);
@ -14602,6 +14607,76 @@ namespace Nikse.SubtitleEdit.Forms
// put new entries above tabs
}
private void AutoGuessStartTime(int index)
{
var silenceLengthInSeconds = 0.11;
var p = _subtitle.GetParagraphOrDefault(index);
for (var startVolume = 8.5; startVolume < 14; startVolume += 0.3)
{
var pos = audioVisualizer.FindDataBelowThresholdBackForStart(startVolume, silenceLengthInSeconds, p.StartTime.TotalSeconds);
var pos2 = audioVisualizer.FindDataBelowThresholdBackForStart(startVolume + 0.3, silenceLengthInSeconds, p.StartTime.TotalSeconds);
if (pos >= 0 && pos > p.StartTime.TotalSeconds - 1)
{
if (pos2 > pos && pos2 >= 0 && pos2 > p.StartTime.TotalSeconds - 1)
{
pos = pos2;
}
var newStartTimeMs = pos * TimeCode.BaseUnit;
var prev = _subtitle.GetParagraphOrDefault(index - 1);
if (prev != null && prev.EndTime.TotalMilliseconds + Configuration.Settings.General.MinimumMillisecondsBetweenLines >= newStartTimeMs)
{
newStartTimeMs = prev.EndTime.TotalMilliseconds + Configuration.Settings.General.MinimumMillisecondsBetweenLines;
if (newStartTimeMs >= p.StartTime.TotalMilliseconds)
{
break; // cannot move start time
}
}
// check for scene changes
if (audioVisualizer.SceneChanges != null)
{
var matchingSceneChanges = audioVisualizer.SceneChanges
.Where(sc => sc > p.StartTime.TotalSeconds - 0.3 && sc < p.StartTime.TotalSeconds + 0.2)
.OrderBy(sc => Math.Abs(sc - p.StartTime.TotalSeconds));
if (matchingSceneChanges.Count() > 0)
{
newStartTimeMs = matchingSceneChanges.First() * TimeCode.BaseUnit;
}
}
if (Math.Abs(p.StartTime.TotalMilliseconds - newStartTimeMs) < 10)
{
break; // diff too small
}
var newEndTimeMs = p.EndTime.TotalMilliseconds;
if (newStartTimeMs > p.StartTime.TotalMilliseconds)
{
var temp = new Paragraph(p);
temp.StartTime.TotalMilliseconds = newStartTimeMs;
if (temp.Duration.TotalMilliseconds < Configuration.Settings.General.SubtitleMinimumDisplayMilliseconds ||
Utilities.GetCharactersPerSecond(temp) > Configuration.Settings.General.SubtitleMaximumCharactersPerSeconds)
{
var next = _subtitle.GetParagraphOrDefault(index + 1);
if (next == null ||
next.StartTime.TotalMilliseconds > newStartTimeMs + p.Duration.TotalMilliseconds + Configuration.Settings.General.MinimumMillisecondsBetweenLines)
{
newEndTimeMs = newStartTimeMs + p.Duration.TotalMilliseconds;
}
}
}
MakeHistoryForUndo(string.Format(Configuration.Settings.Language.Main.BeforeX, Configuration.Settings.Language.Settings.WaveformGuessStart));
p.StartTime.TotalMilliseconds = newStartTimeMs;
p.EndTime.TotalMilliseconds = newEndTimeMs;
RefreshSelectedParagraph();
SubtitleListview1.SetStartTimeAndDuration(index, p, _subtitle.GetParagraphOrDefault(index + 1), _subtitle.GetParagraphOrDefault(index - 1));
break;
}
}
}
private void GoToBookmark()
{
using (var form = new BookmarksGoTo(_subtitle))

View File

@ -1270,6 +1270,7 @@ namespace Nikse.SubtitleEdit.Forms
AddNode(audioVisualizerNode, language.WaveformGoToPreviousSceneChange, nameof(Configuration.Settings.Shortcuts.WaveformGoToPreviousSceneChange));
AddNode(audioVisualizerNode, language.WaveformGoToNextSceneChange, nameof(Configuration.Settings.Shortcuts.WaveformGoToNextSceneChange));
AddNode(audioVisualizerNode, language.WaveformToggleSceneChange, nameof(Configuration.Settings.Shortcuts.WaveformToggleSceneChange));
AddNode(audioVisualizerNode, language.WaveformGuessStart, nameof(Configuration.Settings.Shortcuts.WaveformGuessStart));
if (audioVisualizerNode.Nodes.Count > 0)
{
_shortcuts.Nodes.Add(audioVisualizerNode);

View File

@ -132,6 +132,7 @@ namespace Nikse.SubtitleEdit.Logic
public Keys WaveformGoToPreviousSceneChange { get; set; }
public Keys WaveformGoToNextSceneChange { get; set; }
public Keys WaveformToggleSceneChange { get; set; }
public Keys WaveformGuessStart { get; set; }
public Keys MainTranslateGoogleIt { get; set; }
public Keys MainTranslateGoogleTranslate { get; set; }
public Keys MainTranslateCustomSearch1 { get; set; }
@ -269,6 +270,7 @@ namespace Nikse.SubtitleEdit.Logic
WaveformGoToPreviousSceneChange = UiUtil.GetKeys(Configuration.Settings.Shortcuts.WaveformGoToPreviousSceneChange);
WaveformGoToNextSceneChange = UiUtil.GetKeys(Configuration.Settings.Shortcuts.WaveformGoToNextSceneChange);
WaveformToggleSceneChange = UiUtil.GetKeys(Configuration.Settings.Shortcuts.WaveformToggleSceneChange);
WaveformGuessStart = UiUtil.GetKeys(Configuration.Settings.Shortcuts.WaveformGuessStart);
MainTranslateGoogleIt = UiUtil.GetKeys(Configuration.Settings.Shortcuts.MainTranslateGoogleIt);
MainTranslateGoogleTranslate = UiUtil.GetKeys(Configuration.Settings.Shortcuts.MainTranslateGoogleTranslate);
MainTranslateCustomSearch1 = UiUtil.GetKeys(Configuration.Settings.Shortcuts.MainTranslateCustomSearch1);

View File

@ -66,7 +66,15 @@ namespace UpdateLanguageFiles
if (oldLanguageDeserializerContent != languageDeserializerContent)
{
File.WriteAllText(args[1], languageDeserializerContent, Encoding.UTF8);
try
{
File.WriteAllText(args[1], languageDeserializerContent, Encoding.UTF8);
}
catch
{
System.Threading.Thread.Sleep(100);
File.WriteAllText(args[1], languageDeserializerContent, Encoding.UTF8);
}
noOfChanges++;
Console.Write(" {0} generated...", Path.GetFileName(args[1]));
}