Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion ASSLoader.AutoEffects/ASSLoader.AutoEffects.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<TargetFramework>netstandard2.1</TargetFramework>
</PropertyGroup>

<ItemGroup>
Expand Down
155 changes: 155 additions & 0 deletions ASSLoader.NET/ASSEvent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
using ASSLoader.NET.Enums;
using log4net;
using System;
using System.Collections.Generic;
using System.Text;

namespace ASSLoader.NET
{
public class ASSEvent : ICloneable
{
public ASSEventType Type { get; set; }

public int Layer { get; set; }

public ASSEventTime Start { get; set; }

public ASSEventTime End { get; set; }

public string Style { get; set; }

public string Name { get; set; }

public int MarginL { get; set; }

public int MarginR { get; set; }

public int MarginV { get; set; }

public string Effect { get; set; }

public string Text { get; set; }

private static ILog log = LogManager.GetLogger(typeof(ASSStyle));

public static IList<string> DefaultFormat = new List<string> {
"Layer", "Start", "End", "Style", "Name", "MarginL", "MarginR", "MarginV", "Effect", "Text"
};

public object Clone()
{
var newInst = new ASSEvent();
newInst.Type = this.Type;
newInst.Layer = this.Layer;
newInst.Start = new ASSEventTime(this.Start.ToString());
newInst.End = new ASSEventTime(this.End.ToString());
newInst.Style = this.Style;
newInst.Name = this.Name;
newInst.MarginL = this.MarginL;
newInst.MarginR = this.MarginR;
newInst.MarginV = this.MarginV;
newInst.Effect = this.Effect;
newInst.Text = this.Text;
return newInst;
}

public ASSEvent()
{
this.Type = ASSEventType.Dialogue;
this.Layer = 0;
this.Start = new ASSEventTime(0, 0, 0, 0);
this.End = new ASSEventTime(0, 0, 0, 0);
this.Style = "Default";
this.Name = string.Empty;
this.MarginL = 0;
this.MarginR = 0;
this.MarginV = 0;
this.Effect = string.Empty;
this.Text = string.Empty;
}


/// <summary>
/// Convert an event text into ASSEvent object.
/// </summary>
/// <param name="prefix">The prefix of the line of the event text. Must be one of the ASSEventType.</param>
/// <param name="eventFormat">The headings list from the "Format" of the "Events" section.</param>
/// <param name="values">The values list of the line of the event text.</param>
/// <returns>The ASSEvent object.</returns>
public static ASSEvent Parse(string prefix, IList<string> eventFormat, IList<string> values)
{
var eventType = (ASSEventType)Enum.Parse(typeof(ASSEventType), prefix);
var evt = new ASSEvent();
evt.Type = eventType;
for (var i = 0; i < eventFormat.Count; i++)
{
var field = eventFormat[i];
var value = values[i];
switch (field.Trim())
{
case "Layer": evt.Layer = Convert.ToInt32(value); continue;
case "Start": evt.Start = new ASSEventTime(value); continue;
case "End": evt.End = new ASSEventTime(value); continue;
case "Style": evt.Style = value; continue;
case "Name": evt.Name = value; continue;
case "MarginL": evt.MarginL = Convert.ToInt32(value); continue;
case "MarginR": evt.MarginR = Convert.ToInt32(value); continue;
case "MarginV": evt.MarginV = Convert.ToInt32(value); continue;
case "Effect": evt.Effect = value; continue;
case "Text": evt.Text = value; continue;
default:
log.Warn($"EVENT MAPPING ERROR: Unknown field skipped: [{field}].");
continue;
}
}
return evt;
}

/// <summary>
/// Convert an ASSEvent object into a line of event text.
/// </summary>
/// <param name="eventFormat">The headings list from the "Format" of the "Events" section.</param>
/// <param name="spliter">The spliter used for stringify. Defaultly use ",".</param>
/// <returns>The event text converted from ASSEvent.</returns>
public string Stringify(IList<string> eventFormat, string spliter = ",")
{
var sb = new StringBuilder();
sb.Append(this.Type.ToString() + ": ");
for (var i = 0; i < eventFormat.Count; i++)
{
var field = eventFormat[i];
switch (field.Trim())
{
case "Layer": sb.Append(this.Layer); break;
case "Start": sb.Append(this.Start); break;
case "End": sb.Append(this.End); break;
case "Style": sb.Append(this.Style); break;
case "Name": sb.Append(this.Name); break;
case "MarginL": sb.Append(this.MarginL); break;
case "MarginR": sb.Append(this.MarginR); break;
case "MarginV": sb.Append(this.MarginV); break;
case "Effect": sb.Append(this.Effect); break;
case "Text": sb.Append(this.Text); break;
default:
log.Warn($"EVENT MAPPING ERROR: Unknown field skipped: [{field}].");
break;
}
if (i != eventFormat.Count - 1)
{
sb.Append(spliter);
}
}
return sb.ToString();
}

/// <summary>
/// Only for debug usage.
/// </summary>
/// <returns></returns>
public override string ToString()
{
return $"{Start} - {End} | {Type}:{Name}:{Text}";
}
}

}
128 changes: 128 additions & 0 deletions ASSLoader.NET/ASSEventTime.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
using System;
using System.Collections.Generic;
using System.Text;

namespace ASSLoader.NET
{
public class ASSEventTime : IComparable
{
public int Hour { get; set; }

public int Minute { get; set; }

public int Second { get; set; }

public int Millisecond { get; set; }

public ASSEventTime(string assTime)
{
var parts = assTime.Split(':', '.');
var msIndex = parts.Length - 1;
var secIndex = parts.Length - 2;
var minIndex = parts.Length - 3;
var hourIndex = parts.Length - 4;
this.Hour = hourIndex >= 0 ? Convert.ToInt32(parts[hourIndex]) : 0;
this.Minute = minIndex >= 0 ? Convert.ToInt32(parts[minIndex]) : 0;
this.Second = secIndex >= 0 ? Convert.ToInt32(parts[secIndex]) : 0;
this.Millisecond = msIndex >= 0 ? Convert.ToInt32((parts[msIndex] + "000").Substring(0, 3)) : 0;
}

public ASSEventTime(int hour, int minute, int second, int millisecond)
{
this.Hour = hour;
this.Minute = minute;
this.Second = second;
this.Millisecond = millisecond;
}

public long TotalMilliseconds()
{
return this.Hour * 3600000 + this.Minute * 60000 + this.Second * 1000 + this.Millisecond;
}

public static explicit operator ASSEventTime(TimeSpan ts)
{
return new ASSEventTime(ts.Hours, ts.Minutes, ts.Seconds, ts.Milliseconds);
}

public static explicit operator TimeSpan(ASSEventTime time)
{
return new TimeSpan(0, time.Hour, time.Minute, time.Second, time.Millisecond);
}

public static ASSEventTime operator +(ASSEventTime aet, double num)
{
var target = new ASSEventTime(aet.ToString());
var ms = Convert.ToInt32(Math.Floor(num * 1000));
target.Millisecond = target.Millisecond + ms;
if (target.Millisecond > 1000)
{
target.Second += target.Millisecond / 1000;
target.Millisecond = target.Millisecond % 1000;
}
if (target.Second > 60)
{
target.Minute += target.Second / 60;
target.Second = target.Second % 60;
}
if (target.Minute > 60)
{
target.Hour += target.Minute / 60;
target.Minute = target.Minute % 60;
}

return target;
}

public static ASSEventTime operator -(ASSEventTime aet, double num)
{
var ms = Convert.ToInt32(Math.Floor(num * 1000));
var target = new ASSEventTime(aet.ToString());
target.Millisecond = aet.Millisecond - ms;
if (target.Millisecond < 0)
{
target.Millisecond += 1000;
target.Second -= 1;
}
if (target.Second < 0)
{
target.Second += 60;
target.Minute -= 1;
}
if (target.Minute < 0)
{
target.Minute += 60;
target.Hour -= 1;
}
return target;
}

public override bool Equals(object obj)
{
return CompareTo(obj) == 0;
}

public override int GetHashCode()
{
return (int)this.TotalMilliseconds();
}

public override string ToString()
{
return this.Hour.ToString().Substring(0, 1) + ":"
+ this.Minute.ToString().PadLeft(2, '0') + ":"
+ this.Second.ToString().PadLeft(2, '0') + "."
+ this.Millisecond.ToString().PadLeft(3, '0').Substring(0, 2);
}

public int CompareTo(object obj)
{
var target = obj as ASSEventTime;
if (target == null)
{
target = new ASSEventTime(obj.ToString());
}
return (int)(this.TotalMilliseconds() - target.TotalMilliseconds());
}
}
}
14 changes: 10 additions & 4 deletions ASSLoader.NET/ASSLoader.NET.csproj
Original file line number Diff line number Diff line change
@@ -1,13 +1,19 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<TargetFrameworks>netstandard2.1;net45</TargetFrameworks>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<Version>0.0.1</Version>
<Version>0.9.3.3-pre</Version>
<Authors>Akaishi Toshiya</Authors>
<Company>RMEGo Studio</Company>
<Company>Shiba Studio</Company>
<Description>A ass subtitle toolkit.</Description>
<PackageProjectUrl>https://github.com/toshiya14/ASSLoader.NET</PackageProjectUrl>
</PropertyGroup>
<Copyright>Akaishi Toshiya</Copyright>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="log4net" Version="2.0.12" />
</ItemGroup>

</Project>
Loading