/// <summary> /// Reads the chapter information from the specified file. /// </summary> /// <param name="fileHandle">The handle to the file from which to read the chapter information.</param> /// <returns>A new instance of a <see cref="ChapterList"/> object containing the information /// about the chapters for the file.</returns> internal static ChapterList ReadFromFile(IntPtr fileHandle) { ChapterList list = new ChapterList(); IntPtr chapterListPointer = IntPtr.Zero; int chapterCount = 0; NativeMethods.MP4ChapterType chapterType = NativeMethods.MP4GetChapters(fileHandle, ref chapterListPointer, ref chapterCount, NativeMethods.MP4ChapterType.Qt); if (chapterType != NativeMethods.MP4ChapterType.None && chapterCount != 0) { IntPtr currentChapterPointer = chapterListPointer; for (int i = 0; i < chapterCount; i++) { NativeMethods.MP4Chapter currentChapter = currentChapterPointer.ReadStructure <NativeMethods.MP4Chapter>(); TimeSpan duration = TimeSpan.FromMilliseconds(currentChapter.duration); string title = Encoding.UTF8.GetString(currentChapter.title); if ((currentChapter.title[0] == 0xFE && currentChapter.title[1] == 0xFF) || (currentChapter.title[0] == 0xFF && currentChapter.title[1] == 0xFE)) { title = Encoding.Unicode.GetString(currentChapter.title); } title = title.Substring(0, title.IndexOf('\0')); list.AddInternal(new Chapter() { Duration = duration, Title = title }); currentChapterPointer = IntPtr.Add(currentChapterPointer, Marshal.SizeOf(currentChapter)); } } else { int timeScale = NativeMethods.MP4GetTimeScale(fileHandle); long duration = NativeMethods.MP4GetDuration(fileHandle); list.AddInternal(new Chapter() { Duration = TimeSpan.FromSeconds(duration / timeScale), Title = "Chapter 1" }); } if (chapterListPointer != IntPtr.Zero) { NativeMethods.MP4Free(chapterListPointer); } return(list); }
/// <summary> /// Loads the metadata for this file. /// </summary> public void Load() { IntPtr fileHandle = NativeMethods.MP4Read(this.fileName); if (fileHandle != IntPtr.Zero) { try { this.metadataTags = MetadataTags.ReadFromFile(fileHandle); this.chapters = ChapterList.ReadFromFile(fileHandle); } finally { NativeMethods.MP4Close(fileHandle); } } }