public override List <ChapterInfo> GetStreams(string location, int numtitle) { string path = Path.Combine(location, "VIDEO_TS"); if (!Directory.Exists(path)) { throw new FileNotFoundException("The VIDEO_TS folder was not found on the DVD."); } List <ChapterInfo> streams = new List <ChapterInfo>(); Ifo2Extractor ex = new Ifo2Extractor(); ex.StreamDetected += (sender, args) => OnStreamDetected(args.ProgramChain); ex.ChaptersLoaded += (sender, args) => OnChaptersLoaded(args.ProgramChain); string videoIFO = Path.Combine(path, "VIDEO_TS.IFO"); if (File.Exists(videoIFO)) { byte[] bytRead = new byte[4]; long VMG_PTT_STPT_Position = IfoUtil.ToFilePosition(IfoUtil.GetFileBlock(videoIFO, 0xC4, 4)); int titlePlayMaps = IfoUtil.ToInt16(IfoUtil.GetFileBlock(videoIFO, VMG_PTT_STPT_Position, 2)); //string longestIfo = GetLongestIFO(videoTSDir); for (int currentTitle = 1; currentTitle <= titlePlayMaps; ++currentTitle) { long titleInfoStart = 8 + ((currentTitle - 1) * 12); int titleSetNumber = IfoUtil.GetFileBlock(videoIFO, (VMG_PTT_STPT_Position + titleInfoStart) + 6L, 1)[0]; int titleSetTitleNumber = IfoUtil.GetFileBlock(videoIFO, (VMG_PTT_STPT_Position + titleInfoStart) + 7L, 1)[0]; string vtsIFO = Path.Combine(path, string.Format("VTS_{0:D2}_0.IFO", titleSetNumber)); if (!File.Exists(vtsIFO)) { Trace.WriteLine(string.Format("VTS IFO file missing: {0}", Path.GetFileName(vtsIFO))); continue; } ChapterInfo c1 = ex.GetStreams(vtsIFO, titleSetTitleNumber)[0]; c1.TitleID = currentTitle; streams.Add(c1); } } else { Trace.WriteLine("VIDEO_TS.IFO file is missing missing on the DVD."); //read all the ifo files foreach (string file in Directory.GetFiles(path, "VTS_*_0.IFO")) { ChapterInfo pgc = ex.GetStreams(file, 1)[0]; pgc.SourceName = Path.GetFileNameWithoutExtension(file); streams.Add(pgc); } } // streams = streams.OrderByDescending(p => p.Duration).ToList(); OnExtractionComplete(); return(streams); }
List <ChapterEntry> GetChapters(string ifoFile, int programChain, out TimeSpan duration, out double fps) { List <ChapterEntry> chapters = new List <ChapterEntry>(); duration = TimeSpan.Zero; fps = 0; TimeSpan oldTime = TimeSpan.Zero; long pcgITPosition = IfoUtil.GetPCGIP_Position(ifoFile); int programChainPrograms = -1; TimeSpan programTime = TimeSpan.Zero; if (programChain >= 0) { double FPS; uint chainOffset = IfoUtil.GetChainOffset(ifoFile, pcgITPosition, programChain); programTime = IfoUtil.ReadTimeSpan(ifoFile, pcgITPosition, chainOffset, out FPS) ?? TimeSpan.Zero; programChainPrograms = IfoUtil.GetNumberOfPrograms(ifoFile, pcgITPosition, chainOffset); } else { int programChains = IfoUtil.GetProgramChains(ifoFile, pcgITPosition); for (int curChain = 1; curChain <= programChains; curChain++) { double FPS; uint chainOffset = IfoUtil.GetChainOffset(ifoFile, pcgITPosition, curChain); TimeSpan?time = IfoUtil.ReadTimeSpan(ifoFile, pcgITPosition, chainOffset, out FPS); if (time == null) { break; } if (time.Value > programTime) { programChain = curChain; programChainPrograms = IfoUtil.GetNumberOfPrograms(ifoFile, pcgITPosition, chainOffset); programTime = time.Value; } } } if (programChain < 0) { return(null); } // chapters.Add(new ChapterEntry() { Name = "Chapter 1" }); uint longestChainOffset = IfoUtil.GetChainOffset(ifoFile, pcgITPosition, programChain); int programMapOffset = IfoUtil.ToInt16(IfoUtil.GetFileBlock(ifoFile, (pcgITPosition + longestChainOffset) + 230, 2)); int cellTableOffset = IfoUtil.ToInt16(IfoUtil.GetFileBlock(ifoFile, (pcgITPosition + longestChainOffset) + 0xE8, 2)); for (int currentProgram = 0; currentProgram < programChainPrograms; ++currentProgram) { int entryCell = IfoUtil.GetFileBlock(ifoFile, ((pcgITPosition + longestChainOffset) + programMapOffset) + currentProgram, 1)[0]; int exitCell = entryCell; if (currentProgram < (programChainPrograms - 1)) { exitCell = IfoUtil.GetFileBlock(ifoFile, ((pcgITPosition + longestChainOffset) + programMapOffset) + (currentProgram + 1), 1)[0] - 1; } TimeSpan totalTime = TimeSpan.Zero; for (int currentCell = entryCell; currentCell <= exitCell; currentCell++) { int cellStart = cellTableOffset + ((currentCell - 1) * 0x18); byte[] bytes = IfoUtil.GetFileBlock(ifoFile, (pcgITPosition + longestChainOffset) + cellStart, 4); int cellType = bytes[0] >> 6; if (cellType == 0x00 || cellType == 0x01) { bytes = IfoUtil.GetFileBlock(ifoFile, ((pcgITPosition + longestChainOffset) + cellStart) + 4, 4); TimeSpan time = IfoUtil.ReadTimeSpan(bytes, out fps) ?? TimeSpan.Zero; totalTime += time; } } //add a constant amount of time for each chapter? //totalTime += TimeSpan.FromMilliseconds(fps != 0 ? (double)1000 / fps / 8D : 0); duration += totalTime; if (currentProgram < programChainPrograms) { chapters.Add(new ChapterEntry() { Name = string.Format("Chapter {0}", currentProgram + 1), OffsetTime = oldTime, Time = totalTime, chId = currentProgram + 1 }); } oldTime = duration; } return(chapters); }