9 Commits

Author SHA1 Message Date
Imrayya fb75071c44 Merge pull request #2 from kaiju466/feature/kaiju466/add-cli-options-and-3d-mode
feat: add CLI options and support SBS/OU/Anaglyph + experimental GUI
2026-06-24 14:46:32 +07:00
Emrick, Joshua 580c0a534d Merge branch 'feature/kaiju466/add-cli-options-and-3d-mode' of https://github.com/kaiju466/SRTto3Dsubtitles into feature/kaiju466/add-cli-options-and-3d-mode 2026-06-15 10:00:27 -04:00
kaiju466 ea0574ffb2 Update README.md 2026-06-15 09:56:57 -04:00
Emrick, Joshua 5e4e907a2c Add resolution-aware subtitle scaling and configurable layout defaults
- replace fixed RG subtitle bottom positioning with resolution-scaled Y offset
- add centralized ScaleX, ScaleY, and ScaleFont helpers
- scale RG horizontal eye offset based on output width
- scale font size, SBS margins, and OU margins based on output/base resolution
- change default baseline behavior from legacy 384x288 to tunable base resolution
- add BaseResX/BaseResY options with 1280x720 defaults
- add CLI options for:
  - --baseresx
  - --baseresy
  - --bottomoffset
  - --sbssidemargin
  - --outopmargin
  - --verticalmargin
- replace remaining layout magic numbers with configurable options:
  - BottomOffset
  - SbsSideMargin
  - OuTopMargin
  - VerticalMargin
  - FontSize
  - OffsetX
- preserve original numeric defaults for layout settings when not specified (based off of my personal experiences and preferences.
- update WinForms designer to expose new converter settings
- update WinForms code-behind to pass new options to Converter.Main
- prefill GUI controls with converter-aligned default values
- improve mode-based UI enable/disable behavior for SBS, OU, and RG settings
- prepare shared-defaults approach via ConverterDefaults for keeping GUI and converter defaults in sync
2026-06-15 09:50:26 -04:00
Emrick, Joshua 470e23291f feat: add red-green 3D mode and Windows Forms GUI
- add rg (red-green) anaglyph subtitle mode with configurable horizontal offset
- extend CLI mode handling to support sbs, ou, and rg
- add offsetx option for anaglyph subtitle positioning
- add Windows Forms GUI project for configuring and running conversions
- add file pickers for input/output paths in the GUI
- add GUI controls for mode, resolution, font size, and offset
- add status output and mode-aware UI behavior in the GUI
- update mode selection handling to support user-friendly display labels
2026-06-09 11:16:53 -04:00
Emrick, Joshua 327bc071aa feat: add CLI options and support SBS/OU 3D subtitle modes
- add named CLI arguments for mode, resolution, font size, and output path
- support stereo modes: sbs (side-by-side) and ou (over-under)
- write output .ass files next to the input file by default
- add console logging, usage help, and argument validation
- update ASS style generation for SBS and OU layouts
- rename OU styles to Top and Bottom
- fix HTML font color conversion to proper ASS color ordering
- refactor runtime settings into an Options class

Side Note: As a hearing impared person, I love this project and am glad it exists and I dont have to start from scratch.
2026-06-09 09:34:24 -04:00
Imrayya 9d51c5f554 Merge pull request #1 from fabio-noga/utf8
Add UTF-8 support and small fix
2025-10-19 13:16:15 +02:00
Fábio Nogueira b3f9bfb074 Fix dialog line when it's a number & Fix new line
Fix dialog line when the dialog is just a number | Fix new line in dialog that happens on the same line
2025-10-16 18:51:28 +01:00
Fábio Nogueira 28f9e4f8f9 Add UTF-8 support and small fix
that j==1 comes from an issue found while using this where a subtitle would be just a number (for example "2025") and it would pass the int.TryParse(line, out int k) check. With j==1 it always knows that it should be a timestamp
2025-10-13 20:31:58 +01:00
14 changed files with 1960 additions and 145 deletions
+9 -3
View File
@@ -1,9 +1,11 @@
Microsoft Visual Studio Solution File, Format Version 12.00 Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16 # Visual Studio Version 17
VisualStudioVersion = 16.0.30523.141 VisualStudioVersion = 17.11.35208.52
MinimumVisualStudioVersion = 10.0.40219.1 MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConvertSRTto3DASS", "ConvertSRTto3DASS\ConvertSRTto3DASS.csproj", "{7D7925DE-ADBD-4A26-B12B-8F12B68D3BFE}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConvertSRTto3DASS", "ConvertSRTto3DASS\ConvertSRTto3DASS.csproj", "{7D7925DE-ADBD-4A26-B12B-8F12B68D3BFE}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConvertSRTto3DASSGUI", "ConvertSRTto3DASSGUI\ConvertSRTto3DASSGUI.csproj", "{8C44F434-2097-4FA3-BEE1-9569FB99F49C}"
EndProject EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -15,6 +17,10 @@ Global
{7D7925DE-ADBD-4A26-B12B-8F12B68D3BFE}.Debug|Any CPU.Build.0 = Debug|Any CPU {7D7925DE-ADBD-4A26-B12B-8F12B68D3BFE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7D7925DE-ADBD-4A26-B12B-8F12B68D3BFE}.Release|Any CPU.ActiveCfg = Release|Any CPU {7D7925DE-ADBD-4A26-B12B-8F12B68D3BFE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7D7925DE-ADBD-4A26-B12B-8F12B68D3BFE}.Release|Any CPU.Build.0 = Release|Any CPU {7D7925DE-ADBD-4A26-B12B-8F12B68D3BFE}.Release|Any CPU.Build.0 = Release|Any CPU
{8C44F434-2097-4FA3-BEE1-9569FB99F49C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8C44F434-2097-4FA3-BEE1-9569FB99F49C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8C44F434-2097-4FA3-BEE1-9569FB99F49C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8C44F434-2097-4FA3-BEE1-9569FB99F49C}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE
+658 -136
View File
@@ -1,115 +1,464 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
//SSA/ASS specification v4+ http://www.tcax.org/docs/ass-specs.htm // SSA/ASS specification v4+ http://www.tcax.org/docs/ass-specs.htm
//SRT (SubRip) specification https://en.wikipedia.org/wiki/SubRip // SRT (SubRip) specification https://en.wikipedia.org/wiki/SubRip
namespace ConvertSRTto3DASS namespace ConvertSRTto3DASS
{ {
class Converter public class Converter
{ {
private enum StereoMode
static void Main(string[] args)
{ {
SBS,
var extracted = ExtractSubFromSRT(args[0]); OU,
var style = CreateStandardStyle(); RG // Experimental
var header = CreateHeader(args[0]);
var events = ProcessSubs(extracted);
var finished = "[Script Info]\n" + header + "\n\n[V4+ Styles]\n" + style + "\n\n[Events]\n" + events;
File.WriteAllText(Path.GetFileNameWithoutExtension(args[0]) + ".ass", finished);
} }
//Is there a better way to do it? public static class ConverterDefaults
private static Dictionary<Regex, string> regexReplacementDict = {
new Dictionary<Regex, string> { /// <summary>
{new Regex("<b>"), "{\\b1}"}, ///720 as default is arbitary,it's my favorite resolution for space saving and most mobile 3d viewing doesn't benefit from much higher (IE google cardboard or Meta Quest Headset).
{new Regex("(</b>)"),"{\\b0}"}, /// </summary>
{new Regex("(<i>)"),"{\\i1}"}, public const int ResX = 1280;
{new Regex("(</i>)"),"{\\i0}"}, public const int ResY = 720;
{new Regex("(<u>)"),"{\\u1}" },
{new Regex("(</u>)"),"{\\u0}"},
{new Regex("(</font>)"),"{\\c&HFFFFFF&}"} //TODO custom colors. When you add custom colors, it needs to change this too
public const int BaseResX = 1280;
public const int BaseResY = 720;
public const int FontSize = 16;
public const int OffsetX = 4;
public const int BottomOffset = 18;
public const int SbsSideMargin = 640;
public const int OuTopMargin = 385;
public const int VerticalMargin = 25;
public const string DefaultMode = "sbs";
}
private class Options
{
public string InputPath { get; set; }
public string OutputPath { get; set; }
public StereoMode Mode { get; set; } = StereoMode.SBS;
public int ResX { get; set; } = ConverterDefaults.ResX;
public int ResY { get; set; } = ConverterDefaults.ResY;
public int BaseResX { get; set; } = ConverterDefaults.BaseResX;
public int BaseResY { get; set; } = ConverterDefaults.BaseResY;
public int FontSize { get; set; } = ConverterDefaults.FontSize;
public int OffsetX { get; set; } = ConverterDefaults.OffsetX;
public int BottomOffset { get; set; } = ConverterDefaults.BottomOffset;
public int SbsSideMargin { get; set; } = ConverterDefaults.SbsSideMargin;
public int OuTopMargin { get; set; } = ConverterDefaults.OuTopMargin;
public int VerticalMargin { get; set; } = ConverterDefaults.VerticalMargin;
}
private static readonly Dictionary<Regex, string> RegexReplacementDict =
new Dictionary<Regex, string>
{
{ new Regex("<b>", RegexOptions.IgnoreCase), "{\\b1}" },
{ new Regex("</b>", RegexOptions.IgnoreCase), "{\\b0}" },
{ new Regex("<i>", RegexOptions.IgnoreCase), "{\\i1}" },
{ new Regex("</i>", RegexOptions.IgnoreCase), "{\\i0}" },
{ new Regex("<u>", RegexOptions.IgnoreCase), "{\\u1}" },
{ new Regex("</u>", RegexOptions.IgnoreCase), "{\\u0}" },
{ new Regex("</font>", RegexOptions.IgnoreCase), "{\\c&HFFFFFF&}" }
}; };
private static Regex color = new Regex("<font color=\"#.{6}\">");
//TODO Add positional data to the formatting. private static readonly Regex ColorRegex =
new Regex("<font color=\"#([0-9A-Fa-f]{6})\">", RegexOptions.IgnoreCase);
private static readonly Regex RemoveFormattingRegex =
new Regex("<.+?>|(\\r)", RegexOptions.IgnoreCase);
public static void Main(string[] args)
{
try
{
var options = ParseArguments(args);
if (options == null)
return;
if (!File.Exists(options.InputPath))
{
Console.Error.WriteLine("Input file not found: " + options.InputPath);
return;
}
if (string.IsNullOrWhiteSpace(options.OutputPath))
{
options.OutputPath = Path.Combine(
Path.GetDirectoryName(options.InputPath) ?? string.Empty,
Path.GetFileNameWithoutExtension(options.InputPath) + ".ass");
}
Console.WriteLine("Input: " + options.InputPath);
Console.WriteLine("Output: " + options.OutputPath);
Console.WriteLine("Mode: " + options.Mode);
Console.WriteLine("Resolution: " + options.ResX + "x" + options.ResY);
Console.WriteLine("Base Res: " + options.BaseResX + "x" + options.BaseResY);
Console.WriteLine("Font size: " + options.FontSize);
Console.WriteLine("OffsetX: " + options.OffsetX);
Console.WriteLine("BottomOffset: " + options.BottomOffset);
Console.WriteLine("SbsSideMargin: " + options.SbsSideMargin);
Console.WriteLine("OuTopMargin: " + options.OuTopMargin);
Console.WriteLine("VerticalMargin: " + options.VerticalMargin);
var extracted = ExtractSubFromSRT(options.InputPath);
Console.WriteLine("Subtitle blocks parsed: " + extracted.Count);
var style = CreateStandardStyle(options);
var header = CreateHeader(options.InputPath, options.ResY, options.ResX);
var eventsText = ProcessSubs(extracted, options);
var finished =
"[Script Info]\n" +
header +
"\n\n[V4+ Styles]\n" +
style +
"\n\n[Events]\n" +
eventsText;
File.WriteAllText(
options.OutputPath,
finished,
new UTF8Encoding(encoderShouldEmitUTF8Identifier: true));
Console.WriteLine("Conversion complete.");
}
catch (Exception ex)
{
Console.Error.WriteLine("ERROR: " + ex.Message);
Console.Error.WriteLine(ex.ToString());
}
}
private static Options ParseArguments(string[] args)
{
if (args == null || args.Length == 0)
{
PrintUsage();
return null;
}
var options = new Options();
int i = 0;
if (args[0].StartsWith("--"))
{
Console.Error.WriteLine("First argument must be the input .srt file.");
PrintUsage();
return null;
}
options.InputPath = args[0];
i = 1;
while (i < args.Length)
{
string arg = args[i].Trim();
switch (arg.ToLowerInvariant())
{
case "--mode":
EnsureValueExists(args, i, "--mode");
options.Mode = ParseStereoMode(args[i + 1]);
i += 2;
break;
case "--resx":
EnsureValueExists(args, i, "--resx");
options.ResX = ParsePositiveInt(args[i + 1], "--resx");
i += 2;
break;
case "--resy":
EnsureValueExists(args, i, "--resy");
options.ResY = ParsePositiveInt(args[i + 1], "--resy");
i += 2;
break;
case "--baseresx":
EnsureValueExists(args, i, "--baseresx");
options.BaseResX = ParsePositiveInt(args[i + 1], "--baseresx");
i += 2;
break;
case "--baseresy":
EnsureValueExists(args, i, "--baseresy");
options.BaseResY = ParsePositiveInt(args[i + 1], "--baseresy");
i += 2;
break;
case "--fontsize":
EnsureValueExists(args, i, "--fontsize");
options.FontSize = ParsePositiveInt(args[i + 1], "--fontsize");
i += 2;
break;
case "--offsetx":
EnsureValueExists(args, i, "--offsetx");
options.OffsetX = ParseNonNegativeInt(args[i + 1], "--offsetx");
i += 2;
break;
case "--bottomoffset":
EnsureValueExists(args, i, "--bottomoffset");
options.BottomOffset = ParseNonNegativeInt(args[i + 1], "--bottomoffset");
i += 2;
break;
case "--sbssidemargin":
EnsureValueExists(args, i, "--sbssidemargin");
options.SbsSideMargin = ParseNonNegativeInt(args[i + 1], "--sbssidemargin");
i += 2;
break;
case "--outopmargin":
EnsureValueExists(args, i, "--outopmargin");
options.OuTopMargin = ParseNonNegativeInt(args[i + 1], "--outopmargin");
i += 2;
break;
case "--verticalmargin":
EnsureValueExists(args, i, "--verticalmargin");
options.VerticalMargin = ParseNonNegativeInt(args[i + 1], "--verticalmargin");
i += 2;
break;
case "--output":
EnsureValueExists(args, i, "--output");
options.OutputPath = args[i + 1];
i += 2;
break;
case "--help":
case "-h":
case "/?":
PrintUsage();
return null;
default:
throw new ArgumentException("Unknown argument: " + arg);
}
}
return options;
}
private static void EnsureValueExists(string[] args, int index, string optionName)
{
if (index + 1 >= args.Length || args[index + 1].StartsWith("--"))
throw new ArgumentException("Missing value for " + optionName);
}
private static int ParsePositiveInt(string value, string optionName)
{
if (!int.TryParse(value, out int parsed) || parsed <= 0)
throw new ArgumentException("Invalid value for " + optionName + ": " + value);
return parsed;
}
private static int ParseNonNegativeInt(string value, string optionName)
{
if (!int.TryParse(value, out int parsed) || parsed < 0)
throw new ArgumentException("Invalid value for " + optionName + ": " + value);
return parsed;
}
private static void PrintUsage()
{
Console.WriteLine("Usage:");
Console.WriteLine(" ConvertSRTto3DASS.exe <input.srt> [options]");
Console.WriteLine();
Console.WriteLine("Options:");
Console.WriteLine(" --mode sbs|ou|rg");
Console.WriteLine(" --resx <number>");
Console.WriteLine(" --resy <number>");
Console.WriteLine(" --baseresx <number> (scaling reference width, default 1280)");
Console.WriteLine(" --baseresy <number> (scaling reference height, default 720)");
Console.WriteLine(" --fontsize <number>");
Console.WriteLine(" --offsetx <number> (RG eye separation)");
Console.WriteLine(" --bottomoffset <number> (RG bottom offset)");
Console.WriteLine(" --sbssidemargin <number> (SBS side margin)");
Console.WriteLine(" --outopmargin <number> (OU top subtitle margin)");
Console.WriteLine(" --verticalmargin <number> (general vertical/bottom margin)");
Console.WriteLine(" --output <path>");
Console.WriteLine();
Console.WriteLine("Examples:");
Console.WriteLine(@" ConvertSRTto3DASS.exe ""movie.srt"" --mode sbs");
Console.WriteLine(@" ConvertSRTto3DASS.exe ""movie.srt"" --mode ou --resx 1280 --resy 720");
Console.WriteLine(@" ConvertSRTto3DASS.exe ""movie.srt"" --mode rg --offsetx 6 --bottomoffset 24");
Console.WriteLine(@" ConvertSRTto3DASS.exe ""movie.srt"" --resx 1920 --resy 1080 --baseresx 1280 --baseresy 720");
Console.WriteLine(@" ConvertSRTto3DASS.exe ""movie.srt"" --sbssidemargin 220 --verticalmargin 16");
Console.WriteLine(@" ConvertSRTto3DASS.exe ""movie.srt"" --outopmargin 180 --fontsize 20 --output ""movie_custom.ass""");
}
private static StereoMode ParseStereoMode(string mode)
{
if (string.IsNullOrWhiteSpace(mode))
return StereoMode.SBS;
switch (mode.Trim().ToLowerInvariant())
{
case "sbs":
case "sidebyside":
case "side-by-side":
return StereoMode.SBS;
case "ou":
case "overunder":
case "over-under":
case "tab":
case "topandbottom":
case "top-and-bottom":
return StereoMode.OU;
case "rg":
case "redgreen":
case "red-green":
case "anaglyph":
case "anaglyph-rg":
return StereoMode.RG;
default:
throw new ArgumentException(
"Invalid 3D type '" + mode + "'. Valid values are: sbs, ou, rg");
}
}
private static int ScaleX(int value, Options options)
{
return (int)Math.Round(value * (options.ResX / (double)options.BaseResX));
}
private static int ScaleY(int value, Options options)
{
return (int)Math.Round(value * (options.ResY / (double)options.BaseResY));
}
private static int ScaleFont(int fontSize, Options options)
{
return Math.Max(1, ScaleY(fontSize, options));
}
private static string ChangeFormatting(string line) private static string ChangeFormatting(string line)
{ {
foreach (var tuple in regexReplacementDict) foreach (var tuple in RegexReplacementDict)
{ {
line = tuple.Key.Replace(line, tuple.Value); line = tuple.Key.Replace(line, tuple.Value);
} }
while (color.IsMatch(line)) while (ColorRegex.IsMatch(line))
{ {
var match = color.Match(line); var match = ColorRegex.Match(line);
string str_match = match.Value; string rgb = match.Groups[1].Value; // RRGGBB
var color_str = str_match.Substring(14, 6); //RGB value in HEX
//ASS uses RGB value, but in reverse order so got to reverse it string rr = rgb.Substring(0, 2);
var char_array = color_str.ToCharArray(); string gg = rgb.Substring(2, 2);
Array.Reverse(char_array); string bb = rgb.Substring(4, 2);
color_str = new string(char_array);
line = color.Replace(line, "{\\c&" + color_str + "&}");
// ASS expects BBGGRR
string assColor = bb + gg + rr;
line = ColorRegex.Replace(line, "{\\c&H" + assColor + "&}", 1);
} }
return removeFormatting(line); return RemoveFormatting(line);
} }
private static string RemoveFormatting(string line)
//TODO: remove this and use the above method instead where it actually uses the formatting of the file
private static Regex reg = new Regex("<.+?>|(\\r)"); //Used to remove html tags used and line breaks
private static string removeFormatting(string line)
{ {
var replacement = reg.Replace(line, ""); return RemoveFormattingRegex.Replace(line, "");
return replacement;
} }
private static string ProcessSubs(List<Tuple<string, string, string, string>> srt, Options options)
private static string ProcessSubs(List<Tuple<string, string, string, string>> srt)
{ {
string endResult = "Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text\n"; string endResult = "Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text\n";
foreach (var events in srt) foreach (var events in srt)
{ {
var start = ConvertTimeStamp(events.Item1); var start = ConvertTimeStamp(events.Item1);
var end = ConvertTimeStamp(events.Item2); var end = ConvertTimeStamp(events.Item2);
var text = events.Item3;
//First layer, for the right eye if (options.Mode == StereoMode.SBS)
var line = "Dialogue: " + 0 + "," + start + "," + end + ",Right,,0,0,0,," + events.Item3 + "\n"; {
//Second layer, for the left eye var line = "Dialogue: 0," + start + "," + end + ",Right,,0,0,0,," + text + "\n";
line += "Dialogue: " + 1 + "," + start + "," + end + ",Left,,0,0,0,," + events.Item3; line += "Dialogue: 1," + start + "," + end + ",Left,,0,0,0,," + text;
endResult += line + "\n";
}
else if (options.Mode == StereoMode.OU)
{
var line = "Dialogue: 0," + start + "," + end + ",Top,,0,0,0,," + text + "\n";
line += "Dialogue: 1," + start + "," + end + ",Bottom,,0,0,0,," + text;
endResult += line + "\n";
}
else if (options.Mode == StereoMode.RG)
{
int centerX = options.ResX / 2;
int scaledBottomOffset = ScaleY(options.BottomOffset, options);
int y = options.ResY - scaledBottomOffset;
endResult += line + "\n"; int scaledOffsetX = ScaleX(options.OffsetX, options);
int redX = centerX - scaledOffsetX;
int greenX = centerX + scaledOffsetX;
string redText = "{\\an2\\pos(" + redX + "," + y + ")}" + text;
string greenText = "{\\an2\\pos(" + greenX + "," + y + ")}" + text;
var line = "Dialogue: 0," + start + "," + end + ",RedEye,,0,0,0,," + redText + "\n";
line += "Dialogue: 1," + start + "," + end + ",GreenEye,,0,0,0,," + greenText;
endResult += line + "\n";
}
} }
return endResult; return endResult;
} }
private static string ConvertTimeStamp(string timeStamp) private static string ConvertTimeStamp(string timeStamp)
{ {
//Change double digit hour (for .srt) to single digit hour marker (for .ass) <- very crude
var tmp = timeStamp.Substring(1); var tmp = timeStamp.Substring(1);
tmp = tmp.Substring(0, tmp.Length - 1);
//Change thousands of a second hunderdth second
tmp = tmp.Substring(0, tmp.Length - 1);//TODO: Do actual rounding
return tmp.Replace(",", "."); return tmp.Replace(",", ".");
} }
//TODO: Make this human readable private static string CreateStandardStyle(Options options)
//TODO: Add adjustable parameters
private static string CreateStandardStyle()
{ {
string style = "Format: " + int scaledFontSize = ScaleFont(options.FontSize, options);
switch (options.Mode)
{
case StereoMode.SBS:
return CreateSbsStyle(scaledFontSize, options);
case StereoMode.OU:
return CreateOuStyle(scaledFontSize, options);
case StereoMode.RG:
return CreateRgStyle(scaledFontSize, options);
default:
throw new ArgumentOutOfRangeException(nameof(options.Mode));
}
}
private static string CreateSbsStyle(int fontSize, Options options)
{
int sideMargin = ScaleX(options.SbsSideMargin, options);
int verticalMargin = ScaleY(options.VerticalMargin, options);
string style =
"Format: " +
"Name, " + "Name, " +
"Fontname, " + "Fontname, " +
"Fontsize, " + "Fontsize, " +
@@ -137,11 +486,11 @@ namespace ConvertSRTto3DASS
"Style: " + "Style: " +
"Right," + "Right," +
"Arial," + "Arial," +
"16," + fontSize + "," +
"&Hffffff," + "&HFFFFFF," +
"&Hffffff," + "&HFFFFFF," +
"&H0," + "&H000000," +
"&H0," + "&H000000," +
"0," + "0," +
"0," + "0," +
"0," + "0," +
@@ -154,20 +503,19 @@ namespace ConvertSRTto3DASS
"1," + "1," +
"0," + "0," +
"2," + "2," +
"192," + sideMargin + "," +
"0," + "0," +
"10," + verticalMargin + "," +
"0\n" + "0\n" +
"Style: " + "Style: " +
"Left," + "Left," +
"Arial," + "Arial," +
"16," + fontSize + "," +
"&Hffffff," + "&HFFFFFF," +
"&Hffffff," + "&HFFFFFF," +
"&H0," + "&H000000," +
"&H0," + "&H000000," +
"0," + "0," +
"0," + "0," +
"0," + "0," +
@@ -181,97 +529,271 @@ namespace ConvertSRTto3DASS
"0," + "0," +
"2," + "2," +
"0," + "0," +
"192 ," + sideMargin + "," +
"10," + verticalMargin + "," +
"0"; "0";
return style; return style;
} }
//TODO: create a system where you can actually give paramaters to it private static string CreateOuStyle(int fontSize, Options options)
private static string CreateHeader(string file, int resY = 288, int resX = 384) {
int bottomMargin = ScaleY(options.VerticalMargin, options);
int topMargin = ScaleY(options.OuTopMargin, options);
string style =
"Format: " +
"Name, " +
"Fontname, " +
"Fontsize, " +
"PrimaryColour, " +
"SecondaryColour, " +
"OutlineColour, " +
"BackColour, " +
"Bold, " +
"Italic, " +
"Underline, " +
"StrikeOut, " +
"ScaleX, " +
"ScaleY, " +
"Spacing, " +
"Angle, " +
"BorderStyle, " +
"Outline, " +
"Shadow, " +
"Alignment, " +
"MarginL, " +
"MarginR, " +
"MarginV, " +
"Encoding\n" +
"Style: " +
"Top," +
"Arial," +
fontSize + "," +
"&HFFFFFF," +
"&HFFFFFF," +
"&H000000," +
"&H000000," +
"0," +
"0," +
"0," +
"0," +
"100," +
"100," +
"0," +
"0," +
"1," +
"1," +
"0," +
"2," +
"0," +
"0," +
topMargin + "," +
"0\n" +
"Style: " +
"Bottom," +
"Arial," +
fontSize + "," +
"&HFFFFFF," +
"&HFFFFFF," +
"&H000000," +
"&H000000," +
"0," +
"0," +
"0," +
"0," +
"100," +
"100," +
"0," +
"0," +
"1," +
"1," +
"0," +
"2," +
"0," +
"0," +
bottomMargin + "," +
"0";
return style;
}
private static string CreateRgStyle(int fontSize, Options options)
{
int verticalMargin = ScaleY(options.VerticalMargin, options);
string style =
"Format: " +
"Name, " +
"Fontname, " +
"Fontsize, " +
"PrimaryColour, " +
"SecondaryColour, " +
"OutlineColour, " +
"BackColour, " +
"Bold, " +
"Italic, " +
"Underline, " +
"StrikeOut, " +
"ScaleX, " +
"ScaleY, " +
"Spacing, " +
"Angle, " +
"BorderStyle, " +
"Outline, " +
"Shadow, " +
"Alignment, " +
"MarginL, " +
"MarginR, " +
"MarginV, " +
"Encoding\n" +
// ASS color format is BBGGRR
// Red = &H0000FF
"Style: " +
"RedEye," +
"Arial," +
fontSize + "," +
"&H0000FF," +
"&H0000FF," +
"&H000000," +
"&H000000," +
"0," +
"0," +
"0," +
"0," +
"100," +
"100," +
"0," +
"0," +
"1," +
"1," +
"0," +
"2," +
"0," +
"0," +
verticalMargin + "," +
"0\n" +
// Green = &H00FF00
"Style: " +
"GreenEye," +
"Arial," +
fontSize + "," +
"&H00FF00," +
"&H00FF00," +
"&H000000," +
"&H000000," +
"0," +
"0," +
"0," +
"0," +
"100," +
"100," +
"0," +
"0," +
"1," +
"1," +
"0," +
"2," +
"0," +
"0," +
verticalMargin + "," +
"0";
return style;
}
private static string CreateHeader(string file, int resY = 720, int resX = 1280)
{ {
var name = Path.GetFileNameWithoutExtension(file); var name = Path.GetFileNameWithoutExtension(file);
string scriptinfo = "; Generated by ConvertSRTto3D\n" +
string scriptInfo =
"; Generated by ConvertSRTto3D\n" +
"Title: " + name + "\n" + "Title: " + name + "\n" +
"ScriptType: v4.00+\n" + "ScriptType: v4.00+\n" +
"Collisions: Normal\n" + "Collisions: Normal\n" +
"PlayResX: " + resX + "\n" + "PlayResX: " + resX + "\n" +
"PlayResY: " + resY + "\n" + "PlayResY: " + resY + "\n" +
"ScaledBorderAndShadow: yes"; "ScaledBorderAndShadow: yes";
return scriptinfo;
return scriptInfo;
}
private static string ReadTextSmart(string path)
{
using (var reader = new StreamReader(path, Encoding.UTF8, detectEncodingFromByteOrderMarks: true))
{
string text = reader.ReadToEnd();
if (text.Contains('\uFFFD'))
text = File.ReadAllText(path, Encoding.GetEncoding(1252));
return text;
}
} }
//start, end, text, format <- tuple format
//Note - I want to change the tuple as format bit is useless as the data is carried in the text field for both .srt and .ass
//but I could reprepose it for any positional data
private static List<Tuple<string, string, string, string>> ExtractSubFromSRT(string file) private static List<Tuple<string, string, string, string>> ExtractSubFromSRT(string file)
{ {
var results = new List<Tuple<string, string, string, string>>();
string srt = ReadTextSmart(file);
var converted = new List<Tuple<string, string, string, string>>(); srt = srt.Replace("\r\n", "\n").Replace("\r", "\n");
var timestamp_start = ""; var blocks = Regex.Split(srt.Trim(), @"\n\s*\n");
var timestamp_end = "";
var subtitiles = "";
string srt = File.ReadAllText(file);
//Which dialog we are on (sanity check) int expectedDialogNumber = 1;
int i = 1;
//Whether to extract the time stamp or not foreach (var block in blocks)
int j = 0; //TODO: Change to a bool
int linecounter = 0; //Where we are in the .srt, meant for debugging
foreach (string line in srt.Split('\n'))
{ {
linecounter++; var lines = block
//Empty line assumes that the next line with event number thus previous dialog is finished and can be saved .Split(new[] { '\n' }, StringSplitOptions.None)
if (line == "" | line == "\r") .Select(l => l.Trim())
.Where(l => l.Length > 0)
.ToList();
if (lines.Count < 3)
continue;
if (!int.TryParse(lines[0], out int dialogNumber))
{ {
j = 0; Console.Error.WriteLine($"Skipping malformed block: expected subtitle number, got [{lines[0]}]");
converted.Add(new Tuple<string, string, string, string>(timestamp_start, timestamp_end, ChangeFormatting(subtitiles), ""));
subtitiles = "";
continue; continue;
} }
//Try to parse the event/dialog number
if (int.TryParse(line, out int k)) if (dialogNumber != expectedDialogNumber)
{ {
//Event number doesn't match counted event number. Mismatch means something probably went wrong Console.Error.WriteLine(
if (k != i) $"Warning: expected subtitle number {expectedDialogNumber}, but found {dialogNumber}.");
{ expectedDialogNumber = dialogNumber;
Console.Error.WriteLine("Something went wrong");
Console.Error.WriteLine("Something wrong on line:" + linecounter);
System.Environment.Exit(-1);
}
else
{
i++;
j++;
continue;
}
} }
//If it a timestamp is expected, extract it expectedDialogNumber++;
if (j == 1)
var timeMatch = Regex.Match(
lines[1],
@"^(?<start>\d{2}:\d{2}:\d{2},\d{3})\s*-->\s*(?<end>\d{2}:\d{2}:\d{2},\d{3})$");
if (!timeMatch.Success)
{ {
timestamp_start = line.Substring(0, 12); Console.Error.WriteLine($"Skipping malformed timestamp line: [{lines[1]}]");
timestamp_end = line.Substring(17, 12); continue;
j++;
}
else
{
if (subtitiles == "")
{
subtitiles = line;
subtitiles.Replace("\\.r", "");
}
else
{
subtitiles = subtitiles + "\\n" + line;
}
} }
string timestampStart = timeMatch.Groups["start"].Value;
string timestampEnd = timeMatch.Groups["end"].Value;
string subtitleText = string.Join("\\N", lines.Skip(2));
results.Add(new Tuple<string, string, string, string>(
timestampStart,
timestampEnd,
ChangeFormatting(subtitleText),
""));
} }
return converted;
return results;
} }
} }
} }
+6
View File
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
</startup>
</configuration>
@@ -0,0 +1,89 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{8C44F434-2097-4FA3-BEE1-9569FB99F49C}</ProjectGuid>
<OutputType>WinExe</OutputType>
<RootNamespace>ConvertSRTto3DASSGUI</RootNamespace>
<AssemblyName>ConvertSRTto3DASSGUI</AssemblyName>
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<Deterministic>true</Deterministic>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Deployment" />
<Reference Include="System.Drawing" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Form1.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="Form1.Designer.cs">
<DependentUpon>Form1.cs</DependentUpon>
</Compile>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<EmbeddedResource Include="Form1.resx">
<DependentUpon>Form1.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
<SubType>Designer</SubType>
</EmbeddedResource>
<Compile Include="Properties\Resources.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
<Compile Include="Properties\Settings.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Settings.settings</DependentUpon>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
</Compile>
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\ConvertSRTto3DASS\ConvertSRTto3DASS.csproj">
<Project>{7d7925de-adbd-4a26-b12b-8f12b68d3bfe}</Project>
<Name>ConvertSRTto3DASS</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
+551
View File
@@ -0,0 +1,551 @@
namespace ConvertSRTto3DASSGUI
{
partial class Form1
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
private System.Windows.Forms.Label lblInputFile;
private System.Windows.Forms.TextBox txtInputFile;
private System.Windows.Forms.Button btnBrowseInput;
private System.Windows.Forms.Label lblOutputFile;
private System.Windows.Forms.TextBox txtOutputFile;
private System.Windows.Forms.Button btnBrowseOutput;
private System.Windows.Forms.Label lblMode;
private System.Windows.Forms.ComboBox cmbMode;
private System.Windows.Forms.Label lblResX;
private System.Windows.Forms.NumericUpDown nudResX;
private System.Windows.Forms.Label lblResY;
private System.Windows.Forms.NumericUpDown nudResY;
private System.Windows.Forms.Label lblBaseResX;
private System.Windows.Forms.NumericUpDown nudBaseResX;
private System.Windows.Forms.Label lblBaseResY;
private System.Windows.Forms.NumericUpDown nudBaseResY;
private System.Windows.Forms.Label lblFontSize;
private System.Windows.Forms.NumericUpDown nudFontSize;
private System.Windows.Forms.Label lblOffsetX;
private System.Windows.Forms.NumericUpDown nudOffsetX;
private System.Windows.Forms.Label lblBottomOffset;
private System.Windows.Forms.NumericUpDown nudBottomOffset;
private System.Windows.Forms.Label lblSbsSideMargin;
private System.Windows.Forms.NumericUpDown nudSbsSideMargin;
private System.Windows.Forms.Label lblOuTopMargin;
private System.Windows.Forms.NumericUpDown nudOuTopMargin;
private System.Windows.Forms.Label lblVerticalMargin;
private System.Windows.Forms.NumericUpDown nudVerticalMargin;
private System.Windows.Forms.Button btnConvert;
private System.Windows.Forms.TextBox txtStatus;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.lblInputFile = new System.Windows.Forms.Label();
this.txtInputFile = new System.Windows.Forms.TextBox();
this.btnBrowseInput = new System.Windows.Forms.Button();
this.lblOutputFile = new System.Windows.Forms.Label();
this.txtOutputFile = new System.Windows.Forms.TextBox();
this.btnBrowseOutput = new System.Windows.Forms.Button();
this.lblMode = new System.Windows.Forms.Label();
this.cmbMode = new System.Windows.Forms.ComboBox();
this.lblResX = new System.Windows.Forms.Label();
this.nudResX = new System.Windows.Forms.NumericUpDown();
this.lblResY = new System.Windows.Forms.Label();
this.nudResY = new System.Windows.Forms.NumericUpDown();
this.lblBaseResX = new System.Windows.Forms.Label();
this.nudBaseResX = new System.Windows.Forms.NumericUpDown();
this.lblBaseResY = new System.Windows.Forms.Label();
this.nudBaseResY = new System.Windows.Forms.NumericUpDown();
this.lblFontSize = new System.Windows.Forms.Label();
this.nudFontSize = new System.Windows.Forms.NumericUpDown();
this.lblOffsetX = new System.Windows.Forms.Label();
this.nudOffsetX = new System.Windows.Forms.NumericUpDown();
this.lblBottomOffset = new System.Windows.Forms.Label();
this.nudBottomOffset = new System.Windows.Forms.NumericUpDown();
this.lblSbsSideMargin = new System.Windows.Forms.Label();
this.nudSbsSideMargin = new System.Windows.Forms.NumericUpDown();
this.lblOuTopMargin = new System.Windows.Forms.Label();
this.nudOuTopMargin = new System.Windows.Forms.NumericUpDown();
this.lblVerticalMargin = new System.Windows.Forms.Label();
this.nudVerticalMargin = new System.Windows.Forms.NumericUpDown();
this.btnConvert = new System.Windows.Forms.Button();
this.txtStatus = new System.Windows.Forms.TextBox();
((System.ComponentModel.ISupportInitialize)(this.nudResX)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.nudResY)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.nudBaseResX)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.nudBaseResY)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.nudFontSize)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.nudOffsetX)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.nudBottomOffset)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.nudSbsSideMargin)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.nudOuTopMargin)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.nudVerticalMargin)).BeginInit();
this.SuspendLayout();
//
// lblInputFile
//
this.lblInputFile.AutoSize = true;
this.lblInputFile.Location = new System.Drawing.Point(24, 28);
this.lblInputFile.Name = "lblInputFile";
this.lblInputFile.Size = new System.Drawing.Size(94, 16);
this.lblInputFile.TabIndex = 0;
this.lblInputFile.Text = "Input SRT File:";
//
// txtInputFile
//
this.txtInputFile.Location = new System.Drawing.Point(140, 25);
this.txtInputFile.Name = "txtInputFile";
this.txtInputFile.Size = new System.Drawing.Size(780, 22);
this.txtInputFile.TabIndex = 1;
//
// btnBrowseInput
//
this.btnBrowseInput.Location = new System.Drawing.Point(940, 23);
this.btnBrowseInput.Name = "btnBrowseInput";
this.btnBrowseInput.Size = new System.Drawing.Size(120, 28);
this.btnBrowseInput.TabIndex = 2;
this.btnBrowseInput.Text = "Browse...";
this.btnBrowseInput.UseVisualStyleBackColor = true;
this.btnBrowseInput.Click += new System.EventHandler(this.btnBrowseInput_Click);
//
// lblOutputFile
//
this.lblOutputFile.AutoSize = true;
this.lblOutputFile.Location = new System.Drawing.Point(24, 72);
this.lblOutputFile.Name = "lblOutputFile";
this.lblOutputFile.Size = new System.Drawing.Size(103, 16);
this.lblOutputFile.TabIndex = 3;
this.lblOutputFile.Text = "Output ASS File:";
//
// txtOutputFile
//
this.txtOutputFile.Location = new System.Drawing.Point(140, 69);
this.txtOutputFile.Name = "txtOutputFile";
this.txtOutputFile.Size = new System.Drawing.Size(780, 22);
this.txtOutputFile.TabIndex = 4;
//
// btnBrowseOutput
//
this.btnBrowseOutput.Location = new System.Drawing.Point(940, 67);
this.btnBrowseOutput.Name = "btnBrowseOutput";
this.btnBrowseOutput.Size = new System.Drawing.Size(120, 28);
this.btnBrowseOutput.TabIndex = 5;
this.btnBrowseOutput.Text = "Browse...";
this.btnBrowseOutput.UseVisualStyleBackColor = true;
this.btnBrowseOutput.Click += new System.EventHandler(this.btnBrowseOutput_Click);
//
// lblMode
//
this.lblMode.AutoSize = true;
this.lblMode.Location = new System.Drawing.Point(24, 125);
this.lblMode.Name = "lblMode";
this.lblMode.Size = new System.Drawing.Size(65, 16);
this.lblMode.TabIndex = 6;
this.lblMode.Text = "3D Mode:";
//
// cmbMode
//
this.cmbMode.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.cmbMode.FormattingEnabled = true;
this.cmbMode.Items.AddRange(new object[] {
"sbs (Side-By-Side)",
"ou (Over-Under)",
"rg (Red-Green)"});
this.cmbMode.Location = new System.Drawing.Point(140, 122);
this.cmbMode.Name = "cmbMode";
this.cmbMode.Size = new System.Drawing.Size(180, 24);
this.cmbMode.TabIndex = 7;
this.cmbMode.SelectedIndexChanged += new System.EventHandler(this.cmbMode_SelectedIndexChanged);
//
// lblResX
//
this.lblResX.AutoSize = true;
this.lblResX.Location = new System.Drawing.Point(24, 178);
this.lblResX.Name = "lblResX";
this.lblResX.Size = new System.Drawing.Size(46, 16);
this.lblResX.TabIndex = 8;
this.lblResX.Text = "Res X:";
//
// nudResX
//
this.nudResX.Location = new System.Drawing.Point(140, 176);
this.nudResX.Maximum = new decimal(new int[] {
10000,
0,
0,
0});
this.nudResX.Minimum = new decimal(new int[] {
1,
0,
0,
0});
this.nudResX.Name = "nudResX";
this.nudResX.Size = new System.Drawing.Size(120, 22);
this.nudResX.TabIndex = 9;
this.nudResX.Value = new decimal(new int[] {
1280,
0,
0,
0});
//
// lblResY
//
this.lblResY.AutoSize = true;
this.lblResY.Location = new System.Drawing.Point(300, 178);
this.lblResY.Name = "lblResY";
this.lblResY.Size = new System.Drawing.Size(47, 16);
this.lblResY.TabIndex = 10;
this.lblResY.Text = "Res Y:";
//
// nudResY
//
this.nudResY.Location = new System.Drawing.Point(360, 176);
this.nudResY.Maximum = new decimal(new int[] {
10000,
0,
0,
0});
this.nudResY.Minimum = new decimal(new int[] {
1,
0,
0,
0});
this.nudResY.Name = "nudResY";
this.nudResY.Size = new System.Drawing.Size(120, 22);
this.nudResY.TabIndex = 11;
this.nudResY.Value = new decimal(new int[] {
720,
0,
0,
0});
//
// lblBaseResX
//
this.lblBaseResX.AutoSize = true;
this.lblBaseResX.Location = new System.Drawing.Point(520, 178);
this.lblBaseResX.Name = "lblBaseResX";
this.lblBaseResX.Size = new System.Drawing.Size(81, 16);
this.lblBaseResX.TabIndex = 12;
this.lblBaseResX.Text = "Base Res X:";
//
// nudBaseResX
//
this.nudBaseResX.Location = new System.Drawing.Point(620, 176);
this.nudBaseResX.Maximum = new decimal(new int[] {
10000,
0,
0,
0});
this.nudBaseResX.Minimum = new decimal(new int[] {
1,
0,
0,
0});
this.nudBaseResX.Name = "nudBaseResX";
this.nudBaseResX.Size = new System.Drawing.Size(120, 22);
this.nudBaseResX.TabIndex = 13;
this.nudBaseResX.Value = new decimal(new int[] {
1280,
0,
0,
0});
//
// lblBaseResY
//
this.lblBaseResY.AutoSize = true;
this.lblBaseResY.Location = new System.Drawing.Point(760, 178);
this.lblBaseResY.Name = "lblBaseResY";
this.lblBaseResY.Size = new System.Drawing.Size(82, 16);
this.lblBaseResY.TabIndex = 14;
this.lblBaseResY.Text = "Base Res Y:";
//
// nudBaseResY
//
this.nudBaseResY.Location = new System.Drawing.Point(860, 176);
this.nudBaseResY.Maximum = new decimal(new int[] {
10000,
0,
0,
0});
this.nudBaseResY.Minimum = new decimal(new int[] {
1,
0,
0,
0});
this.nudBaseResY.Name = "nudBaseResY";
this.nudBaseResY.Size = new System.Drawing.Size(120, 22);
this.nudBaseResY.TabIndex = 15;
this.nudBaseResY.Value = new decimal(new int[] {
720,
0,
0,
0});
//
// lblFontSize
//
this.lblFontSize.AutoSize = true;
this.lblFontSize.Location = new System.Drawing.Point(24, 228);
this.lblFontSize.Name = "lblFontSize";
this.lblFontSize.Size = new System.Drawing.Size(65, 16);
this.lblFontSize.TabIndex = 16;
this.lblFontSize.Text = "Font Size:";
//
// nudFontSize
//
this.nudFontSize.Location = new System.Drawing.Point(140, 226);
this.nudFontSize.Maximum = new decimal(new int[] {
200,
0,
0,
0});
this.nudFontSize.Minimum = new decimal(new int[] {
1,
0,
0,
0});
this.nudFontSize.Name = "nudFontSize";
this.nudFontSize.Size = new System.Drawing.Size(120, 22);
this.nudFontSize.TabIndex = 17;
this.nudFontSize.Value = new decimal(new int[] {
16,
0,
0,
0});
//
// lblOffsetX
//
this.lblOffsetX.AutoSize = true;
this.lblOffsetX.Location = new System.Drawing.Point(300, 228);
this.lblOffsetX.Name = "lblOffsetX";
this.lblOffsetX.Size = new System.Drawing.Size(55, 16);
this.lblOffsetX.TabIndex = 18;
this.lblOffsetX.Text = "Offset X:";
//
// nudOffsetX
//
this.nudOffsetX.Location = new System.Drawing.Point(360, 226);
this.nudOffsetX.Maximum = new decimal(new int[] {
1000,
0,
0,
0});
this.nudOffsetX.Name = "nudOffsetX";
this.nudOffsetX.Size = new System.Drawing.Size(120, 22);
this.nudOffsetX.TabIndex = 19;
this.nudOffsetX.Value = new decimal(new int[] {
4,
0,
0,
0});
//
// lblBottomOffset
//
this.lblBottomOffset.AutoSize = true;
this.lblBottomOffset.Location = new System.Drawing.Point(520, 228);
this.lblBottomOffset.Name = "lblBottomOffset";
this.lblBottomOffset.Size = new System.Drawing.Size(89, 16);
this.lblBottomOffset.TabIndex = 20;
this.lblBottomOffset.Text = "Bottom Offset:";
//
// nudBottomOffset
//
this.nudBottomOffset.Location = new System.Drawing.Point(620, 226);
this.nudBottomOffset.Maximum = new decimal(new int[] {
1000,
0,
0,
0});
this.nudBottomOffset.Name = "nudBottomOffset";
this.nudBottomOffset.Size = new System.Drawing.Size(120, 22);
this.nudBottomOffset.TabIndex = 21;
this.nudBottomOffset.Value = new decimal(new int[] {
18,
0,
0,
0});
//
// lblSbsSideMargin
//
this.lblSbsSideMargin.AutoSize = true;
this.lblSbsSideMargin.Location = new System.Drawing.Point(24, 278);
this.lblSbsSideMargin.Name = "lblSbsSideMargin";
this.lblSbsSideMargin.Size = new System.Drawing.Size(112, 16);
this.lblSbsSideMargin.TabIndex = 22;
this.lblSbsSideMargin.Text = "SBS Side Margin:";
//
// nudSbsSideMargin
//
this.nudSbsSideMargin.Location = new System.Drawing.Point(140, 276);
this.nudSbsSideMargin.Maximum = new decimal(new int[] {
5000,
0,
0,
0});
this.nudSbsSideMargin.Name = "nudSbsSideMargin";
this.nudSbsSideMargin.Size = new System.Drawing.Size(120, 22);
this.nudSbsSideMargin.TabIndex = 23;
this.nudSbsSideMargin.Value = new decimal(new int[] {
192,
0,
0,
0});
//
// lblOuTopMargin
//
this.lblOuTopMargin.AutoSize = true;
this.lblOuTopMargin.Location = new System.Drawing.Point(300, 278);
this.lblOuTopMargin.Name = "lblOuTopMargin";
this.lblOuTopMargin.Size = new System.Drawing.Size(102, 16);
this.lblOuTopMargin.TabIndex = 24;
this.lblOuTopMargin.Text = "OU Top Margin:";
//
// nudOuTopMargin
//
this.nudOuTopMargin.Location = new System.Drawing.Point(410, 276);
this.nudOuTopMargin.Maximum = new decimal(new int[] {
5000,
0,
0,
0});
this.nudOuTopMargin.Name = "nudOuTopMargin";
this.nudOuTopMargin.Size = new System.Drawing.Size(120, 22);
this.nudOuTopMargin.TabIndex = 25;
this.nudOuTopMargin.Value = new decimal(new int[] {
154,
0,
0,
0});
//
// lblVerticalMargin
//
this.lblVerticalMargin.AutoSize = true;
this.lblVerticalMargin.Location = new System.Drawing.Point(560, 278);
this.lblVerticalMargin.Name = "lblVerticalMargin";
this.lblVerticalMargin.Size = new System.Drawing.Size(99, 16);
this.lblVerticalMargin.TabIndex = 26;
this.lblVerticalMargin.Text = "Vertical Margin:";
//
// nudVerticalMargin
//
this.nudVerticalMargin.Location = new System.Drawing.Point(670, 276);
this.nudVerticalMargin.Maximum = new decimal(new int[] {
5000,
0,
0,
0});
this.nudVerticalMargin.Name = "nudVerticalMargin";
this.nudVerticalMargin.Size = new System.Drawing.Size(120, 22);
this.nudVerticalMargin.TabIndex = 27;
this.nudVerticalMargin.Value = new decimal(new int[] {
10,
0,
0,
0});
//
// btnConvert
//
this.btnConvert.Location = new System.Drawing.Point(27, 329);
this.btnConvert.Name = "btnConvert";
this.btnConvert.Size = new System.Drawing.Size(145, 40);
this.btnConvert.TabIndex = 28;
this.btnConvert.Text = "Convert";
this.btnConvert.UseVisualStyleBackColor = true;
this.btnConvert.Click += new System.EventHandler(this.btnConvert_Click);
//
// txtStatus
//
this.txtStatus.Location = new System.Drawing.Point(27, 392);
this.txtStatus.Multiline = true;
this.txtStatus.Name = "txtStatus";
this.txtStatus.ScrollBars = System.Windows.Forms.ScrollBars.Vertical;
this.txtStatus.Size = new System.Drawing.Size(1033, 225);
this.txtStatus.TabIndex = 29;
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 16F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(1088, 640);
this.Controls.Add(this.txtStatus);
this.Controls.Add(this.btnConvert);
this.Controls.Add(this.nudVerticalMargin);
this.Controls.Add(this.lblVerticalMargin);
this.Controls.Add(this.nudOuTopMargin);
this.Controls.Add(this.lblOuTopMargin);
this.Controls.Add(this.nudSbsSideMargin);
this.Controls.Add(this.lblSbsSideMargin);
this.Controls.Add(this.nudBottomOffset);
this.Controls.Add(this.lblBottomOffset);
this.Controls.Add(this.nudOffsetX);
this.Controls.Add(this.lblOffsetX);
this.Controls.Add(this.nudFontSize);
this.Controls.Add(this.lblFontSize);
this.Controls.Add(this.nudBaseResY);
this.Controls.Add(this.lblBaseResY);
this.Controls.Add(this.nudBaseResX);
this.Controls.Add(this.lblBaseResX);
this.Controls.Add(this.nudResY);
this.Controls.Add(this.lblResY);
this.Controls.Add(this.nudResX);
this.Controls.Add(this.lblResX);
this.Controls.Add(this.cmbMode);
this.Controls.Add(this.lblMode);
this.Controls.Add(this.btnBrowseOutput);
this.Controls.Add(this.txtOutputFile);
this.Controls.Add(this.lblOutputFile);
this.Controls.Add(this.btnBrowseInput);
this.Controls.Add(this.txtInputFile);
this.Controls.Add(this.lblInputFile);
this.Name = "Form1";
this.Text = "Convert SRT to 3D ASS";
this.Load += new System.EventHandler(this.Form1_Load);
((System.ComponentModel.ISupportInitialize)(this.nudResX)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.nudResY)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.nudBaseResX)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.nudBaseResY)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.nudFontSize)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.nudOffsetX)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.nudBottomOffset)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.nudSbsSideMargin)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.nudOuTopMargin)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.nudVerticalMargin)).EndInit();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
}
}
+241
View File
@@ -0,0 +1,241 @@
using ConvertSRTto3DASS;
using System;
using System.IO;
using System.Windows.Forms;
using static ConvertSRTto3DASS.Converter;
namespace ConvertSRTto3DASSGUI
{
public partial class Form1 : Form
{
// Keep these in sync with Converter.cs defaults
private const int DefaultResX = Converter.ConverterDefaults.ResX;//1280
private const int DefaultResY = 720;
private const int DefaultBaseResX = 1280;
private const int DefaultBaseResY = 720;
private const int DefaultFontSize = 16;
private const int DefaultOffsetX = 4;
private const int DefaultBottomOffset = 18;
private const int DefaultSbsSideMargin = 192;
private const int DefaultOuTopMargin = 154;
private const int DefaultVerticalMargin = 10;
public Form1()
{
InitializeComponent();
InitializeDefaults();
if (cmbMode.Items.Count > 0)
cmbMode.SelectedIndex = 0;
UpdateModeUI();
}
private void InitializeDefaults()
{
txtInputFile.Text = string.Empty;
txtOutputFile.Text = string.Empty;
nudResX.Value = ConverterDefaults.ResX;
nudResY.Value = ConverterDefaults.ResY;
nudBaseResX.Value = ConverterDefaults.BaseResX;
nudBaseResY.Value = ConverterDefaults.BaseResY;
nudFontSize.Value = ConverterDefaults.FontSize;
nudOffsetX.Value = ConverterDefaults.OffsetX;
nudBottomOffset.Value = ConverterDefaults.BottomOffset;
nudSbsSideMargin.Value = ConverterDefaults.SbsSideMargin;
nudOuTopMargin.Value = ConverterDefaults.OuTopMargin;
nudVerticalMargin.Value = ConverterDefaults.VerticalMargin;
switch (ConverterDefaults.DefaultMode.ToLowerInvariant())
{
case "sbs":
cmbMode.SelectedIndex = 0;
break;
case "ou":
cmbMode.SelectedIndex = 1;
break;
case "rg":
cmbMode.SelectedIndex = 2;
break;
default:
cmbMode.SelectedIndex = 0;
break;
}
}
private void btnBrowseInput_Click(object sender, EventArgs e)
{
using (var ofd = new OpenFileDialog())
{
ofd.Filter = "SRT files (*.srt)|*.srt|All files (*.*)|*.*";
ofd.Title = "Select input SRT file";
if (ofd.ShowDialog() == DialogResult.OK)
{
txtInputFile.Text = ofd.FileName;
if (string.IsNullOrWhiteSpace(txtOutputFile.Text))
{
txtOutputFile.Text = Path.ChangeExtension(ofd.FileName, ".ass");
}
AppendStatus("Selected input file: " + ofd.FileName);
}
}
}
private void btnBrowseOutput_Click(object sender, EventArgs e)
{
using (var sfd = new SaveFileDialog())
{
sfd.Filter = "ASS files (*.ass)|*.ass|All files (*.*)|*.*";
sfd.Title = "Select output ASS file";
sfd.DefaultExt = "ass";
if (!string.IsNullOrWhiteSpace(txtInputFile.Text))
{
sfd.FileName = Path.GetFileNameWithoutExtension(txtInputFile.Text) + ".ass";
sfd.InitialDirectory = Path.GetDirectoryName(txtInputFile.Text);
}
if (sfd.ShowDialog() == DialogResult.OK)
{
txtOutputFile.Text = sfd.FileName;
AppendStatus("Selected output file: " + sfd.FileName);
}
}
}
private void cmbMode_SelectedIndexChanged(object sender, EventArgs e)
{
UpdateModeUI();
}
private string GetSelectedModeValue()
{
string selected = cmbMode.SelectedItem?.ToString() ?? "sbs";
int spaceIndex = selected.IndexOf(' ');
if (spaceIndex > 0)
return selected.Substring(0, spaceIndex).Trim().ToLowerInvariant();
return selected.Trim().ToLowerInvariant();
}
private void btnConvert_Click(object sender, EventArgs e)
{
try
{
txtStatus.Clear();
string inputPath = txtInputFile.Text.Trim();
string outputPath = txtOutputFile.Text.Trim();
string mode = GetSelectedModeValue();
if (string.IsNullOrWhiteSpace(inputPath))
{
MessageBox.Show("Please select an input SRT file.", "Missing Input", MessageBoxButtons.OK, MessageBoxIcon.Warning);
return;
}
if (!File.Exists(inputPath))
{
MessageBox.Show("The selected input file does not exist.", "Invalid Input", MessageBoxButtons.OK, MessageBoxIcon.Warning);
return;
}
if (string.IsNullOrWhiteSpace(outputPath))
{
outputPath = Path.ChangeExtension(inputPath, ".ass");
txtOutputFile.Text = outputPath;
}
int resX = (int)nudResX.Value;
int resY = (int)nudResY.Value;
int baseResX = (int)nudBaseResX.Value;
int baseResY = (int)nudBaseResY.Value;
int fontSize = (int)nudFontSize.Value;
int offsetX = (int)nudOffsetX.Value;
int bottomOffset = (int)nudBottomOffset.Value;
int sbsSideMargin = (int)nudSbsSideMargin.Value;
int ouTopMargin = (int)nudOuTopMargin.Value;
int verticalMargin = (int)nudVerticalMargin.Value;
AppendStatus("Starting conversion...");
AppendStatus("Input: " + inputPath);
AppendStatus("Output: " + outputPath);
AppendStatus("Mode: " + mode);
AppendStatus("Resolution: " + resX + "x" + resY);
AppendStatus("Base Resolution: " + baseResX + "x" + baseResY);
AppendStatus("Font Size: " + fontSize);
AppendStatus("OffsetX: " + offsetX);
AppendStatus("BottomOffset: " + bottomOffset);
AppendStatus("SbsSideMargin: " + sbsSideMargin);
AppendStatus("OuTopMargin: " + ouTopMargin);
AppendStatus("VerticalMargin: " + verticalMargin);
Converter.Main(new[]
{
inputPath,
"--mode", mode,
"--resx", resX.ToString(),
"--resy", resY.ToString(),
"--baseresx", baseResX.ToString(),
"--baseresy", baseResY.ToString(),
"--fontsize", fontSize.ToString(),
"--offsetx", offsetX.ToString(),
"--bottomoffset", bottomOffset.ToString(),
"--sbssidemargin", sbsSideMargin.ToString(),
"--outopmargin", ouTopMargin.ToString(),
"--verticalmargin", verticalMargin.ToString(),
"--output", outputPath
});
AppendStatus("Conversion complete.");
MessageBox.Show("Conversion complete.", "Success", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
catch (Exception ex)
{
AppendStatus("ERROR: " + ex.Message);
MessageBox.Show(ex.Message, "Conversion Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void UpdateModeUI()
{
string mode = GetSelectedModeValue();
bool isSbs = mode == "sbs";
bool isOu = mode == "ou";
bool isRg = mode == "rg";
nudOffsetX.Enabled = isRg;
lblOffsetX.Enabled = isRg;
nudBottomOffset.Enabled = isRg;
lblBottomOffset.Enabled = isRg;
nudSbsSideMargin.Enabled = isSbs;
lblSbsSideMargin.Enabled = isSbs;
nudOuTopMargin.Enabled = isOu;
lblOuTopMargin.Enabled = isOu;
nudVerticalMargin.Enabled = true;
lblVerticalMargin.Enabled = true;
}
private void AppendStatus(string message)
{
if (txtStatus.TextLength > 0)
txtStatus.AppendText(Environment.NewLine);
txtStatus.AppendText(message);
}
private void Form1_Load(object sender, EventArgs e)
{
}
}
}
+120
View File
@@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>
+22
View File
@@ -0,0 +1,22 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace ConvertSRTto3DASSGUI
{
internal static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}
}
@@ -0,0 +1,33 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("ConvertSRTto3DASSGUI")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Stanley Black & Decker inc.")]
[assembly: AssemblyProduct("ConvertSRTto3DASSGUI")]
[assembly: AssemblyCopyright("Copyright © Stanley Black & Decker inc. 2026")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("8c44f434-2097-4fa3-bee1-9569fb99f49c")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
+71
View File
@@ -0,0 +1,71 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace ConvertSRTto3DASSGUI.Properties
{
/// <summary>
/// A strongly-typed resource class, for looking up localized strings, etc.
/// </summary>
// This class was auto-generated by the StronglyTypedResourceBuilder
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources
{
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resources()
{
}
/// <summary>
/// Returns the cached ResourceManager instance used by this class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager
{
get
{
if ((resourceMan == null))
{
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ConvertSRTto3DASSGUI.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture
{
get
{
return resourceCulture;
}
set
{
resourceCulture = value;
}
}
}
}
@@ -0,0 +1,117 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>
+30
View File
@@ -0,0 +1,30 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace ConvertSRTto3DASSGUI.Properties
{
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
{
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
public static Settings Default
{
get
{
return defaultInstance;
}
}
}
}
@@ -0,0 +1,7 @@
<?xml version='1.0' encoding='utf-8'?>
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)">
<Profiles>
<Profile Name="(Default)" />
</Profiles>
<Settings />
</SettingsFile>
+5 -5
View File
@@ -9,9 +9,9 @@ Currently just a command line program to convert a .srt subtitle file to an .ass
_Basically nothing right now_ _Basically nothing right now_
- [x] Convert a .srt to an .ass/.ssa - [x] Convert a .srt to an .ass/.ssa
- [x] For HSBS media - [x] For HSBS media
- [ ] For **S**ide **B**y **S**ide (SBS) media - [X] For **S**ide **B**y **S**ide (SBS) media
- [ ] For **O**ver **U**nder (OU) media - [X] For **O**ver **U**nder (OU) media
- [ ] For Anaglyph 3D media (red and green media) - [X] For Anaglyph 3D media (red and green media) - Warning Experimental
- [ ] For traditionally media (pancake mode). - [ ] For traditionally media (pancake mode).
- _I suggest to just use ffmpeg for this use case_ - _I suggest to just use ffmpeg for this use case_
- [x] Convert formatting of .srt subtitles to transfer to the converted version - [x] Convert formatting of .srt subtitles to transfer to the converted version
@@ -20,9 +20,9 @@ _Basically nothing right now_
- [ ] Font - [ ] Font
- [ ] Color - [ ] Color
- [ ] Position - [ ] Position
- [ ] Margins - [X] Margins
- [ ] Encoding - [ ] Encoding
- [ ] Add a proper GUI - [X] Add a proper GUI
- [ ] Any form of error handling or unit testing - [ ] Any form of error handling or unit testing