New Plugin c/o ChatGPT
Maintainer thường phản hồi trong vòng 1 ngày
Chưa có ai nhận issue này.
Đánh giá
- Độ khó
- 5/5
- Thời gian dự kiến
- Hơn một tuần
- Mức phù hợp với người mới
- 25/100
Hướng nghiên cứu
Bắt đầu bằng việc xem xét mã ProblemLinePlugin được cung cấp và tham chiếu của nó đến Nikse.SubtitleEdit.PluginInterface.dll, sau đó so sánh phần triển khai IPlugin của nó với hành vi phát hiện plugin phía sau mục Plugins của Subtitle Edit. Xác định cần những gì để plugin xuất hiện và liệu workflow hiệu chỉnh các dòng được đánh dấu được đề xuất có được hỗ trợ hay không. Hoàn tất có nghĩa là plugin tải được trong Subtitle Edit và có thể nhắm đến các dòng có vấn đề dự kiến.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
I thought I'd see if I could get ChatGPT to help write a plugin for Subtitle Edit that would allow me to select all highlighted problem lines for targeted correction (a feature I've wanted incorporating into SE for a long time). This would allow, for example, the auto-balancing of only lines deemed to be of excessive length (rather than every single line, as is currently the case).
Unfortunately, I kept hitting a snag seemingly relating to Nikse.SubtitleEdit.PluginInterface.dll (in that the code below would build successfully in Visual Studio but not appear in the SE Plugins section) and ChatGPT could offer no useful advice about how to resolve this issue.
Could anyone who knows anything about Subtitle Edit plugins please take a look at the code below and let me know if it was even anywhere close to working? Possibly this whole endeavour was a waste of time, given that I know nothing about C#, but it seemed worth a try!
using Nikse.SubtitleEdit.PluginInterface;
using System;
using System.Collections.Generic;
using System.Windows.Forms;
using System.Text;
using System.Text.RegularExpressions;
namespace SubtitleEdit.ProblemLineHighlighter
{
public class ProblemLinePlugin : IPlugin
{
private Subtitle _subtitle;
private SubRip _subRipFormat;
public string Name => "Problem Line Highlighter";
public string Text => "Highlight problem lines in subtitles";
public string Version => "1.0";
public void Initialize()
{
_subRipFormat = new SubRip();
_subtitle = new Subtitle(_subRipFormat);
}
public bool DoesShowDialog()
{
return true;
}
public void ShowDialog()
{
MessageBox.Show("Problem Line Highlighter Plugin loaded!");
// Here you can later add UI or further plugin logic
}
// You can expose your subtitle loading logic here, example:
public void LoadSubtitleFromLines(string[] lines)
{
_subtitle.Paragraphs.Clear();
var listLines = new List<string>(lines);
_subRipFormat.LoadSubtitle(_subtitle, listLines, "Example.srt");
_subtitle.Renumber(1);
}
public string GetSubtitleText()
{
return _subtitle.ToText();
}
}
// Paste your Subtitle, SubRip, Paragraph, TimeCode classes here (internal or public as needed)
// For brevity, you can keep them as internal classes below the plugin class,
// or move to separate files as your project grows.
internal class Paragraph
{
public int Number { get; set; }
public TimeCode StartTime { get; set; }
public TimeCode EndTime { get; set; }
public string Text { get; set; }
public Paragraph()
{
Text = string.Empty;
StartTime = new TimeCode();
EndTime = new TimeCode();
}
}
internal class TimeCode
{
public int Hours { get; set; }
public int Minutes { get; set; }
public int Seconds { get; set; }
public int Milliseconds { get; set; }
public TimeCode() { }
public TimeCode(int hours, int minutes, int seconds, int milliseconds)
{
Hours = hours;
Minutes = minutes;
Seconds = seconds;
Milliseconds = milliseconds;
}
public override string ToString()
{
return $"{Hours:D2}:{Minutes:D2}:{Seconds:D2},{Milliseconds:D3}";
}
public void AddTime(TimeSpan timeSpan)
{
var totalMs = ToTimeSpan().TotalMilliseconds + timeSpan.TotalMilliseconds;
if (totalMs < 0) totalMs = 0;
var ts = TimeSpan.FromMilliseconds(totalMs);
Hours = ts.Hours;
Minutes = ts.Minutes;
Seconds = ts.Seconds;
Milliseconds = ts.Milliseconds;
}
public TimeSpan ToTimeSpan()
{
return new TimeSpan(0, Hours, Minutes, Seconds, Milliseconds);
}
}
internal class Subtitle
{
private List<Paragraph> _paragraphs;
private readonly SubRip _format;
public string Header { get; set; }
public string Footer { get; set; }
public string FileName { get; set; }
public bool IsHearingImpaired { get; private set; }
public List<Paragraph> Paragraphs => _paragraphs;
public Subtitle(SubRip subrip)
{
_paragraphs = new List<Paragraph>();
FileName = "Untitled";
_format = subrip;
}
public Paragraph GetParagraphOrDefault(int index)
{
if (_paragraphs == null || _paragraphs.Count <= index || index < 0)
return null;
return _paragraphs[index];
}
public string ToText()
{
return _format.ToText(this, System.IO.Path.GetFileNameWithoutExtension(FileName));
}
public void AddTimeToAllParagraphs(TimeSpan time)
{
foreach (var paragraph in Paragraphs)
{
paragraph.StartTime.AddTime(time);
paragraph.EndTime.AddTime(time);
}
}
public void Renumber(int startNumber)
{
int num = ((startNumber >= 0) ? startNumber : 0);
foreach (var paragraph in _paragraphs)
{
paragraph.Number = num;
num++;
}
}
}
internal class SubRip
{
private enum ExpectingLine
{
Number,
TimeCodes,
Text
}
private static Regex RegexTimeCodes = new Regex(@"^\d{1,2}:\d{2}:\d{2}[,.:]\d{1,3}\s*-->\s*\d{1,2}:\d{2}:\d{2}[,.:]\d{1,3}$", RegexOptions.Compiled);
private ExpectingLine _expecting;
private Paragraph _paragraph;
private int _errorCount;
public string Extension => ".srt";
public string Name => "SubRip";
public int ErrorCount => _errorCount;
public void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
{
bool flag = false;
_paragraph = new Paragraph();
_expecting = ExpectingLine.Number;
_errorCount = 0;
subtitle.Paragraphs.Clear();
for (int i = 0; i < lines.Count; i++)
{
string text = lines[i].TrimEnd();
text = text.Trim('\u007f');
string next = (i + 1 < lines.Count) ? lines[i + 1] : string.Empty;
if (_expecting == ExpectingLine.Text && i + 1 < lines.Count && _paragraph != null && !string.IsNullOrEmpty(_paragraph.Text) && int.TryParse(text, out _) && RegexTimeCodes.IsMatch(lines[i + 1]))
{
_errorCount++;
ReadLine(subtitle, string.Empty, string.Empty);
}
if (_expecting == ExpectingLine.Number && RegexTimeCodes.IsMatch(text))
{
_errorCount++;
_expecting = ExpectingLine.TimeCodes;
flag = true;
}
ReadLine(subtitle, text, next);
}
if (_paragraph.Text.Trim().Length > 0)
subtitle.Paragraphs.Add(_paragraph);
foreach (var paragraph in subtitle.Paragraphs)
paragraph.Text = paragraph.Text.Replace(Environment.NewLine + Environment.NewLine, Environment.NewLine);
if (_errorCount < 100 && flag)
subtitle.Renumber(1);
}
public string ToText(Subtitle subtitle, string title)
{
var sb = new StringBuilder();
foreach (var paragraph in subtitle.Paragraphs)
{
var text = paragraph.Text.Replace(Environment.NewLine + Environment.NewLine, Environment.NewLine);
sb.Append($"{paragraph.Number}\r\n{paragraph.StartTime} --> {paragraph.EndTime}\r\n{text}\r\n\r\n");
}
return sb.ToString().Trim();
}
private void ReadLine(Subtitle subtitle, string line, string next)
{
switch (_expecting)
{
case ExpectingLine.Number:
if (int.TryParse(line, out int number))
{
_paragraph.Number = number;
_expecting = ExpectingLine.TimeCodes;
}
else if (line.Trim().Length > 0)
{
_errorCount++;
}
break;
case ExpectingLine.TimeCodes:
if (TryReadTimeCodesLine(line, _paragraph))
{
_paragraph.Text = string.Empty;
_expecting = ExpectingLine.Text;
}
else if (line.Trim().Length > 0)
{
_errorCount++;
_expecting = ExpectingLine.Number;
}
break;
case ExpectingLine.Text:
if (!string.IsNullOrWhiteSpace(line))
{
if (_paragraph.Text.Length > 0)
_paragraph.Text += Environment.NewLine;
_paragraph.Text += line.TrimEnd().Replace(Environment.NewLine + Environment.NewLine, Environment.NewLine);
}
else if (!string.IsNullOrWhiteSpace(next) && (int.TryParse(next, out _) || RegexTimeCodes.IsMatch(next)))
{
subtitle.Paragraphs.Add(_paragraph);
_paragraph = new Paragraph();
_expecting = ExpectingLine.Number;
}
break;
}
}
private bool TryReadTimeCodesLine(string line, Paragraph paragraph)
{
line = line.Replace('،', ',').Replace('\uf7c8', ',').Replace('¡', ',');
line = line.Replace(" -> ", " --> ").Replace(" - > ", " --> ").Replace(" ->> ", " --> ");
line = line.Replace(" -- > ", " --> ").Replace(" - -> ", " --> ").Replace(" -->> ", " --> ").Replace(" ---> ", " --> ");
line = line.Trim();
line = line.Replace('.', ':');
line = Regex.Replace(line, @"\s+", " ");
if (!RegexTimeCodes.IsMatch(line))
return false;
string[] parts = line.Split(new[] { ' ', '-', '>', ':', ',' }, StringSplitOptions.RemoveEmptyEntries);
try
{
int h1 = int.Parse(parts[0]);
int m1 = int.Parse(parts[1]);
int s1 = int.Parse(parts[2]);
int ms1 = int.Parse(parts[3]);
int h2 = int.Parse(parts[4]);
int m2 = int.Parse(parts[5]);
int s2 = int.Parse(parts[6]);
int ms2 = int.Parse(parts[7]);
paragraph.StartTime = new TimeCode(h1, m1, s1, ms1);
paragraph.EndTime = new TimeCode(h2, m2, s2, ms2);
return true;
}
catch
{
return false;
}
}
}
}
- Ngôn ngữ chính
- C#
- Star
- 138
- Fork
- 49
- Merge trung bình
- 28 phút
- Pull request đã merge (30 ngày)
- 24
Chuẩn bị môi trường
Dự án này không cung cấp dev container, Dockerfile hay hướng dẫn đóng góp, nên bạn cần tự thiết lập môi trường: hãy bắt đầu từ README và xem hướng dẫn đóng góp lần đầu của chúng tôi để biết các bước chung.
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của SubtitleEdit/plugins
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 45/100
SubtitleEdit/plugins#286 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
HELP WITH REBALANCINGĐang mở
Độ khó 3/5 1-2 ngày Mức phù hợp với người mới 48/100
SubtitleEdit/plugins#283 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 5/5 Hơn một tuần Mức phù hợp với người mới 25/100
SubtitleEdit/plugins#274 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 3/5 1-2 ngày Mức phù hợp với người mới 25/100
SubtitleEdit/plugins#266 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 5/5 Hơn một tuần Mức phù hợp với người mới 25/100
SubtitleEdit/plugins#265 · 2 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
Tất cả issue của SubtitleEdit/plugins
Issue tương tự
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 75/100
rjmurillo/moq.analyzers#1468 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 83/100
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
-
[誤判定] `define` が `デフィね`・`デフィ値` になるCó thể đã có người làm Có pull request liên kết đang mở hoặc đã được merge. Đang mở再現済み 要トリアージ 誤判定
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
yksr-melt/Meltype#421 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 64/100
Facepunch/sbox-public#12063 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 2 ngày