Allow generation of waveform without audio - thx serquis/grzesiek :)

Fix #3953
This commit is contained in:
Nikolaj Olsson 2020-04-10 16:13:28 +02:00
parent 7bd81b1a3a
commit 0adc0b128e
6 changed files with 63 additions and 11 deletions

View File

@ -133,6 +133,7 @@ Command line: {1} {2}
Note: Do check free disk space.</WaveFileMalformed>
<LowDiskSpace>LOW DISK SPACE!</LowDiskSpace>
<FreeDiskSpace>{0} free</FreeDiskSpace>
<NoAudioTracksFoundGenerateEmptyWaveform>No audio tracks found! Generate empty waveform?</NoAudioTracksFoundGenerateEmptyWaveform>
</AddWaveform>
<AddWaveformBatch>
<Title>Batch generate waveform data</Title>

View File

@ -261,6 +261,7 @@ namespace Nikse.SubtitleEdit.Core
"Note: Do check free disk space.",
LowDiskSpace = "LOW DISK SPACE!",
FreeDiskSpace = "{0} free",
NoAudioTracksFoundGenerateEmptyWaveform = "No audio tracks found! Generate empty waveform?",
};
AddWaveformBatch = new LanguageStructure.AddWaveformBatch

View File

@ -376,6 +376,9 @@ namespace Nikse.SubtitleEdit.Core
case "AddWaveform/FreeDiskSpace":
language.AddWaveform.FreeDiskSpace = reader.Value;
break;
case "AddWaveform/NoAudioTracksFoundGenerateEmptyWaveform":
language.AddWaveform.NoAudioTracksFoundGenerateEmptyWaveform = reader.Value;
break;
case "AddWaveformBatch/Title":
language.AddWaveformBatch.Title = reader.Value;
break;

View File

@ -131,6 +131,7 @@
public string WaveFileMalformed { get; set; }
public string LowDiskSpace { get; set; }
public string FreeDiskSpace { get; set; }
public string NoAudioTracksFoundGenerateEmptyWaveform { get; set; }
}
public class AddWaveformBatch

View File

@ -401,13 +401,7 @@ namespace Nikse.SubtitleEdit.Core
/// <summary>
/// Returns true if the current wave file can be processed. Compressed wave files are not supported.
/// </summary>
public bool IsSupported
{
get
{
return _header.AudioFormat == WaveHeader.AudioFormatPcm && _header.Format == "WAVE";
}
}
public bool IsSupported => _header.AudioFormat == WaveHeader.AudioFormatPcm && _header.Format == "WAVE";
/// <summary>
/// Generates peaks and saves them to disk.
@ -501,6 +495,34 @@ namespace Nikse.SubtitleEdit.Core
return new WavePeakData(peaksPerSecond, peaks);
}
public static WavePeakData GenerateEmptyPeaks(string peakFileName, int totalSeconds)
{
int peaksPerSecond = Configuration.Settings.VideoControls.WaveformMinimumSampleRate;
var peaks = new List<WavePeak>();
peaks.Add(new WavePeak(1000, -1000));
var totalPeaks = peaksPerSecond * totalSeconds;
for (int i = 0; i < totalPeaks; i++)
{
peaks.Add(new WavePeak(1, -1));
}
peaks.Add(new WavePeak(1000, -1000));
// save results to file
using (var stream = File.Create(peakFileName))
{
WaveHeader.WriteHeader(stream, peaksPerSecond, 2, 16, peaks.Count);
byte[] buffer = new byte[4];
foreach (var peak in peaks)
{
WriteValue16Bit(buffer, 0, peak.Max);
WriteValue16Bit(buffer, 2, peak.Min);
stream.Write(buffer, 0, 4);
}
}
return new WavePeakData(peaksPerSecond, peaks);
}
private static WavePeak CalculatePeak(float[] chunk, int count)
{
if (count == 0)

View File

@ -25,6 +25,7 @@ namespace Nikse.SubtitleEdit.Forms
private const string RetryEncodeParameters = "acodec=s16l";
private int _audioTrackNumber = -1;
private int _delayInMilliseconds;
private int _numberOfAudioTracks;
public AddWaveform()
{
@ -231,6 +232,13 @@ namespace Nikse.SubtitleEdit.Forms
return;
}
if (_numberOfAudioTracks == 0 && MessageBox.Show(Configuration.Settings.Language.AddWaveform.NoAudioTracksFoundGenerateEmptyWaveform, Configuration.Settings.Language.General.Title, MessageBoxButtons.YesNoCancel) == DialogResult.Yes)
{
MakeEmptyWaveFile();
DialogResult = DialogResult.OK;
return;
}
MessageBox.Show(string.Format(Configuration.Settings.Language.AddWaveform.WaveFileNotFound, IntPtr.Size * 8, process.StartInfo.FileName, process.StartInfo.Arguments));
labelPleaseWait.Visible = false;
@ -241,6 +249,13 @@ namespace Nikse.SubtitleEdit.Forms
if (targetFileInfo.Length <= 200)
{
if (_numberOfAudioTracks == 0 && MessageBox.Show(Configuration.Settings.Language.AddWaveform.NoAudioTracksFoundGenerateEmptyWaveform, Configuration.Settings.Language.General.Title, MessageBoxButtons.YesNoCancel) == DialogResult.Yes)
{
MakeEmptyWaveFile();
DialogResult = DialogResult.OK;
return;
}
MessageBox.Show(string.Format(Configuration.Settings.Language.AddWaveform.WaveFileMalformed, encoderName, process.StartInfo.FileName, process.StartInfo.Arguments));
labelPleaseWait.Visible = false;
@ -275,12 +290,21 @@ namespace Nikse.SubtitleEdit.Forms
labelPleaseWait.Visible = false;
}
private void MakeEmptyWaveFile()
{
labelProgress.Text = Configuration.Settings.Language.AddWaveform.GeneratingPeakFile;
Refresh();
var videoInfo = UiUtil.GetVideoInfo(SourceVideoFileName);
Peaks = WavePeakGenerator.GenerateEmptyPeaks(_peakWaveFileName, (int)videoInfo.TotalMilliseconds / 1000);
labelPleaseWait.Visible = false;
}
private void AddWaveform_Shown(object sender, EventArgs e)
{
Refresh();
_numberOfAudioTracks = 0;
var audioTrackNames = new List<string>();
var mkvAudioTrackNumbers = new Dictionary<int, int>();
int numberOfAudioTracks = 0;
if (labelVideoFileName.Text.Length > 1 && File.Exists(labelVideoFileName.Text))
{
if (labelVideoFileName.Text.EndsWith(".mkv", StringComparison.OrdinalIgnoreCase))
@ -295,7 +319,7 @@ namespace Nikse.SubtitleEdit.Forms
{
if (track.IsAudio)
{
numberOfAudioTracks++;
_numberOfAudioTracks++;
if (track.CodecId != null && track.Language != null)
{
audioTrackNames.Add("#" + track.TrackNumber + ": " + track.CodecId.Replace("\0", string.Empty) + " - " + track.Language.Replace("\0", string.Empty));
@ -338,7 +362,7 @@ namespace Nikse.SubtitleEdit.Forms
audioTrackNames.Add(i.ToString(CultureInfo.InvariantCulture));
}
}
numberOfAudioTracks = tracks.Count;
_numberOfAudioTracks = tracks.Count;
}
catch
{
@ -347,7 +371,7 @@ namespace Nikse.SubtitleEdit.Forms
}
// Choose audio track
if (numberOfAudioTracks > 1)
if (_numberOfAudioTracks > 1)
{
using (var form = new ChooseAudioTrack(audioTrackNames, _audioTrackNumber))
{