/// <summary> /// Validates any imported chapter information against the currently detected chapter information in the /// source media. If validation fails then an error message is returned via the out parameter <see cref="validationErrorMessage"/> /// </summary> /// <param name="importedChapters">The list of imported chapter information</param> /// <param name="validationErrorMessage">In case of a validation error this variable will hold /// a detailed message that can be presented to the user</param> /// <returns>True if there are no errors with imported chapters, false otherwise</returns> private bool ValidateImportedChapters(Dictionary <int, Tuple <string, TimeSpan> > importedChapters, out string validationErrorMessage, bool hasTimestamps) { validationErrorMessage = null; // If the number of chapters don't match, prompt for confirmation if (importedChapters.Count != this.Chapters.Count) { if (this.errorService.ShowMessageBox( string.Format(Resources.ChaptersViewModel_ValidateImportedChapters_ChapterCountMismatchMsg, this.Chapters.Count, importedChapters.Count), Resources.ChaptersViewModel_ValidateImportedChapters_ChapterCountMismatchWarning, MessageBoxButton.YesNo, MessageBoxImage.Question) != MessageBoxResult.Yes) { return(false); } } // If the average discrepancy in timings between chapters is either: // a) more than 15 sec for more than 2 chapters // (I chose 15sec based on empirical evidence from testing a few DVDs and comparing to chapter-marker files I downloaded) // => This check will not be performed for the first and last chapter as they're very likely to differ significantly due to language and region // differences (e.g. longer title sequences and different distributor credits) if (hasTimestamps) { List <TimeSpan> diffs = new List <TimeSpan>(); foreach (KeyValuePair <int, Tuple <string, TimeSpan> > import in importedChapters) { ChapterMarker sourceMarker = this.Chapters[import.Key - 1]; TimeSpan source = sourceMarker.Duration; TimeSpan diff = source - import.Value.Item2; diffs.Add(diff); } // var diffs = importedChapters.Zip(this.Chapters, (import, source) => source.Duration - import.Value.Item2); if (diffs.Count(diff => Math.Abs(diff.TotalSeconds) > 15) > 2) { if (this.errorService.ShowMessageBox( Resources.ChaptersViewModel_ValidateImportedChapters_ChapterDurationMismatchMsg, Resources.ChaptersViewModel_ValidateImportedChapters_ChapterDurationMismatchWarning, MessageBoxButton.YesNo, MessageBoxImage.Question) != MessageBoxResult.Yes) { return(false); } } } // All is well, we should import chapters return(true); }
/// <summary> /// Set the Source Chapters List /// </summary> /// <param name="sourceChapters"> /// The source chapters. /// </param> public void SetSourceChapters(IEnumerable <Chapter> sourceChapters) { // Cache the chapters in this screen this.SourceChapterList = new ObservableCollection <Chapter>(sourceChapters); this.Task.ChapterNames.Clear(); // Then Add new Chapter Markers. int counter = 1; foreach (Chapter chapter in this.SourceChapterList) { string chapterName = string.IsNullOrEmpty(chapter.ChapterName) ? string.Format("Chapter {0}", counter) : chapter.ChapterName; var marker = new ChapterMarker(chapter.ChapterNumber, chapterName, chapter.Duration); this.Task.ChapterNames.Add(marker); counter += 1; } }
/// <summary> /// Set the Source Chapters List /// </summary> /// <param name="sourceChapters"> /// The source chapters. /// </param> public void SetSourceChapters(IEnumerable<Chapter> sourceChapters) { // Cache the chapters in this screen this.SourceChapterList = new ObservableCollection<Chapter>(sourceChapters); this.Task.ChapterNames.Clear(); // Then Add new Chapter Markers. int counter = 1; foreach (Chapter chapter in this.SourceChapterList) { string chapterName = string.IsNullOrEmpty(chapter.ChapterName) ? string.Format("Chapter {0}", counter) : chapter.ChapterName; var marker = new ChapterMarker(chapter.ChapterNumber, chapterName, chapter.Duration); this.Task.ChapterNames.Add(marker); counter += 1; } }