public FormDiscInfo(Disc disc) { InitializeComponent(); _defaultJacketSizeMode = pictureBoxJacket.SizeMode; var fs = disc.FileSystem; var metadata = disc.Metadata; labelQuickSummary.Text = GenerateQuickSummary(metadata, fs); if (fs.Files.JacketImageSmall != null) { _hasSmallJacketImage = true; _smallJacketImagePath = fs.Files.JacketImageSmall.FullName; pictureBoxJacket.ImageLocation = _smallJacketImagePath; toolStripMenuItemJacketImagePath.Text = _smallJacketImagePath; } groupBoxJacket.Visible = _hasSmallJacketImage; discInfoMetadataPanel.SetDisc(disc); discInfoFeaturesPanel.SetDisc(disc); this.EnableSelectAll(); }
public void SetDisc(Disc disc) { var fs = disc.FileSystem; var metadata = disc.Metadata; var raw = metadata.Raw; var der = metadata.Derived; // textboxes InitTextAndIcon(iconHardwareVolumeLabel, textBoxHardwareVolumeLabel, raw.HardwareVolumeLabel); InitTextAndIcon(iconAnyDVDDiscInf, textBoxAnyDVDDiscInf, raw.DiscInf != null ? raw.DiscInf.ToString() : null); InitTextAndIcon(iconDboxTitle, textBoxDboxTitle, raw.DboxTitle); InitTextAndIcon(iconVISAN, textBoxVISAN, GetIsanText(raw.V_ISAN)); InitTextAndIcon(iconAllBdmtTitles, textBoxAllBdmtTitles, GetBdmtTitles(raw.AllBdmtTitles)); InitTextAndIcon(iconVolumeLabel, textBoxVolumeLabel, der.VolumeLabel); InitTextAndIcon(iconVolumeLabelSanitized, textBoxVolumeLabelSanitized, der.VolumeLabelSanitized); InitTextAndIcon(iconDboxTitleSanitized, textBoxDboxTitleSanitized, der.DboxTitleSanitized); InitTextAndIcon(iconIsan, textBoxIsan, GetIsanText(raw.ISAN)); InitTextAndIcon(iconValidBdmtTitles, textBoxValidBdmtTitles, GetBdmtTitles(der.ValidBdmtTitles)); // buttons InitButton(buttonHardwareVolumeLabel, fs.Directories.Root); InitButton(buttonAnyDVDDiscInf, fs.Files.AnyDVDDiscInf); InitButton(buttonDboxTitle, fs.Files.Dbox); InitButton(buttonVISAN, fs.Files.MCMF); InitButton(buttonAllBdmtTitles, fs.Directories.BDMT); InitButton(buttonVolumeLabel, fs.Directories.Root); InitButton(buttonVolumeLabelSanitized, fs.Directories.Root); InitButton(buttonDboxTitleSanitized, fs.Files.Dbox); InitButton(buttonIsan, fs.Files.MCMF); InitButton(buttonValidBdmtTitles, fs.Directories.BDMT); }
public static void Transform(BDInfo.BDROM bdrom, Disc disc) { var fs = new DiscFileSystem { Directories = new DiscFileSystem.DiscDirectories { Root = bdrom.DirectoryRoot, BDMV = bdrom.DirectoryBDMV, CLIPINF = bdrom.DirectoryCLIPINF, PLAYLIST = bdrom.DirectoryPLAYLIST, STREAM = bdrom.DirectorySTREAM, SSIF = bdrom.DirectorySSIF, BDMT = GetBDMTDirectory(bdrom.DirectoryBDMV), BDJO = bdrom.DirectoryBDJO, SNP = bdrom.DirectorySNP, ANY = GetDirectory("ANY!", bdrom.DirectoryRoot), MAKEMKV = GetDirectory("MAKEMKV", bdrom.DirectoryRoot), AACS = null /* assigned below */ }, Files = new DiscFileSystem.DiscFiles { AnyDVDDiscInf = GetFile("disc.inf", bdrom.DirectoryRoot), MCMF = null, /* assigned below */ BDMT = null, /* assigned below */ Dbox = GetFile("FilmIndex.xml", bdrom.DirectoryRoot) } }; fs.Directories.AACS = GetAACSDirectory(fs); fs.Files.MCMF = GetFileOrBackup("mcmf.xml", fs.Directories.AACS); fs.Files.BDMT = GetFilesByPattern("bdmt_???.xml", fs.Directories.BDMT); disc.FileSystem = fs; }
public static void Transform(Disc disc) { var raw = new DiscMetadata.RawMetadata { HardwareVolumeLabel = GetHardwareVolumeLabel(disc), DiscInf = GetAnyDVDDiscInf(disc), AllBdmtTitles = GetAllBdmtTitles(disc), DboxTitle = GetDboxTitle(disc), V_ISAN = GetVISAN(disc) }; var derived = new DiscMetadata.DerivedMetadata { VolumeLabel = GetVolumeLabel(raw), VolumeLabelSanitized = GetVolumeLabelSanitized(raw), ValidBdmtTitles = GetValidBdmtTitles(raw.AllBdmtTitles), DboxTitleSanitized = GetDboxTitleSanitized(raw), SearchQueries = new List<SearchQuery>() /* populated by DiscTransformer */ }; var metadata = new DiscMetadata { Raw = raw, Derived = derived }; disc.Metadata = metadata; }
private static void TransformPrimaryLanguage(Disc disc) { if (disc.PrimaryLanguage != null) return; disc.PrimaryLanguage = disc.Playlists.SelectMany(playlist => playlist.AudioTracks) .Select(track => track.Language) .GroupBy(language => language) .OrderByDescending(grouping => grouping.Count()) .Select(grouping => grouping.Key) .FirstOrDefault(); }
public void SetDisc(Disc disc) { var features = disc.Features; SetFeature(iconBDPlus, labelBDPlus, features.IsBDPlus); SetFeature(iconBDJava, labelBDJava, features.IsBDJava); SetFeature(icon3D, label3D, features.Is3D); SetFeature(iconDbox, labelDbox, features.IsDbox); SetFeature(iconDCopy, labelDCopy, features.IsDCopy); SetFeature(iconPSP, labelPSP, features.IsPSP); }
private static void TransformTitle(Disc disc) { var derived = disc.Metadata.Derived; var validBdmtTitles = derived.ValidBdmtTitles; if (validBdmtTitles.ContainsKey(disc.PrimaryLanguage)) { AddSearchableTitleIfNotEmpty(disc, validBdmtTitles[disc.PrimaryLanguage]); } AddSearchableTitleIfNotEmpty(disc, derived.DboxTitleSanitized); AddSearchableTitleIfNotEmpty(disc, derived.VolumeLabelSanitized); }
public static void Transform(Disc disc) { var fs = disc.FileSystem; var root = fs.Directories.Root; var features = new DiscFeatures { IsBDPlus = IsBDPlus(root), IsBDJava = IsBDJava(fs), Is3D = Is3D(fs), IsDbox = IsDbox(fs), IsDCopy = IsDCopy(fs), IsPSP = IsPSP(fs) }; disc.Features = features; }
public FormDiscInfo(Disc disc) { InitializeComponent(); var fs = disc.FileSystem; var metadata = disc.Metadata; labelQuickSummary.Text = string.Format("{0} {1}", metadata.Derived.VolumeLabel, fs.Directories.Root.FullName ); discInfoMetadataPanel.SetDisc(disc); discInfoFeaturesPanel.SetDisc(disc); this.EnableSelectAll(); }
public void SetDisc(Disc disc) { var fs = disc.FileSystem; var meta = disc.Metadata; var raw = meta.Raw; var der = meta.Derived; var inf = raw.DiscInf; string discInfVolumeLabel = null; string regionName = null; string regionDesc = null; if (inf != null) { discInfVolumeLabel = inf.VolumeLabel; regionName = inf.Region.GetLongName(); regionDesc = inf.Region.GetDescription(); } new ToolTip().SetToolTip(textBoxAnyDVDDiscInfSanitized, regionDesc); // textboxes InitTextAndIcon(iconHardwareVolumeLabel, textBoxHardwareVolumeLabel, raw.HardwareVolumeLabel); InitTextAndIcon(iconAnyDVDDiscInf, textBoxAnyDVDDiscInf, discInfVolumeLabel); InitTextAndIcon(iconDboxTitle, textBoxDboxTitle, raw.DboxTitle); InitTextAndIcon(iconVISAN, textBoxVISAN, GetIsanText(raw.V_ISAN)); InitTextAndIcon(iconAllBdmtTitles, textBoxAllBdmtTitles, GetBdmtTitles(raw.AllBdmtTitles)); InitText(textBoxVolumeLabelSanitized, der.VolumeLabelSanitized); InitText(textBoxAnyDVDDiscInfSanitized, regionName); InitText(textBoxDboxTitleSanitized, der.DboxTitleSanitized); InitText(textBoxIsan, GetIsanText(raw.ISAN)); InitText(textBoxValidBdmtTitles, GetBdmtTitles(der.ValidBdmtTitles)); // buttons InitButton(buttonVolumeLabelSanitized, fs.Directories.Root); InitButton(buttonAnyDVDDiscInfSanitized, fs.Files.AnyDVDDiscInf); InitButton(buttonDboxTitleSanitized, fs.Files.DBox); InitButton(buttonIsan, fs.Files.MCMF); InitButton(buttonValidBdmtTitles, fs.Directories.BDMT); }
private static IDictionary<Language, string> GetAllBdmtTitles(Disc disc) { var titles = new Dictionary<Language, string>(); foreach (var file in disc.FileSystem.Files.BDMT) { var filenameMatch = BdmtFileNameRegex.Match(file.Name); var iso639_2 = filenameMatch.Groups[1].Value; var language = Language.FromCode(iso639_2); var xml = string.Join("", File.ReadLines(file.FullName)); if (!BdmtXmlTitleRegex.IsMatch(xml)) continue; var xmlMatch = BdmtXmlTitleRegex.Match(xml); var title = xmlMatch.Groups[1].Value.Trim(); titles[language] = title; } return titles; }
private static void TransformLanguageList(Disc disc) { var playlists = disc.Playlists; var languages = disc.Languages; var primaryLanguage = disc.PrimaryLanguage; // Sort languages alphabetically var languagesWithDups = playlists .SelectMany(playlist => playlist.Tracks) .Select(track => track.Language) .Where(language => language != null && language != Language.Undetermined); languages.Clear(); languages.AddRange(new HashSet<Language>(languagesWithDups).OrderBy(language => language.Name)); if (primaryLanguage == null || primaryLanguage == Language.Undetermined) return; // Move primary language to the beginning of the list languages.Remove(primaryLanguage); languages.Insert(0, primaryLanguage); }
public static Disc Transform(BDInfo.BDROM bdrom) { var tsPlaylistFiles = PlaylistTransformer.Transform(bdrom.PlaylistFiles); var disc = new Disc { PrimaryLanguage = bdrom.DiscLanguage, Playlists = PlaylistTransformer.Transform(tsPlaylistFiles) }; DiscFileSystemTransformer.Transform(bdrom, disc); DiscFeaturesTransformer.Transform(disc); DiscMetadataTransformer.Transform(disc); // Data gathering TransformPrimaryLanguage(disc); TransformVideoLanguages(disc); TransformLanguageList(disc); TransformTitle(disc); return disc; }
private static string GetHardwareVolumeLabel(Disc disc) { var root = disc.FileSystem.Directories.Root; var parent = Directory.GetParent(root.FullName); if (parent == null) { // path is the root directory var drives = DriveInfo.GetDrives().ToArray(); var drive = drives.FirstOrDefault(info => info.Name == root.FullName); if (drive != null) { return drive.VolumeLabel; } } return root.Name; }
private static string GetDboxTitle(Disc disc) { var dbox = disc.FileSystem.Files.Dbox; if (dbox == null) return null; string xml; var encoding = FileUtils.DetectEncodingAuto(dbox.FullName, out xml); // Replace newlines with spaces xml = Regex.Replace(xml, @"[\n\r\f]+", " "); if (!DboxTitleRegex.IsMatch(xml)) return null; var match = DboxTitleRegex.Match(xml); var title = SanitizeTitle(match.Groups[1].Value); return title; }
internal static Job CreateMovieJob() { var metadata = new DiscMetadata { Derived = new DiscMetadata.DerivedMetadata { VolumeLabel = "EMPIRE_STRIKES_BACK" } }; var disc = new Disc { Metadata = metadata, Playlists = new List<Playlist> { new Playlist { Tracks = new List<Track> { new Track { IsVideo = true, Codec = Codec.AVC, Type = TrackType.MainFeature, VideoFormat = TSVideoFormat.VIDEOFORMAT_1080p, AspectRatio = TSAspectRatio.ASPECT_16_9, Index = 0, IndexOfType = 0, IsBestGuess = true, Keep = true, Language = Language.English }, new Track { IsAudio = true, Codec = Codec.DTSHDMA, Type = TrackType.MainFeature, ChannelCount = 6.1, Index = 1, IndexOfType = 0, IsBestGuess = true, Keep = true, Language = Language.English }, new Track { IsSubtitle = true, Codec = Codec.PGS, Type = TrackType.MainFeature, Index = 2, IndexOfType = 0, IsBestGuess = true, Keep = true, Language = Language.English }, } } } }; var job = new Job(disc) { ReleaseMediumType = ReleaseMediumType.Movie, SearchQuery = new SearchQuery { Title = "Star Wars: Episode V - The Empire Strikes Back", Year = 1980, Language = Language.English } }; job.Movies.Add(new Movie { IsSelected = true, Title = "Star Wars: Episode V - The Empire Strikes Back", ReleaseYear = 1980, Id = 1891, Url = "http://www.themoviedb.org/movie/1891-star-wars-episode-v-the-empire-strikes-back" }); return job; }
internal static Job CreateTVShowJob() { var metadata = new DiscMetadata { Derived = new DiscMetadata.DerivedMetadata { VolumeLabel = "SCRUBS_S1_D1" } }; var disc = new Disc { Metadata = metadata, Playlists = new List<Playlist> { new Playlist { Tracks = new List<Track> { new Track { IsVideo = true, Codec = Codec.AVC, Type = TrackType.MainFeature, VideoFormat = TSVideoFormat.VIDEOFORMAT_1080p, AspectRatio = TSAspectRatio.ASPECT_16_9, Index = 0, IndexOfType = 0, IsBestGuess = true, Keep = true, Language = Language.English }, new Track { IsAudio = true, Codec = Codec.DTSHDMA, Type = TrackType.MainFeature, ChannelCount = 5.1, Index = 1, IndexOfType = 0, IsBestGuess = true, Keep = true, Language = Language.English }, new Track { IsSubtitle = true, Codec = Codec.PGS, Type = TrackType.MainFeature, Index = 2, IndexOfType = 0, IsBestGuess = true, Keep = true, Language = Language.English }, } } } }; var job = new Job(disc) { ReleaseMediumType = ReleaseMediumType.TVShow, SearchQuery = new SearchQuery { Title = "Scrubs", Year = 2001, Language = Language.English } }; var tvShow = new TVShow { IsSelected = true, Title = "Scrubs", Id = 76156, Url = "http://thetvdb.com/?tab=series&id=76156&lid=7", SelectedEpisodeIndex = 0 }; tvShow.Episodes.AddRange(new[] { new TVShow.Episode { SeasonNumber = 1, EpisodeNumber = 1, Title = "My First Day", Id = 184602, ReleaseDate = DateTime.Parse("2001-10-02") } }); job.TVShows.Add(tvShow); return job; }
private static void DetectMainFeaturePlaylistTrackTypes(Disc disc) { foreach (var playlist in disc.Playlists.Where(playlist => playlist.IsMainFeature)) { // Additional video tracks are usually PiP commentary foreach (var videoTrack in playlist.VideoTracks.Skip(1)) { videoTrack.Type = TrackType.Commentary; } var audioLanguages = new HashSet<Language>(playlist.AudioTracks.Select(track => track.Language)).ToArray(); var subtitleLanguages = new HashSet<Language>(playlist.SubtitleTracks.Select(track => track.Language)).ToArray(); // Detect type of audio tracks (per-language) foreach (var audioLanguage in audioLanguages) { var lang = audioLanguage; var audioTracksWithLang = playlist.AudioTracks.Where(track => track.Language == lang).ToArray(); // Detect type of audio tracks for (var i = 0; i < audioTracksWithLang.Length; i++) { var audioTrack = audioTracksWithLang[i]; if (IsMainFeatureAudioTrack(audioTrack, i)) audioTrack.Type = TrackType.MainFeature; if (IsCommentaryAudioTrack(audioTrack, i)) audioTrack.Type = TrackType.Commentary; } } // Detect type of audio tracks (per-language) // Assume the first subtitle track of every language is the Main Feature, // and all other subtitle tracks of that language are Commentary foreach (var subtitleLanguage in subtitleLanguages) { var lang = subtitleLanguage; var subtitleTracksWithLang = playlist.SubtitleTracks.Where(track => track.Language == lang).ToArray(); // Detect type of subtitle tracks for (var i = 0; i < subtitleTracksWithLang.Length; i++) { var subtitleTrack = subtitleTracksWithLang[i]; subtitleTrack.Type = i == 0 ? TrackType.MainFeature : TrackType.Commentary; var codec = subtitleTrack.Codec; if (!codec.IsKnown || !codec.IsMuxable) { subtitleTrack.Type = TrackType.Misc; } } } } }
private static void DetectCommentaryPlaylistTrackTypes(Disc disc) { var tracks = disc.Playlists.Where(playlist => playlist.IsVideoCommentary).SelectMany(playlist => playlist.Tracks); foreach (var track in tracks) { track.Type = TrackType.Commentary; } }
private static void DetectPlaylistTypes(Disc disc) { var maxLength = GetMaxPlaylistLength(disc); foreach (var playlist in disc.Playlists) { if (playlist.IsMainFeaturePlaylist(maxLength)) playlist.Type = TrackType.MainFeature; if (playlist.IsSpecialFeaturePlaylist(maxLength)) playlist.Type = TrackType.SpecialFeature; } }
private void TransformPlaylistQuality(Disc disc) { // TODO: ONLY LOOK AT MAIN MOVIE PLAYLISTS var bestAudioPlaylist = disc.Playlists.OrderByDescending(p => p.MaxAudioChannels).FirstOrDefault(); if (bestAudioPlaylist == null) return; var bestVideoPlaylist = disc.Playlists.OrderByDescending(p => p.MaxAvailableVideoResolution).FirstOrDefault(); if (bestVideoPlaylist == null) return; var maxChannels = bestAudioPlaylist.MaxAudioChannels; var maxHeight = bestVideoPlaylist.MaxAvailableVideoResolution; var maxQualityPlaylists = disc.Playlists.Where(playlist => playlist.MaxAudioChannels == maxChannels && playlist.MaxAvailableVideoResolution == maxHeight); foreach (var playlist in maxQualityPlaylists) { playlist.IsMaxQuality = true; } }
private static VIsan GetVISAN(Disc disc) { var file = disc.FileSystem.Files.MCMF; if (file == null) return null; var xml = string.Join(" ", File.ReadAllLines(file.FullName)); if (!ISANContentIdRegex.IsMatch(xml)) return null; var match = ISANContentIdRegex.Match(xml); var contentId = match.Groups[1].Value; return VIsan.TryParse(contentId); }
private static void DetectSpecialFeaturePlaylistTrackTypes(Disc disc) { var tracks = disc.Playlists.Where(playlist => playlist.IsSpecialFeature).SelectMany(playlist => playlist.Tracks); foreach (var track in tracks) { track.Type = TrackType.SpecialFeature; } }
private static TimeSpan GetMaxPlaylistLength(Disc disc) { return disc.Playlists .Where(playlist => playlist.IsPossibleMainFeature && !playlist.IsBogus) .Select(playlist => playlist.Length) .OrderByDescending(length => length) .FirstOrDefault(); }
private static void SelectBestTracks(Disc disc) { foreach (var playlist in disc.Playlists) { // Video playlist.VideoTracks.First().IsBestGuess = true; playlist.VideoTracks.First().Keep = true; // Audio var mainFeatureAudioTracks = playlist.AudioTracks.Where(track => track.IsMainFeature).ToList(); var primaryLanguageAudioTracks = mainFeatureAudioTracks.Where(track => track.Language == disc.PrimaryLanguage).ToList(); var firstAudioTrack = playlist.AudioTracks.FirstOrDefault(); if (primaryLanguageAudioTracks.Any()) SelectTracks(primaryLanguageAudioTracks); else if (mainFeatureAudioTracks.Any()) SelectTrack(primaryLanguageAudioTracks.First()); else if (firstAudioTrack != null) SelectTrack(firstAudioTrack); // Subtitles var mainFeatureSubtitleTracks = playlist.SubtitleTracks.Where(track => track.IsMainFeature).ToList(); var primaryLanguageSubtitleTracks = mainFeatureSubtitleTracks.Where(track => track.Language == disc.PrimaryLanguage).ToList(); var firstSubtitleTrack = playlist.SubtitleTracks.FirstOrDefault(); if (primaryLanguageSubtitleTracks.Any()) SelectTracks(primaryLanguageSubtitleTracks); else if (mainFeatureSubtitleTracks.Any()) SelectTrack(mainFeatureSubtitleTracks.First()); else if (firstSubtitleTrack != null) SelectTrack(firstSubtitleTrack); } }
private void FindDuplicatePlaylists(Disc disc) { var bdamPlaylistMap = disc.Playlists.ToDictionary(playlist => playlist.FileName); var bdinfoDuplicateMap = disc.Playlists.ToMultiValueDictionary(GetPlaylistDupKey); var dups = (from key in bdinfoDuplicateMap.Keys where bdinfoDuplicateMap[key].Count > 1 select bdinfoDuplicateMap[key].OrderBy(playlist => playlist.Tracks.Count(track => track.IsHidden))) .SelectMany(sortedFiles => sortedFiles.Skip(1)); foreach (var playlist in dups) { playlist.IsDuplicate = true; bdamPlaylistMap[playlist.FileName].IsDuplicate = true; } }
private static AnyDVDDiscInf GetAnyDVDDiscInf(Disc disc) { var discInf = disc.FileSystem.Files.AnyDVDDiscInf; if (discInf == null) return null; var parser = new FileIniDataParser(); var data = parser.LoadFile(discInf.FullName); var discData = data["disc"]; var anyDVDDiscInf = new AnyDVDDiscInf { AnyDVDVersion = discData["version"], VolumeLabel = discData["label"], Region = RegionCodeParser.Parse(discData["region"]) }; return anyDVDDiscInf; }
private void FindDuplicatePlaylists(Disc disc) { var bdamPlaylistMap = disc.Playlists.ToDictionary(playlist => playlist.FileName); var bdinfoDuplicateMap = disc.Playlists.ToMultiValueDictionary(GetPlaylistDupKey); var dups = (from key in bdinfoDuplicateMap.Keys where bdinfoDuplicateMap[key].Count > 1 select bdinfoDuplicateMap[key].OrderBy(GetDupSortValue)) .SelectMany(SkipBestDup); foreach (var playlist in dups) { playlist.IsDuplicate = true; bdamPlaylistMap[playlist.FileName].IsDuplicate = true; } }
public Job(Disc disc) { Disc = disc; }
private void TransformPlaylistQuality(Disc disc) { // TODO: Fix or remove quality detection // Only consider feature-length playlists when searching for highest quality tracks var maxLength = GetMaxPlaylistLength(disc); var allPlaylists = disc.Playlists; var featureLengthPlaylists = allPlaylists.Where(playlist => playlist.IsFeatureLength(maxLength)).ToArray(); var bestAudioPlaylist = featureLengthPlaylists.OrderByDescending(p => p.MaxAudioChannels).FirstOrDefault(); if (bestAudioPlaylist == null) return; var bestVideoPlaylist = featureLengthPlaylists.OrderByDescending(p => p.MaxAvailableVideoResolution).FirstOrDefault(); if (bestVideoPlaylist == null) return; var maxChannels = bestAudioPlaylist.MaxAudioChannels; var maxHeight = bestVideoPlaylist.MaxAvailableVideoResolution; var maxQualityPlaylists = allPlaylists.Where(playlist => IsMaxQualityPlaylist(playlist, maxChannels, maxHeight)).ToArray(); foreach (var playlist in maxQualityPlaylists) { playlist.IsMaxQuality = true; } }