diff --git a/src/Test/Logic/DimensionTest.cs b/src/Test/Logic/DimensionTest.cs
new file mode 100644
index 000000000..c43ad570c
--- /dev/null
+++ b/src/Test/Logic/DimensionTest.cs
@@ -0,0 +1,34 @@
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Nikse.SubtitleEdit.Core.Common;
+
+namespace Test.Logic
+{
+ [TestClass]
+ public class DimensionTest
+ {
+ [TestMethod]
+ public void InvalidTest()
+ {
+ var dimension = new Dimension();
+ Assert.AreEqual(0, dimension.Width);
+ Assert.AreEqual(0, dimension.Height);
+ Assert.IsTrue(!dimension.IsValid());
+ }
+
+ [TestMethod]
+ public void ValidTest()
+ {
+ var dimension = new Dimension(10, 10);
+ Assert.IsTrue(dimension.IsValid());
+ }
+
+ [TestMethod]
+ public void EqualityTest()
+ {
+ var dimensionOne = new Dimension();
+ var dimensionTwo = new Dimension();
+ Assert.AreEqual(dimensionOne, dimensionTwo);
+ Assert.IsTrue(dimensionOne == dimensionTwo);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Test/Test.csproj b/src/Test/Test.csproj
index 0bbe85949..c0c2f74a0 100644
--- a/src/Test/Test.csproj
+++ b/src/Test/Test.csproj
@@ -76,6 +76,7 @@
+
diff --git a/src/libse/Common/Dimension.cs b/src/libse/Common/Dimension.cs
new file mode 100644
index 000000000..e70de3674
--- /dev/null
+++ b/src/libse/Common/Dimension.cs
@@ -0,0 +1,40 @@
+using System;
+
+namespace Nikse.SubtitleEdit.Core.Common
+{
+ ///
+ /// Struct representing the dimensions of an object.
+ ///
+ public struct Dimension : IEquatable
+ {
+ public int Height { get; set; }
+ public int Width { get; set; }
+
+ public Dimension(int height, int width) => (Height, Width) = (height, width);
+
+ ///
+ /// Returns a string representation of the Dimension object, representing its height and width.
+ ///
+ /// A string representation of the Dimension object, in the format "height x width".
+ public override string ToString() => $"{Height}x{Width}";
+
+ public bool Equals(Dimension other) => Height == other.Height && Width == other.Width;
+ public override bool Equals(object obj) => obj is Dimension other && Equals(other);
+ public static bool operator ==(Dimension left, Dimension right) => left.Equals(right);
+ public static bool operator !=(Dimension left, Dimension right) => !(left == right);
+
+ ///
+ /// Checks if the dimension (height and width) is valid.
+ ///
+ /// True if the dimension is valid; otherwise, false.
+ public bool IsValid() => Width > 0 && Height > 0;
+
+ public override int GetHashCode()
+ {
+ unchecked
+ {
+ return (Height * 397) ^ Width;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/libse/Common/FfmpegMediaInfo.cs b/src/libse/Common/FfmpegMediaInfo.cs
index d4ff98e53..a45176794 100644
--- a/src/libse/Common/FfmpegMediaInfo.cs
+++ b/src/libse/Common/FfmpegMediaInfo.cs
@@ -11,8 +11,8 @@ namespace Nikse.SubtitleEdit.Core.Common
public class FfmpegMediaInfo
{
public List Tracks { get; set; }
- public int VideoWidth { get; set; }
- public int VideoHeight { get; set; }
+
+ public Dimension Dimension { get; set; }
private static readonly Regex ResolutionRegex = new Regex(@"\d\d+x\d\d+", RegexOptions.Compiled);
@@ -65,13 +65,12 @@ namespace Nikse.SubtitleEdit.Core.Common
if (resolutionMatch.Success)
{
var parts = resolutionMatch.Value.Split('x');
- if (info.VideoWidth == 0 &&
+ if (info.Dimension.Width == 0 &&
parts.Length == 2 &&
int.TryParse(parts[0], out var w) &&
int.TryParse(parts[1], out var h))
{
- info.VideoWidth = w;
- info.VideoHeight = h;
+ info.Dimension = new Dimension(h, w);
}
}
diff --git a/src/libse/Common/FileUtil.cs b/src/libse/Common/FileUtil.cs
index 7da4577ae..f9fa0760c 100644
--- a/src/libse/Common/FileUtil.cs
+++ b/src/libse/Common/FileUtil.cs
@@ -6,6 +6,7 @@ using Nikse.SubtitleEdit.Core.VobSub;
using System;
using System.Collections.Generic;
using System.IO;
+using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
@@ -707,5 +708,53 @@ namespace Nikse.SubtitleEdit.Core.Common
return false;
}
+
+ public static string TryLocateSubtitleFile(string path, string videoFileName)
+ {
+ // search in these subdirectories: \Subs;\Sub;\Subtitles;
+ var knownSubtitleDirectories = new[]
+ {
+ path, Path.Combine(path, "Subs"), Path.Combine(path, "Sub"), Path.Combine(path, "Subtitles")
+ };
+
+ // handles if video file was sent with full path
+ if (Path.IsPathRooted(videoFileName))
+ {
+ videoFileName = Path.GetFileName(videoFileName);
+ }
+
+ foreach (var knownSubtitleDirectory in knownSubtitleDirectories)
+ {
+ if (!Directory.Exists(knownSubtitleDirectory))
+ {
+ continue;
+ }
+
+ // try to locate subtitle file that has the same name as the video file
+ var defaultSubtitles = new[]
+ {
+ Path.Combine(knownSubtitleDirectory, Path.ChangeExtension(videoFileName, ".ass")),
+ Path.Combine(knownSubtitleDirectory, Path.ChangeExtension(videoFileName, ".srt"))
+ };
+ foreach (var defaultSubtitle in defaultSubtitles)
+ {
+ if (File.Exists(defaultSubtitle))
+ {
+ return defaultSubtitle;
+ }
+ }
+
+ // get first subtitle in path with extension .ass or .srt
+ var assEnumerable = Directory.EnumerateFiles(knownSubtitleDirectory, "*.ass", SearchOption.TopDirectoryOnly);
+ var subRipEnumerable = Directory.EnumerateFiles(knownSubtitleDirectory, "*.srt", SearchOption.TopDirectoryOnly);
+ var subtitleFile = assEnumerable.Concat(subRipEnumerable).FirstOrDefault();
+ if (!string.IsNullOrEmpty(subtitleFile))
+ {
+ return subtitleFile;
+ }
+ }
+
+ return string.Empty;
+ }
}
}
diff --git a/src/ui/Forms/GenerateVideoWithHardSubs.cs b/src/ui/Forms/GenerateVideoWithHardSubs.cs
index 722e7ca6a..e5b64fa2e 100644
--- a/src/ui/Forms/GenerateVideoWithHardSubs.cs
+++ b/src/ui/Forms/GenerateVideoWithHardSubs.cs
@@ -2139,100 +2139,88 @@ namespace Nikse.SubtitleEdit.Forms
}
}
- private void AddInputFile(string fileName)
+ private void AddInputFile(string videoFileName)
{
- if (string.IsNullOrEmpty(fileName))
+ if (string.IsNullOrEmpty(videoFileName))
{
return;
}
- var ext = Path.GetExtension(fileName).ToLowerInvariant();
- if ((Utilities.AudioFileExtensions.Contains(ext) || Utilities.VideoFileExtensions.Contains(ext)) && File.Exists(fileName))
+ var ext = Path.GetExtension(videoFileName).ToLowerInvariant();
+ if ((Utilities.AudioFileExtensions.Contains(ext) || Utilities.VideoFileExtensions.Contains(ext)) && File.Exists(videoFileName))
{
- var item = new BatchVideoAndSub();
- item.VideoFileName = fileName;
- item.VideoFileSizeInBytes = new FileInfo(fileName).Length;
-
- var path = Path.GetDirectoryName(fileName);
- var fileNameNoExt = Path.GetFileNameWithoutExtension(fileName);
- var subFileName = Path.ChangeExtension(fileName, ".ass");
-
- if (!File.Exists(subFileName))
+ var videoDimension = GetVideoDimension(videoFileName);
+ if (!videoDimension.IsValid())
{
- subFileName = Path.ChangeExtension(fileName, ".srt");
+ return;
}
-
- if (!File.Exists(subFileName))
- {
- var files = Directory.GetFiles(path, fileNameNoExt + "*.ass");
- if (files.Length > 0)
- {
- subFileName = files[0];
- }
- }
-
- if (!File.Exists(subFileName))
- {
- var files = Directory.GetFiles(path, fileNameNoExt + "*.srt");
- if (files.Length > 0)
- {
- subFileName = files[0];
- }
- }
-
- if (File.Exists(subFileName))
- {
- item.SubtitleFileName = subFileName;
- item.SubtitleFileFileSizeInBytes = new FileInfo(subFileName).Length;
- }
-
- var mediaInfo = FfmpegMediaInfo.Parse(fileName);
- int width;
- int height;
- if (mediaInfo.VideoWidth > 0 && mediaInfo.VideoHeight > 0)
- {
- width = mediaInfo.VideoWidth;
- height = mediaInfo.VideoHeight;
- }
- else
- {
- var vInfo = new VideoInfo { Success = false };
- if (fileName.EndsWith(".mp4", StringComparison.OrdinalIgnoreCase))
- {
- vInfo = QuartsPlayer.GetVideoInfo(fileName);
- if (!vInfo.Success)
- {
- vInfo = LibMpvDynamic.GetVideoInfo(fileName);
- }
- }
-
- if (!vInfo.Success)
- {
- vInfo = UiUtil.GetVideoInfo(fileName);
- }
-
- width = vInfo.Width;
- height = vInfo.Height;
- }
-
- if (width == 0 || height == 0)
- {
- SeLogger.Error("Skipping burn-in file with no video: " + fileName);
- return; // skip audio or damaged files
- }
-
- var listViewItem = new ListViewItem(fileName);
- listViewItem.Tag = item;
- listViewItem.SubItems.Add($"{width}x{height}");
- var s = Utilities.FormatBytesToDisplayFileSize(item.VideoFileSizeInBytes);
+
+ var batchVideoAndSub = CreateBatchVideoAndSub(videoFileName);
+ var listViewItem = new ListViewItem(videoFileName) { Tag = batchVideoAndSub };
+ listViewItem.SubItems.Add(videoDimension.ToString());
+ var s = Utilities.FormatBytesToDisplayFileSize(batchVideoAndSub.VideoFileSizeInBytes);
listViewItem.SubItems.Add(s);
- listViewItem.SubItems.Add(Path.GetFileName(item.SubtitleFileName));
+ listViewItem.SubItems.Add(Path.GetFileName(batchVideoAndSub.SubtitleFileName));
listViewItem.SubItems.Add(string.Empty);
listViewBatch.Items.Add(listViewItem);
- _batchVideoAndSubList.Add(item);
+ _batchVideoAndSubList.Add(batchVideoAndSub);
}
}
+ private BatchVideoAndSub CreateBatchVideoAndSub(string videoFileName)
+ {
+ var batchVideoAndSub = new BatchVideoAndSub
+ {
+ VideoFileName = videoFileName,
+ VideoFileSizeInBytes = new FileInfo(videoFileName).Length
+ };
+
+ var path = Path.GetDirectoryName(videoFileName);
+ // try to locate subtitle file for the input vide file
+ var subtitleFile = FileUtil.TryLocateSubtitleFile(path, videoFileName);
+ if (File.Exists(subtitleFile))
+ {
+ batchVideoAndSub.SubtitleFileName = subtitleFile;
+ batchVideoAndSub.SubtitleFileFileSizeInBytes = new FileInfo(subtitleFile).Length;
+ }
+
+ return batchVideoAndSub;
+ }
+
+ private Dimension GetVideoDimension(string videoFileName)
+ {
+ var mediaInfo = FfmpegMediaInfo.Parse(videoFileName);
+ if (mediaInfo.Dimension.IsValid())
+ {
+ return mediaInfo.Dimension;
+ }
+
+ var vInfo = new VideoInfo { Success = false };
+ if (videoFileName.EndsWith(".mp4", StringComparison.OrdinalIgnoreCase))
+ {
+ vInfo = QuartsPlayer.GetVideoInfo(videoFileName);
+ if (!vInfo.Success)
+ {
+ vInfo = LibMpvDynamic.GetVideoInfo(videoFileName);
+ }
+ }
+
+ if (!vInfo.Success)
+ {
+ vInfo = UiUtil.GetVideoInfo(videoFileName);
+ }
+
+ var dimension = new Dimension(vInfo.Height, vInfo.Width);
+
+ // skip audio or damaged files
+ if (!dimension.IsValid())
+ {
+ SeLogger.Error("Skipping burn-in file with no video: " + videoFileName);
+ }
+
+ return dimension;
+ }
+
private void deleteToolStripMenuItem_Click(object sender, EventArgs e)
{
var indices = new List();