From 771ebfe074dc253a975567b715728d3f24ccc5fe Mon Sep 17 00:00:00 2001 From: Elwador <75888166+Elwador@users.noreply.github.com> Date: Tue, 30 Jul 2024 12:12:02 +0200 Subject: [PATCH] Fix - Crash with multiple OVAs in series Fix - FFMPEG error with chapters --- CRD/Downloader/Crunchyroll/CrSeries.cs | 13 +++++++--- CRD/Utils/Helpers.cs | 29 ++++++++++++++++------ CRD/ViewModels/AddDownloadPageViewModel.cs | 8 +++--- 3 files changed, 36 insertions(+), 14 deletions(-) diff --git a/CRD/Downloader/Crunchyroll/CrSeries.cs b/CRD/Downloader/Crunchyroll/CrSeries.cs index d22ac27..dfdb66c 100644 --- a/CRD/Downloader/Crunchyroll/CrSeries.cs +++ b/CRD/Downloader/Crunchyroll/CrSeries.cs @@ -160,7 +160,7 @@ public class CrSeries(){ var seasonData = await GetSeasonDataById(s.Id, ""); if (seasonData.Data != null){ if (crunInstance.CrunOptions.History){ - crunInstance.History.UpdateWithSeasonData(seasonData,false); + crunInstance.History.UpdateWithSeasonData(seasonData, false); } foreach (var episode in seasonData.Data){ @@ -229,11 +229,18 @@ public class CrSeries(){ string newKey; if (isSpecial && !string.IsNullOrEmpty(item.Items[0].Episode)){ - newKey = item.Items[0].Episode ?? "SP" + (specialIndex + " " + item.Items[0].Id); + newKey = $"SP{specialIndex}_" + item.Items[0].Episode ?? "SP" + (specialIndex + " " + item.Items[0].Id); } else{ newKey = $"{(isSpecial ? "SP" : 'E')}{(isSpecial ? (specialIndex + " " + item.Items[0].Id) : epIndex + "")}"; } + int counter = 1; + string originalKey = newKey; + while (episodes.ContainsKey(newKey)){ + newKey = originalKey + "_" + counter; + counter++; + } + episodes.Remove(key); episodes.Add(newKey, item); @@ -285,7 +292,7 @@ public class CrSeries(){ Season = Helpers.ExtractNumberAfterS(value.Items[0].Identifier) ?? value.Items[0].SeasonNumber.ToString(), SeriesTitle = Regex.Replace(value.Items[0].SeriesTitle, @"\(\w+ Dub\)", "").TrimEnd(), SeasonTitle = Regex.Replace(value.Items[0].SeasonTitle, @"\(\w+ Dub\)", "").TrimEnd(), - EpisodeNum = value.Items[0].EpisodeNumber?.ToString() ?? value.Items[0].Episode ?? "?", + EpisodeNum = key.StartsWith("SP") ? key : value.Items[0].EpisodeNumber?.ToString() ?? value.Items[0].Episode ?? "?", Id = value.Items[0].SeasonId, Img = images[images.Count / 2].FirstOrDefault().Source, Description = value.Items[0].Description, diff --git a/CRD/Utils/Helpers.cs b/CRD/Utils/Helpers.cs index 7af37a7..237b6ec 100644 --- a/CRD/Utils/Helpers.cs +++ b/CRD/Utils/Helpers.cs @@ -133,6 +133,7 @@ public class Helpers{ public static void ConvertChapterFileForFFMPEG(string chapterFilePath){ var chapterLines = File.ReadAllLines(chapterFilePath); var ffmpegChapterLines = new List{ ";FFMETADATA1" }; + var chapters = new List<(double StartTime, string Title)>(); for (int i = 0; i < chapterLines.Length; i += 2){ var timeLine = chapterLines[i]; @@ -143,16 +144,30 @@ public class Helpers{ if (timeParts.Length == 2 && nameParts.Length == 2){ var startTime = TimeSpan.Parse(timeParts[1]).TotalMilliseconds; - var endTime = i + 2 < chapterLines.Length ? TimeSpan.Parse(chapterLines[i + 2].Split('=')[1]).TotalMilliseconds : startTime + 10000; - - ffmpegChapterLines.Add("[CHAPTER]"); - ffmpegChapterLines.Add("TIMEBASE=1/1000"); - ffmpegChapterLines.Add($"START={startTime}"); - ffmpegChapterLines.Add($"END={endTime}"); - ffmpegChapterLines.Add($"title={nameParts[1]}"); + var title = nameParts[1]; + chapters.Add((startTime, title)); } } + // Sort chapters by start time + chapters = chapters.OrderBy(c => c.StartTime).ToList(); + + for (int i = 0; i < chapters.Count; i++){ + var startTime = chapters[i].StartTime; + var title = chapters[i].Title; + var endTime = (i + 1 < chapters.Count) ? chapters[i + 1].StartTime : startTime + 10000; // Add 10 seconds to the last chapter end time + + if (endTime < startTime) { + endTime = startTime + 10000; // Correct end time if it is before start time + } + + ffmpegChapterLines.Add("[CHAPTER]"); + ffmpegChapterLines.Add("TIMEBASE=1/1000"); + ffmpegChapterLines.Add($"START={startTime}"); + ffmpegChapterLines.Add($"END={endTime}"); + ffmpegChapterLines.Add($"title={title}"); + } + File.WriteAllLines(chapterFilePath, ffmpegChapterLines); } diff --git a/CRD/ViewModels/AddDownloadPageViewModel.cs b/CRD/ViewModels/AddDownloadPageViewModel.cs index eb1f4e5..c596646 100644 --- a/CRD/ViewModels/AddDownloadPageViewModel.cs +++ b/CRD/ViewModels/AddDownloadPageViewModel.cs @@ -235,11 +235,11 @@ public partial class AddDownloadPageViewModel : ViewModelBase{ currentSeriesList = list; foreach (var episode in currentSeriesList.Value.List){ if (episodesBySeason.ContainsKey("S" + episode.Season)){ - episodesBySeason["S" + episode.Season].Add(new ItemModel(episode.Img, episode.Description, episode.Time, episode.Name, "S" + episode.Season, "E" + episode.EpisodeNum, episode.E, + episodesBySeason["S" + episode.Season].Add(new ItemModel(episode.Img, episode.Description, episode.Time, episode.Name, "S" + episode.Season, episode.EpisodeNum.StartsWith("SP") ? episode.EpisodeNum : "E" + episode.EpisodeNum, episode.E, episode.Lang)); } else{ episodesBySeason.Add("S" + episode.Season, new List{ - new ItemModel(episode.Img, episode.Description, episode.Time, episode.Name, "S" + episode.Season, "E" + episode.EpisodeNum, episode.E, episode.Lang) + new ItemModel(episode.Img, episode.Description, episode.Time, episode.Name, "S" + episode.Season, episode.EpisodeNum.StartsWith("SP") ? episode.EpisodeNum : "E" + episode.EpisodeNum, episode.E, episode.Lang) }); SeasonList.Add(new ComboBoxItem{ Content = "S" + episode.Season }); } @@ -346,11 +346,11 @@ public partial class AddDownloadPageViewModel : ViewModelBase{ currentSeriesList = list; foreach (var episode in currentSeriesList.Value.List){ if (episodesBySeason.ContainsKey("S" + episode.Season)){ - episodesBySeason["S" + episode.Season].Add(new ItemModel(episode.Img, episode.Description, episode.Time, episode.Name, "S" + episode.Season, "E" + episode.EpisodeNum, episode.E, + episodesBySeason["S" + episode.Season].Add(new ItemModel(episode.Img, episode.Description, episode.Time, episode.Name, "S" + episode.Season, episode.EpisodeNum.StartsWith("SP") ? episode.EpisodeNum : "E" + episode.EpisodeNum, episode.E, episode.Lang)); } else{ episodesBySeason.Add("S" + episode.Season, new List{ - new(episode.Img, episode.Description, episode.Time, episode.Name, "S" + episode.Season, "E" + episode.EpisodeNum, episode.E, episode.Lang) + new(episode.Img, episode.Description, episode.Time, episode.Name, "S" + episode.Season, episode.EpisodeNum.StartsWith("SP") ? episode.EpisodeNum : "E" + episode.EpisodeNum, episode.E, episode.Lang) }); SeasonList.Add(new ComboBoxItem{ Content = "S" + episode.Season }); }