Fix - Couldn't parse different formatted vtt for CC subtitle https://github.com/Crunchy-DL/Crunchy-Downloader/issues/72
This commit is contained in:
Elwador 2024-08-11 21:39:23 +02:00
parent dff195ce1f
commit 3914e98dbb
5 changed files with 93 additions and 46 deletions

View File

@ -1402,17 +1402,29 @@ public class CrunchyrollManager{
assBuilder.AppendLine("Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text");
// Parse the VTT content
var lines = subsAssReqResponse.ResponseContent.Split(new[]{ Environment.NewLine }, StringSplitOptions.None);
string normalizedContent = subsAssReqResponse.ResponseContent.Replace("\r\n", "\n").Replace("\r", "\n");
var blocks = normalizedContent.Split(new[]{ "\n\n" }, StringSplitOptions.RemoveEmptyEntries);
Regex timePattern = new Regex(@"(?<start>\d{2}:\d{2}:\d{2}\.\d{3})\s-->\s(?<end>\d{2}:\d{2}:\d{2}\.\d{3})");
for (int i = 0; i < lines.Length; i++){
Match match = timePattern.Match(lines[i]);
foreach (var block in blocks){
// Split each block into lines
var lines = block.Split(new[]{ '\n' }, StringSplitOptions.RemoveEmptyEntries);
if (lines.Length < 3) continue; // Skip blocks that don't have enough lines
// Match the first line to get the time codes
Match match = timePattern.Match(lines[1]);
if (match.Success){
string startTime = Helpers.ConvertTimeFormat(match.Groups["start"].Value);
string endTime = Helpers.ConvertTimeFormat(match.Groups["end"].Value);
string dialogue = Helpers.ExtractDialogue(lines, i + 1);
// Join the remaining lines for dialogue, using \N for line breaks
string dialogue = string.Join("\\N", lines.Skip(2));
dialogue = Helpers.ConvertVTTStylesToASS(dialogue);
// Append dialogue to ASS
assBuilder.AppendLine($"Dialogue: 0,{startTime},{endTime},Default,,0000,0000,0000,,{dialogue}");
}
}

View File

@ -65,7 +65,6 @@ public class History(){
}
public void SetAsDownloaded(string? seriesId, string? seasonId, string episodeId){
var historySeries = crunInstance.HistoryList.FirstOrDefault(series => series.SeriesId == seriesId);
@ -129,18 +128,24 @@ public class History(){
return (null, downloadDirPath);
}
public (HistoryEpisode? historyEpisode, List<string> dublist, string downloadDirPath) GetHistoryEpisodeWithDubListAndDownloadDir(string? seriesId, string? seasonId, string episodeId){
public (HistoryEpisode? historyEpisode, List<string> dublist, List<string> sublist, string downloadDirPath) GetHistoryEpisodeWithDubListAndDownloadDir(string? seriesId, string? seasonId, string episodeId){
var historySeries = crunInstance.HistoryList.FirstOrDefault(series => series.SeriesId == seriesId);
var downloadDirPath = "";
List<string> dublist = [];
List<string> dublist =[];
List<string> sublist =[];
if (historySeries != null){
var historySeason = historySeries.Seasons.FirstOrDefault(s => s.SeasonId == seasonId);
if (historySeries.HistorySeriesDubLangOverride.Count > 0){
dublist = historySeries.HistorySeriesDubLangOverride;
}
if (historySeries.HistorySeriesSoftSubsOverride.Count > 0){
sublist = historySeries.HistorySeriesSoftSubsOverride;
}
if (!string.IsNullOrEmpty(historySeries.SeriesDownloadPath)){
downloadDirPath = historySeries.SeriesDownloadPath;
}
@ -150,23 +155,28 @@ public class History(){
if (historySeason.HistorySeasonDubLangOverride.Count > 0){
dublist = historySeason.HistorySeasonDubLangOverride;
}
if (historySeason.HistorySeasonSoftSubsOverride.Count > 0){
sublist = historySeason.HistorySeasonSoftSubsOverride;
}
if (!string.IsNullOrEmpty(historySeason.SeasonDownloadPath)){
downloadDirPath = historySeason.SeasonDownloadPath;
}
if (historyEpisode != null){
return (historyEpisode, dublist,downloadDirPath);
return (historyEpisode, dublist, sublist, downloadDirPath);
}
}
}
return (null, dublist,downloadDirPath);
return (null, dublist, sublist, downloadDirPath);
}
public List<string> GetDubList(string? seriesId, string? seasonId){
var historySeries = crunInstance.HistoryList.FirstOrDefault(series => series.SeriesId == seriesId);
List<string> dublist = [];
List<string> dublist =[];
if (historySeries != null){
var historySeason = historySeries.Seasons.FirstOrDefault(s => s.SeasonId == seasonId);
@ -181,7 +191,25 @@ public class History(){
return dublist;
}
public List<string> GetSubList(string? seriesId, string? seasonId){
var historySeries = crunInstance.HistoryList.FirstOrDefault(series => series.SeriesId == seriesId);
List<string> sublist =[];
if (historySeries != null){
var historySeason = historySeries.Seasons.FirstOrDefault(s => s.SeasonId == seasonId);
if (historySeries.HistorySeriesSoftSubsOverride.Count > 0){
sublist = historySeries.HistorySeriesSoftSubsOverride;
}
if (historySeason is{ HistorySeasonSoftSubsOverride.Count: > 0 }){
sublist = historySeason.HistorySeasonSoftSubsOverride;
}
}
return sublist;
}
public async Task UpdateWithEpisode(CrunchyEpisode episodeParam){
@ -256,13 +284,10 @@ public class History(){
SortItems();
SortSeasons(historySeries);
}
public async Task UpdateWithSeasonData(CrunchyEpisodeList seasonData,bool skippVersionCheck = true){
public async Task UpdateWithSeasonData(CrunchyEpisodeList seasonData, bool skippVersionCheck = true){
if (seasonData.Data != null){
if (!skippVersionCheck){
if (seasonData.Data.First().Versions != null){
var version = seasonData.Data.First().Versions.Find(a => a.Original);
@ -275,8 +300,8 @@ public class History(){
return;
}
}
var firstEpisode = seasonData.Data.First();
var seriesId = firstEpisode.SeriesId;
var historySeries = crunInstance.HistoryList.FirstOrDefault(series => series.SeriesId == seriesId);
@ -471,7 +496,7 @@ public class History(){
if (string.IsNullOrEmpty(identifier)){
return false;
}
// Regex pattern to match any sequence that does NOT contain "|S" followed by one or more digits immediately after
string pattern = @"^(?!.*\|S\d+).*";
@ -545,7 +570,7 @@ public class History(){
}
private static readonly object _lock = new object();
public async Task MatchHistoryEpisodesWithSonarr(bool updateAll, HistorySeries historySeries){
if (crunInstance.CrunOptions.SonarrProperties is{ SonarrEnabled: false }){
return;
@ -576,11 +601,11 @@ public class History(){
historyEpisode.SonarrHasFile = episode.HasFile;
historyEpisode.SonarrAbsolutNumber = episode.AbsoluteEpisodeNumber + "";
historyEpisode.SonarrSeasonNumber = episode.SeasonNumber + "";
lock (_lock) {
lock (_lock){
episodes.Remove(episode);
}
} else{
lock (_lock) {
lock (_lock){
failedEpisodes.Add(historyEpisode);
}
}
@ -604,7 +629,7 @@ public class History(){
historyEpisode.SonarrHasFile = episode.HasFile;
historyEpisode.SonarrAbsolutNumber = episode.AbsoluteEpisodeNumber + "";
historyEpisode.SonarrSeasonNumber = episode.SeasonNumber + "";
lock (_lock) {
lock (_lock){
episodes.Remove(episode);
}
} else{
@ -622,7 +647,7 @@ public class History(){
historyEpisode.SonarrHasFile = episode1.HasFile;
historyEpisode.SonarrAbsolutNumber = episode1.AbsoluteEpisodeNumber + "";
historyEpisode.SonarrSeasonNumber = episode1.SeasonNumber + "";
lock (_lock) {
lock (_lock){
episodes.Remove(episode1);
}
} else{
@ -639,7 +664,7 @@ public class History(){
historyEpisode.SonarrHasFile = episode2.HasFile;
historyEpisode.SonarrAbsolutNumber = episode2.AbsoluteEpisodeNumber + "";
historyEpisode.SonarrSeasonNumber = episode2.SeasonNumber + "";
lock (_lock) {
lock (_lock){
episodes.Remove(episode2);
}
} else{
@ -648,9 +673,8 @@ public class History(){
}
}
});
CfgManager.UpdateHistoryFile();
}
}
@ -712,7 +736,7 @@ public class History(){
return highestSimilarity < 0.8 ? null : closestMatch;
}
public CrBrowseSeries? FindClosestMatchCrSeries(List<CrBrowseSeries> episodeList, string title){
CrBrowseSeries? closestMatch = null;
double highestSimilarity = 0.0;

View File

@ -100,7 +100,7 @@ public class QueueManager{
var sList = await CrunchyrollManager.Instance.CrEpisode.EpisodeData((CrunchyEpisode)episodeL, updateHistory);
(HistoryEpisode? historyEpisode, List<string> dublist, string downloadDirPath) historyEpisode = (null, [], "");
(HistoryEpisode? historyEpisode, List<string> dublist, List<string> sublist, string downloadDirPath) historyEpisode = (null, [], [], "");
if (CrunchyrollManager.Instance.CrunOptions.History){
var episode = sList.EpisodeAndLanguages.Items.First();
@ -141,7 +141,8 @@ public class QueueManager{
}
}
selected.DownloadSubs = CrunchyrollManager.Instance.CrunOptions.DlSubs;
selected.DownloadSubs = historyEpisode.sublist.Count > 0 ? historyEpisode.sublist : CrunchyrollManager.Instance.CrunOptions.DlSubs;
Queue.Add(selected);
@ -175,12 +176,12 @@ public class QueueManager{
}
}
public void CrAddEpMetaToQueue(CrunchyEpMeta epMeta){
Queue.Add(epMeta);
MessageBus.Current.SendMessage(new ToastMessage($"Added episode to the queue", ToastType.Information, 1));
Queue.Add(epMeta);
MessageBus.Current.SendMessage(new ToastMessage($"Added episode to the queue", ToastType.Information, 1));
}
public async Task CrAddMusicVideoToQueue(string epId){
await CrunchyrollManager.Instance.CrAuth.RefreshToken(true);
@ -191,13 +192,11 @@ public class QueueManager{
Queue.Add(musicVideoMeta);
MessageBus.Current.SendMessage(new ToastMessage($"Added music video to the queue", ToastType.Information, 1));
}
}
public async Task CrAddConcertToQueue(string epId){
await CrunchyrollManager.Instance.CrAuth.RefreshToken(true);
var concert = await CrunchyrollManager.Instance.CrMusic.ParseConcertByIdAsync(epId, "");
if (concert != null){
@ -205,7 +204,6 @@ public class QueueManager{
Queue.Add(concertMeta);
MessageBus.Current.SendMessage(new ToastMessage($"Added concert to the queue", ToastType.Information, 1));
}
}
@ -213,7 +211,7 @@ public class QueueManager{
var selected = CrunchyrollManager.Instance.CrSeries.ItemSelectMultiDub(list.Data, data.DubLang, data.But, data.AllEpisodes, data.E);
bool failed = false;
foreach (var crunchyEpMeta in selected.Values.ToList()){
if (crunchyEpMeta.Data?.First().Playback != null){
if (CrunchyrollManager.Instance.CrunOptions.History){
@ -243,7 +241,10 @@ public class QueueManager{
}
}
crunchyEpMeta.DownloadSubs = CrunchyrollManager.Instance.CrunOptions.DlSubs;
var subLangList = CrunchyrollManager.Instance.History.GetSubList(crunchyEpMeta.ShowId, crunchyEpMeta.SeasonId);
crunchyEpMeta.DownloadSubs = subLangList.Count > 0 ? subLangList : CrunchyrollManager.Instance.CrunOptions.DlSubs;
Queue.Add(crunchyEpMeta);
} else{
failed = true;

View File

@ -42,6 +42,19 @@ public class Helpers{
return $"{hours}:{minutes:D2}:{seconds:D2}.{milliseconds / 10:D2}";
}
public static string ConvertVTTStylesToASS(string dialogue){
dialogue = Regex.Replace(dialogue, @"<b>", "{\\b1}");
dialogue = Regex.Replace(dialogue, @"</b>", "{\\b0}");
dialogue = Regex.Replace(dialogue, @"<i>", "{\\i1}");
dialogue = Regex.Replace(dialogue, @"</i>", "{\\i0}");
dialogue = Regex.Replace(dialogue, @"<u>", "{\\u1}");
dialogue = Regex.Replace(dialogue, @"</u>", "{\\u0}");
dialogue = Regex.Replace(dialogue, @"<[^>]+>", ""); // Remove any other HTML-like tags
return dialogue;
}
public static string ExtractDialogue(string[] lines, int startLine){
var dialogueBuilder = new StringBuilder();
@ -410,7 +423,4 @@ public class Helpers{
return languageGroups;
}
}

View File

@ -301,7 +301,7 @@
Description="MKVMerge and FFMpeg Settings"
IsExpanded="False">
<controls:SettingsExpanderItem Content="MP4">
<controls:SettingsExpanderItem Content="MP4" Description="Outputs a mp4 instead of an mkv - not recommended to use this option">
<controls:SettingsExpanderItem.Footer>
<CheckBox IsChecked="{Binding MuxToMp4}"> </CheckBox>
</controls:SettingsExpanderItem.Footer>