public static bool InitializeVideoPlayerAndContainer(string fileName, VideoInfo videoInfo, VideoPlayerContainer videoPlayerContainer, EventHandler onVideoLoaded, EventHandler onVideoEnded) { try { videoPlayerContainer.VideoPlayer = GetVideoPlayer(); videoPlayerContainer.VideoPlayer.Initialize(videoPlayerContainer.PanelPlayer, fileName, onVideoLoaded, onVideoEnded); videoPlayerContainer.ShowStopButton = Configuration.Settings.General.VideoPlayerShowStopButton; videoPlayerContainer.ShowFullscreenButton = false; videoPlayerContainer.ShowMuteButton = Configuration.Settings.General.VideoPlayerShowMuteButton; videoPlayerContainer.Volume = Configuration.Settings.General.VideoPlayerDefaultVolume; videoPlayerContainer.EnableMouseWheelStep(); if (fileName != null && (fileName.StartsWith("https://", StringComparison.OrdinalIgnoreCase) || fileName.StartsWith("http://", StringComparison.OrdinalIgnoreCase))) { // we don't have videoInfo for streams... } else { videoPlayerContainer.VideoWidth = videoInfo.Width; videoPlayerContainer.VideoHeight = videoInfo.Height; videoPlayerContainer.VideoPlayer.Resize(videoPlayerContainer.PanelPlayer.Width, videoPlayerContainer.PanelPlayer.Height); } return(true); } catch (Exception exception) { videoPlayerContainer.VideoPlayer = null; var videoError = new VideoError(); videoError.Initialize(fileName, exception); videoError.ShowDialog(); SeLogger.Error(exception, "InitializeVideoPlayerAndContainer failed to load video player"); return(false); } }
private void Translate() { var translator = (ITranslationProcessor)comboBoxParagraphHandling.SelectedItem; buttonOK.Enabled = false; buttonCancel.Enabled = false; _breakTranslation = false; buttonTranslate.Text = LanguageSettings.Current.General.Cancel; Cursor.Current = Cursors.WaitCursor; progressBar1.Visible = true; labelPleaseWait.Visible = true; try { var selectedParagraphs = GetSelectedParagraphs(); progressBar1.Minimum = 0; progressBar1.Maximum = selectedParagraphs.Count; translator.Translate(_translationService, _sourceLanguageIsoCode, _targetLanguageIsoCode, selectedParagraphs, targetParagraphs => { FillTranslatedText(targetParagraphs); progressBar1.Value = selectedParagraphs.FindIndex(x => x.Number == targetParagraphs.Keys.Last()); Application.DoEvents(); return(_breakTranslation); }); } catch (TranslationException translationException) { if (translationException.InnerException != null && !IsAvailableNetworkActive()) { ShowNetworkError(translationException.InnerException); } else { MessageBox.Show(translationException.Message + Environment.NewLine + translationException.InnerException?.Source + ": " + translationException.InnerException?.Message); } } catch (Exception exception) { SeLogger.Error(exception); ShowNetworkError(exception); } finally { labelPleaseWait.Visible = false; progressBar1.Visible = false; Cursor.Current = Cursors.Default; buttonTranslate.Text = LanguageSettings.Current.GoogleTranslate.Translate; buttonTranslate.Enabled = true; buttonOK.Enabled = true; buttonCancel.Enabled = true; Configuration.Settings.Tools.GoogleTranslateLastTargetLanguage = _targetLanguageIsoCode; } }
public static int BridgeGaps(Subtitle subtitle, int minMsBetweenLines, bool divideEven, double maxMs, List <int> fixedIndexes, Dictionary <string, string> dic, bool useFrames) { int fixedCount = 0; if (minMsBetweenLines > maxMs) { string message = $"{nameof(DurationsBridgeGaps)}: {nameof(minMsBetweenLines)} cannot be larger than {nameof(maxMs)}!"; SeLogger.Error(new InvalidOperationException(message), message); return(0); } int count = subtitle.Paragraphs.Count - 1; for (int i = 0; i < count; i++) { var cur = subtitle.Paragraphs[i]; var next = subtitle.Paragraphs[i + 1]; double currentGap = next.StartTime.TotalMilliseconds - cur.EndTime.TotalMilliseconds; // there shouldn't be adjustment if current gaps is shorter or equal than minimum gap or greater than maximum gaps if (currentGap <= minMsBetweenLines || currentGap > maxMs) { continue; } // next paragraph start-time will be pull to try to meet the current paragraph if (divideEven) { next.StartTime.TotalMilliseconds -= currentGap / 2.0; } cur.EndTime.TotalMilliseconds = next.StartTime.TotalMilliseconds - minMsBetweenLines; if (fixedIndexes != null) { fixedIndexes.Add(i); fixedIndexes.Add(i + 1); } fixedCount++; double newGap = next.StartTime.TotalMilliseconds - cur.EndTime.TotalMilliseconds; if (useFrames) { dic?.Add(cur.Id, $"{SubtitleFormat.MillisecondsToFrames(currentGap)} => {SubtitleFormat.MillisecondsToFrames(newGap)}"); } else { dic?.Add(cur.Id, $"{currentGap / TimeCode.BaseUnit:0.000} => {newGap / TimeCode.BaseUnit:0.000}"); } } return(fixedCount); }
public static int BridgeGaps(Subtitle subtitle, int minMsBetweenLines, bool divideEven, double maxMs, List <int> fixedIndexes, Dictionary <string, string> dic) { if (minMsBetweenLines > maxMs) { string message = $"{nameof(DurationsBridgeGaps)}: {nameof(minMsBetweenLines)} cannot be smaller than {nameof(maxMs)}!"; SeLogger.Error(new InvalidOperationException(message), message); return(0); } int count = subtitle.Paragraphs.Count - 1; for (int i = 0; i < count; i++) { Paragraph cur = subtitle.Paragraphs[i]; Paragraph next = subtitle.Paragraphs[i + 1]; double currentGaps = next.StartTime.TotalMilliseconds - cur.EndTime.TotalMilliseconds; // there shouldn't be adjustment if current gaps is shorter than minimum gaps or greater than maximum gaps if (currentGaps < minMsBetweenLines || currentGaps > maxMs) { continue; } // next paragraph start-time will be pull to try to meet the current parragraph if (divideEven) { next.StartTime.TotalMilliseconds -= currentGaps / 2.0; } cur.EndTime.TotalMilliseconds = next.StartTime.TotalMilliseconds - minMsBetweenLines; if (fixedIndexes != null) { fixedIndexes.Add(i); fixedIndexes.Add(i + 1); } double newGaps = next.StartTime.TotalMilliseconds - cur.EndTime.TotalMilliseconds; dic?.Add(cur.ID, $"{currentGaps / TimeCode.BaseUnit:0.000} => {newGaps / TimeCode.BaseUnit:0.000}"); } return(fixedIndexes.Count / 2); }
private long MakeComparableVersionNumber(string versionNumber) { var s = versionNumber.Replace(',', '.').Replace(" ", string.Empty); var arr = s.Split('.'); if (arr.Length == 1 && long.TryParse(arr[0], out var a0)) { return(a0 * 1_000_000); } if (arr.Length == 2 && long.TryParse(arr[0], out var b0) && long.TryParse(arr[1], out var b1)) { return(b0 * 1_000_000 + b1 * 1_000); } if (arr.Length == 3 && long.TryParse(arr[0], out var c0) && long.TryParse(arr[1], out var c1) && long.TryParse(arr[2], out var c2)) { return(c0 * 1_000_000 + c1 * 1_000 + c2); } SeLogger.Error("Bad plugin version number: " + versionNumber); return(0); }
private void AddWaveform_Shown(object sender, EventArgs e) { Refresh(); _numberOfAudioTracks = 0; var audioTrackNames = new List <string>(); var mkvAudioTrackNumbers = new Dictionary <int, int>(); if (labelVideoFileName.Text.Length > 1 && File.Exists(labelVideoFileName.Text)) { if (labelVideoFileName.Text.EndsWith(".mkv", StringComparison.OrdinalIgnoreCase)) { // Choose for number of audio tracks in matroska files MatroskaFile matroska = null; try { matroska = new MatroskaFile(labelVideoFileName.Text); if (matroska.IsValid) { foreach (var track in matroska.GetTracks()) { if (track.IsAudio) { _numberOfAudioTracks++; if (track.CodecId != null && track.Language != null) { audioTrackNames.Add("#" + track.TrackNumber + ": " + track.CodecId.Replace("\0", string.Empty) + " - " + track.Language.Replace("\0", string.Empty)); } else { audioTrackNames.Add("#" + track.TrackNumber); } mkvAudioTrackNumbers.Add(mkvAudioTrackNumbers.Count, track.TrackNumber); } } } } finally { matroska?.Dispose(); } } else if (labelVideoFileName.Text.EndsWith(".mp4", StringComparison.OrdinalIgnoreCase) || labelVideoFileName.Text.EndsWith(".m4v", StringComparison.OrdinalIgnoreCase)) { // Choose for number of audio tracks in mp4 files try { var mp4 = new MP4Parser(labelVideoFileName.Text); var tracks = mp4.GetAudioTracks(); int i = 0; foreach (var track in tracks) { i++; if (track.Name != null && track.Mdia != null && track.Mdia.Mdhd != null && track.Mdia.Mdhd.LanguageString != null) { audioTrackNames.Add(i + ": " + track.Name + " - " + track.Mdia.Mdhd.LanguageString); } else if (track.Name != null) { audioTrackNames.Add(i + ": " + track.Name); } else { audioTrackNames.Add(i.ToString(CultureInfo.InvariantCulture)); } } _numberOfAudioTracks = tracks.Count; } catch { // ignored } } // Choose audio track if (_numberOfAudioTracks > 1) { using (var form = new ChooseAudioTrack(audioTrackNames, AudioTrackNumber)) { if (form.ShowDialog(this) == DialogResult.OK) { if (AudioTrackNumber != form.SelectedTrack) { AudioTrackNumber = form.SelectedTrack; var peakWaveFileName = WavePeakGenerator.GetPeakWaveFileName(labelVideoFileName.Text, form.SelectedTrack); var spectrogramFolder = WavePeakGenerator.SpectrogramDrawer.GetSpectrogramFolder(labelVideoFileName.Text, form.SelectedTrack); if (File.Exists(peakWaveFileName)) { DialogResult = DialogResult.Cancel; return; } _peakWaveFileName = peakWaveFileName; _spectrogramDirectory = spectrogramFolder; } } else { DialogResult = DialogResult.Cancel; return; } } } // check for delay in matroska files if (labelVideoFileName.Text.EndsWith(".mkv", StringComparison.OrdinalIgnoreCase)) { MatroskaFile matroska = null; try { matroska = new MatroskaFile(labelVideoFileName.Text); if (matroska.IsValid) { _delayInMilliseconds = (int)matroska.GetAudioTrackDelayMilliseconds(mkvAudioTrackNumbers[AudioTrackNumber]); } } catch (Exception exception) { SeLogger.Error(exception, $"Error getting delay from mkv: {labelVideoFileName.Text}"); _delayInMilliseconds = 0; } finally { matroska?.Dispose(); } } buttonRipWave_Click(null, null); } else if (_wavFileName != null) { FixWaveOnly(); } }
private void buttonRipWave_Click(object sender, EventArgs e) { if (listViewInputFiles.Items.Count == 0) { MessageBox.Show(Configuration.Settings.Language.BatchConvert.NothingToConvert); return; } _converting = true; buttonRipWave.Enabled = false; progressBar1.Style = ProgressBarStyle.Blocks; progressBar1.Maximum = listViewInputFiles.Items.Count; progressBar1.Value = 0; progressBar1.Visible = progressBar1.Maximum > 2; buttonInputBrowse.Enabled = false; buttonSearchFolder.Enabled = false; _abort = false; listViewInputFiles.BeginUpdate(); foreach (ListViewItem item in listViewInputFiles.Items) { item.SubItems[3].Text = "-"; } listViewInputFiles.EndUpdate(); Refresh(); int index = 0; while (index < listViewInputFiles.Items.Count && _abort == false) { var item = listViewInputFiles.Items[index]; Action <string> updateStatus = status => { item.SubItems[3].Text = status; Refresh(); }; updateStatus(Configuration.Settings.Language.AddWaveformBatch.ExtractingAudio); string fileName = item.Text; try { string targetFile = Path.Combine(Path.GetTempPath(), Guid.NewGuid() + ".wav"); Process process; try { process = AddWaveform.GetCommandLineProcess(fileName, -1, targetFile, Configuration.Settings.General.VlcWaveTranscodeSettings, out var encoderName); labelInfo.Text = encoderName; } catch (DllNotFoundException) { if (MessageBox.Show(Configuration.Settings.Language.AddWaveform.VlcMediaPlayerNotFound + Environment.NewLine + Environment.NewLine + Configuration.Settings.Language.AddWaveform.GoToVlcMediaPlayerHomePage, Configuration.Settings.Language.AddWaveform.VlcMediaPlayerNotFoundTitle, MessageBoxButtons.YesNo) == DialogResult.Yes) { UiUtil.OpenUrl("http://www.videolan.org/"); } buttonRipWave.Enabled = true; return; } process.Start(); while (!process.HasExited && !_abort) { Application.DoEvents(); } // check for delay in matroska files var audioTrackNames = new List <string>(); var mkvAudioTrackNumbers = new Dictionary <int, int>(); if (fileName.ToLowerInvariant().EndsWith(".mkv", StringComparison.OrdinalIgnoreCase)) { try { using (var matroska = new MatroskaFile(fileName)) { if (matroska.IsValid) { foreach (var track in matroska.GetTracks()) { if (track.IsAudio) { if (track.CodecId != null && track.Language != null) { audioTrackNames.Add("#" + track.TrackNumber + ": " + track.CodecId.Replace("\0", string.Empty) + " - " + track.Language.Replace("\0", string.Empty)); } else { audioTrackNames.Add("#" + track.TrackNumber); } mkvAudioTrackNumbers.Add(mkvAudioTrackNumbers.Count, track.TrackNumber); } } if (mkvAudioTrackNumbers.Count > 0) { _delayInMilliseconds = (int)matroska.GetAudioTrackDelayMilliseconds(mkvAudioTrackNumbers[0]); } } } } catch (Exception exception) { SeLogger.Error(exception, $"Error getting delay from mkv: {fileName}"); _delayInMilliseconds = 0; } } updateStatus(Configuration.Settings.Language.AddWaveformBatch.Calculating); MakeWaveformAndSpectrogram(fileName, targetFile, _delayInMilliseconds); if (checkBoxGenerateSceneChanges.Visible && checkBoxGenerateSceneChanges.Checked) { GenerateSceneChanges(fileName); } // cleanup try { File.Delete(targetFile); } catch { // don't show error about unsuccessful delete } IncrementAndShowProgress(); updateStatus(Configuration.Settings.Language.AddWaveformBatch.Done); } catch { IncrementAndShowProgress(); updateStatus(Configuration.Settings.Language.AddWaveformBatch.Error); } index++; } _converting = false; labelProgress.Text = string.Empty; labelInfo.Text = string.Empty; progressBar1.Visible = false; TaskbarList.SetProgressState(Owner.Handle, TaskbarButtonProgressFlags.NoProgress); buttonRipWave.Enabled = true; buttonInputBrowse.Enabled = true; buttonSearchFolder.Enabled = true; }
private void buttonOK_Click(object sender, EventArgs e) { _log = new StringBuilder(); buttonOK.Enabled = false; var oldFontSizeEnabled = numericUpDownFontSize.Enabled; numericUpDownFontSize.Enabled = false; using (var saveDialog = new SaveFileDialog { FileName = SuggestNewVideoFileName(), Filter = "MP4|*.mp4|Matroska|*.mkv|WebM|*.webm", AddExtension = true }) { if (saveDialog.ShowDialog(this) != DialogResult.OK) { buttonOK.Enabled = true; numericUpDownFontSize.Enabled = true; return; } VideoFileName = saveDialog.FileName; } if (File.Exists(VideoFileName)) { try { File.Delete(VideoFileName); } catch { MessageBox.Show($"Cannot overwrite video file { VideoFileName} - probably in use!"); buttonOK.Enabled = true; numericUpDownFontSize.Enabled = oldFontSizeEnabled; return; } } _totalFrames = (long)_videoInfo.TotalFrames; _log = new StringBuilder(); _log.AppendLine("Target file name: " + VideoFileName); _log.AppendLine("Video info width: " + _videoInfo.Width); _log.AppendLine("Video info width: " + _videoInfo.Height); _log.AppendLine("Video info total frames: " + _videoInfo.TotalFrames); _log.AppendLine("Video info total seconds: " + _videoInfo.TotalSeconds); labelFileName.Text = string.Format(LanguageSettings.Current.GenerateVideoWithBurnedInSubs.TargetFileName, VideoFileName); if (!_isAssa) { SetStyleForNonAssa(_assaSubtitle); } FixRightToLeft(_assaSubtitle); var format = new AdvancedSubStationAlpha(); var assaTempFileName = GetAssaFileName(_inputVideoFileName); FileUtil.WriteAllText(assaTempFileName, format.ToText(_assaSubtitle, null), new TextEncoding(Encoding.UTF8, "UTF8")); groupBoxSettings.Enabled = false; labelPleaseWait.Visible = true; if (_videoInfo.TotalFrames > 0) { progressBar1.Visible = true; } var stopWatch = Stopwatch.StartNew(); if (checkBoxTargetFileSize.Checked) { RunTwoPassEncoding(assaTempFileName); } else { RunOnePassEncoding(assaTempFileName); } progressBar1.Visible = false; labelPleaseWait.Visible = false; timer1.Stop(); MillisecondsEncoding = stopWatch.ElapsedMilliseconds; labelProgress.Text = string.Empty; groupBoxSettings.Enabled = true; try { File.Delete(assaTempFileName); } catch { // ignore } if (_abort) { DialogResult = DialogResult.Cancel; return; } if (!File.Exists(VideoFileName) || new FileInfo(VideoFileName).Length == 0) { SeLogger.Error(Environment.NewLine + "Generate hard subbed video failed: " + Environment.NewLine + _log); DialogResult = DialogResult.Cancel; return; } DialogResult = DialogResult.OK; }