using System.IO; using Aaru.CommonTypes.Interfaces; using Aaru.CommonTypes.Metadata; using Aaru.DiscImages; using Aaru.Filters; namespace RedBookPlayer.Common.Discs { public static class OpticalDiscFactory { /// /// Generate an OpticalDisc from an input path /// /// Path to load the image from /// Generate a TOC if the disc is missing one [CompactDisc only] /// Load hidden tracks for playback [CompactDisc only] /// Load data tracks for playback [CompactDisc only] /// True if the image should be playable immediately, false otherwise /// Instantiated OpticalDisc, if possible public static OpticalDisc GenerateFromPath(string path, bool generateMissingToc, bool loadHiddenTracks, bool loadDataTracks, bool autoPlay) { try { // Validate the image exists if(string.IsNullOrWhiteSpace(path) || !File.Exists(path)) return null; // Load the disc image to memory // TODO: Assumes Aaruformat right now for all var image = new AaruFormat(); var filter = new ZZZNoFilter(); filter.Open(path); image.Open(filter); // Generate and instantiate the disc return GenerateFromImage(image, generateMissingToc, loadHiddenTracks, loadDataTracks, autoPlay); } catch { // All errors mean an invalid image in some way return null; } } /// /// Generate an OpticalDisc from an input IOpticalMediaImage /// /// IOpticalMediaImage to create from /// Generate a TOC if the disc is missing one [CompactDisc only] /// Load hidden tracks for playback [CompactDisc only] /// Load data tracks for playback [CompactDisc only] /// True if the image should be playable immediately, false otherwise /// Instantiated OpticalDisc, if possible public static OpticalDisc GenerateFromImage(IOpticalMediaImage image, bool generateMissingToc, bool loadHiddenTracks, bool loadDataTracks, bool autoPlay) { // If the image is not usable, we don't do anything if(!IsUsableImage(image)) return null; // Create the output object OpticalDisc opticalDisc; // Create the proper disc type switch(GetMediaType(image)) { case "Compact Disc": case "GD": opticalDisc = new CompactDisc(generateMissingToc, loadHiddenTracks, loadDataTracks); break; default: opticalDisc = null; break; } // Null image means we don't do anything if(opticalDisc == null) return opticalDisc; // Instantiate the disc and return opticalDisc.Init(image, autoPlay); return opticalDisc; } /// /// Gets the human-readable media type from an image /// /// Media image to check /// Type from the image, empty string on error /// TODO: Can we be more granular with sub types? private static string GetMediaType(IOpticalMediaImage image) { // Null image means we don't do anything if(image == null) return string.Empty; (string type, string _) = MediaType.MediaTypeToString(image.Info.MediaType); return type; } /// /// Indicates if the image is considered "usable" or not /// /// Aaruformat image file /// True if the image is playble, false otherwise private static bool IsUsableImage(IOpticalMediaImage image) { // Invalid images can't be used if(image == null) return false; // Determine based on media type return GetMediaType(image) switch { "Compact Disc" => true, "GD" => true, // Requires TOC generation _ => false, }; } } }