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"); assBuilder.AppendLine("Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text");
// Parse the VTT content // 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})"); 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++){ foreach (var block in blocks){
Match match = timePattern.Match(lines[i]); // 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){ if (match.Success){
string startTime = Helpers.ConvertTimeFormat(match.Groups["start"].Value); string startTime = Helpers.ConvertTimeFormat(match.Groups["start"].Value);
string endTime = Helpers.ConvertTimeFormat(match.Groups["end"].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}"); 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){ public void SetAsDownloaded(string? seriesId, string? seasonId, string episodeId){
var historySeries = crunInstance.HistoryList.FirstOrDefault(series => series.SeriesId == seriesId); var historySeries = crunInstance.HistoryList.FirstOrDefault(series => series.SeriesId == seriesId);
@ -130,17 +129,23 @@ public class History(){
return (null, downloadDirPath); 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 historySeries = crunInstance.HistoryList.FirstOrDefault(series => series.SeriesId == seriesId);
var downloadDirPath = ""; var downloadDirPath = "";
List<string> dublist = []; List<string> dublist =[];
List<string> sublist =[];
if (historySeries != null){ if (historySeries != null){
var historySeason = historySeries.Seasons.FirstOrDefault(s => s.SeasonId == seasonId); var historySeason = historySeries.Seasons.FirstOrDefault(s => s.SeasonId == seasonId);
if (historySeries.HistorySeriesDubLangOverride.Count > 0){ if (historySeries.HistorySeriesDubLangOverride.Count > 0){
dublist = historySeries.HistorySeriesDubLangOverride; dublist = historySeries.HistorySeriesDubLangOverride;
} }
if (historySeries.HistorySeriesSoftSubsOverride.Count > 0){
sublist = historySeries.HistorySeriesSoftSubsOverride;
}
if (!string.IsNullOrEmpty(historySeries.SeriesDownloadPath)){ if (!string.IsNullOrEmpty(historySeries.SeriesDownloadPath)){
downloadDirPath = historySeries.SeriesDownloadPath; downloadDirPath = historySeries.SeriesDownloadPath;
} }
@ -150,23 +155,28 @@ public class History(){
if (historySeason.HistorySeasonDubLangOverride.Count > 0){ if (historySeason.HistorySeasonDubLangOverride.Count > 0){
dublist = historySeason.HistorySeasonDubLangOverride; dublist = historySeason.HistorySeasonDubLangOverride;
} }
if (historySeason.HistorySeasonSoftSubsOverride.Count > 0){
sublist = historySeason.HistorySeasonSoftSubsOverride;
}
if (!string.IsNullOrEmpty(historySeason.SeasonDownloadPath)){ if (!string.IsNullOrEmpty(historySeason.SeasonDownloadPath)){
downloadDirPath = historySeason.SeasonDownloadPath; downloadDirPath = historySeason.SeasonDownloadPath;
} }
if (historyEpisode != null){ 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){ public List<string> GetDubList(string? seriesId, string? seasonId){
var historySeries = crunInstance.HistoryList.FirstOrDefault(series => series.SeriesId == seriesId); var historySeries = crunInstance.HistoryList.FirstOrDefault(series => series.SeriesId == seriesId);
List<string> dublist = []; List<string> dublist =[];
if (historySeries != null){ if (historySeries != null){
var historySeason = historySeries.Seasons.FirstOrDefault(s => s.SeasonId == seasonId); var historySeason = historySeries.Seasons.FirstOrDefault(s => s.SeasonId == seasonId);
@ -182,6 +192,24 @@ public class History(){
return dublist; 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){ public async Task UpdateWithEpisode(CrunchyEpisode episodeParam){
@ -256,13 +284,10 @@ public class History(){
SortItems(); SortItems();
SortSeasons(historySeries); 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 (seasonData.Data != null){
if (!skippVersionCheck){ if (!skippVersionCheck){
if (seasonData.Data.First().Versions != null){ if (seasonData.Data.First().Versions != null){
var version = seasonData.Data.First().Versions.Find(a => a.Original); var version = seasonData.Data.First().Versions.Find(a => a.Original);
@ -576,11 +601,11 @@ public class History(){
historyEpisode.SonarrHasFile = episode.HasFile; historyEpisode.SonarrHasFile = episode.HasFile;
historyEpisode.SonarrAbsolutNumber = episode.AbsoluteEpisodeNumber + ""; historyEpisode.SonarrAbsolutNumber = episode.AbsoluteEpisodeNumber + "";
historyEpisode.SonarrSeasonNumber = episode.SeasonNumber + ""; historyEpisode.SonarrSeasonNumber = episode.SeasonNumber + "";
lock (_lock) { lock (_lock){
episodes.Remove(episode); episodes.Remove(episode);
} }
} else{ } else{
lock (_lock) { lock (_lock){
failedEpisodes.Add(historyEpisode); failedEpisodes.Add(historyEpisode);
} }
} }
@ -604,7 +629,7 @@ public class History(){
historyEpisode.SonarrHasFile = episode.HasFile; historyEpisode.SonarrHasFile = episode.HasFile;
historyEpisode.SonarrAbsolutNumber = episode.AbsoluteEpisodeNumber + ""; historyEpisode.SonarrAbsolutNumber = episode.AbsoluteEpisodeNumber + "";
historyEpisode.SonarrSeasonNumber = episode.SeasonNumber + ""; historyEpisode.SonarrSeasonNumber = episode.SeasonNumber + "";
lock (_lock) { lock (_lock){
episodes.Remove(episode); episodes.Remove(episode);
} }
} else{ } else{
@ -622,7 +647,7 @@ public class History(){
historyEpisode.SonarrHasFile = episode1.HasFile; historyEpisode.SonarrHasFile = episode1.HasFile;
historyEpisode.SonarrAbsolutNumber = episode1.AbsoluteEpisodeNumber + ""; historyEpisode.SonarrAbsolutNumber = episode1.AbsoluteEpisodeNumber + "";
historyEpisode.SonarrSeasonNumber = episode1.SeasonNumber + ""; historyEpisode.SonarrSeasonNumber = episode1.SeasonNumber + "";
lock (_lock) { lock (_lock){
episodes.Remove(episode1); episodes.Remove(episode1);
} }
} else{ } else{
@ -639,7 +664,7 @@ public class History(){
historyEpisode.SonarrHasFile = episode2.HasFile; historyEpisode.SonarrHasFile = episode2.HasFile;
historyEpisode.SonarrAbsolutNumber = episode2.AbsoluteEpisodeNumber + ""; historyEpisode.SonarrAbsolutNumber = episode2.AbsoluteEpisodeNumber + "";
historyEpisode.SonarrSeasonNumber = episode2.SeasonNumber + ""; historyEpisode.SonarrSeasonNumber = episode2.SeasonNumber + "";
lock (_lock) { lock (_lock){
episodes.Remove(episode2); episodes.Remove(episode2);
} }
} else{ } else{
@ -650,7 +675,6 @@ public class History(){
}); });
CfgManager.UpdateHistoryFile(); CfgManager.UpdateHistoryFile();
} }
} }

View File

@ -100,7 +100,7 @@ public class QueueManager{
var sList = await CrunchyrollManager.Instance.CrEpisode.EpisodeData((CrunchyEpisode)episodeL, updateHistory); 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){ if (CrunchyrollManager.Instance.CrunOptions.History){
var episode = sList.EpisodeAndLanguages.Items.First(); 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); Queue.Add(selected);
@ -177,8 +178,8 @@ public class QueueManager{
public void CrAddEpMetaToQueue(CrunchyEpMeta epMeta){ public void CrAddEpMetaToQueue(CrunchyEpMeta epMeta){
Queue.Add(epMeta); Queue.Add(epMeta);
MessageBus.Current.SendMessage(new ToastMessage($"Added episode to the queue", ToastType.Information, 1)); MessageBus.Current.SendMessage(new ToastMessage($"Added episode to the queue", ToastType.Information, 1));
} }
public async Task CrAddMusicVideoToQueue(string epId){ public async Task CrAddMusicVideoToQueue(string epId){
@ -191,8 +192,6 @@ public class QueueManager{
Queue.Add(musicVideoMeta); Queue.Add(musicVideoMeta);
MessageBus.Current.SendMessage(new ToastMessage($"Added music video to the queue", ToastType.Information, 1)); MessageBus.Current.SendMessage(new ToastMessage($"Added music video to the queue", ToastType.Information, 1));
} }
} }
public async Task CrAddConcertToQueue(string epId){ public async Task CrAddConcertToQueue(string epId){
@ -205,7 +204,6 @@ public class QueueManager{
Queue.Add(concertMeta); Queue.Add(concertMeta);
MessageBus.Current.SendMessage(new ToastMessage($"Added concert to the queue", ToastType.Information, 1)); MessageBus.Current.SendMessage(new ToastMessage($"Added concert to the queue", ToastType.Information, 1));
} }
} }
@ -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); Queue.Add(crunchyEpMeta);
} else{ } else{
failed = true; failed = true;

View File

@ -42,6 +42,19 @@ public class Helpers{
return $"{hours}:{minutes:D2}:{seconds:D2}.{milliseconds / 10:D2}"; 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){ public static string ExtractDialogue(string[] lines, int startLine){
var dialogueBuilder = new StringBuilder(); var dialogueBuilder = new StringBuilder();
@ -410,7 +423,4 @@ public class Helpers{
return languageGroups; return languageGroups;
} }
} }

View File

@ -301,7 +301,7 @@
Description="MKVMerge and FFMpeg Settings" Description="MKVMerge and FFMpeg Settings"
IsExpanded="False"> 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> <controls:SettingsExpanderItem.Footer>
<CheckBox IsChecked="{Binding MuxToMp4}"> </CheckBox> <CheckBox IsChecked="{Binding MuxToMp4}"> </CheckBox>
</controls:SettingsExpanderItem.Footer> </controls:SettingsExpanderItem.Footer>