/// <summary> /// Creates a box by reading it from a file given its header, /// parent header, handler, and index in its parent. /// </summary> /// <param name="file"> /// A <see cref="TagLib.File" /> object containing the file /// to read from. /// </param> /// <param name="header"> /// A <see cref="BoxHeader" /> object containing the header /// of the box to create. /// </param> /// <param name="parent"> /// A <see cref="BoxHeader" /> object containing the header /// of the parent box. /// </param> /// <param name="handler"> /// A <see cref="IsoHandlerBox" /> object containing the /// handler that applies to the new box. /// </param> /// <param name="index"> /// A <see cref="int" /> value containing the index of the /// new box in its parent. /// </param> /// <returns> /// A newly created <see cref="Box" /> object. /// </returns> private static Box CreateBox(TagLib.File file, BoxHeader header, BoxHeader parent, IsoHandlerBox handler, int index) { // The first few children of an "stsd" are sample // entries. if (parent.BoxType == BoxType.Stsd && parent.Box is IsoSampleDescriptionBox box && index < box.EntryCount) { if (handler != null && handler.HandlerType == BoxType.Soun) { return(new IsoAudioSampleEntry(header, file, handler)); } if (handler != null && handler.HandlerType == BoxType.Vide) { return(new IsoVisualSampleEntry(header, file, handler)); } if (handler != null && handler.HandlerType == BoxType.Alis) { if (header.BoxType == BoxType.Text) { return(new TextBox(header, file, handler)); } // This could be anything, so just parse it return(new UnknownBox(header, file, handler)); } return(new IsoSampleEntry(header, file, handler)); } // Standard items... var type = header.BoxType; if (type == BoxType.Mvhd) { return(new IsoMovieHeaderBox(header, file, handler)); } if (type == BoxType.Stbl) { return(new IsoSampleTableBox(header, file, handler)); } if (type == BoxType.Stsd) { return(new IsoSampleDescriptionBox(header, file, handler)); } if (type == BoxType.Stco) { return(new IsoChunkOffsetBox(header, file, handler)); } if (type == BoxType.Co64) { return(new IsoChunkLargeOffsetBox(header, file, handler)); } if (type == BoxType.Hdlr) { return(new IsoHandlerBox(header, file, handler)); } if (type == BoxType.Udta) { return(new IsoUserDataBox(header, file, handler)); } if (type == BoxType.Meta) { return(new IsoMetaBox(header, file, handler)); } if (type == BoxType.Ilst) { return(new AppleItemListBox(header, file, handler)); } if (type == BoxType.Data) { return(new AppleDataBox(header, file, handler)); } if (type == BoxType.Esds) { return(new AppleElementaryStreamDescriptor( header, file, handler)); } if (type == BoxType.Free || type == BoxType.Skip) { return(new IsoFreeSpaceBox(header, file, handler)); } if (type == BoxType.Mean || type == BoxType.Name) { return(new AppleAdditionalInfoBox(header, file, handler)); } // If we still don't have a tag, and we're inside an // ItemListBox, load the box as an AnnotationBox // (Apple tag item). if (parent.BoxType == BoxType.Ilst) { return(new AppleAnnotationBox(header, file, handler)); } // Nothing good. Go generic. return(new UnknownBox(header, file, handler)); }
/// <summary> /// Creates a box by reading it from a file given its header /// and handler. /// </summary> /// <param name="file"> /// A <see cref="TagLib.File" /> object containing the file /// to read from. /// </param> /// <param name="header"> /// A <see cref="BoxHeader" /> object containing the header /// of the box to create. /// </param> /// <returns> /// A newly created <see cref="Box" /> object. /// </returns> public static Box CreateBox(TagLib.File file, BoxHeader header) { return(CreateBox(file, header, null)); }
/// <summary> /// Creates a box by reading it from a file given its header /// and handler. /// </summary> /// <param name="file"> /// A <see cref="TagLib.File" /> object containing the file /// to read from. /// </param> /// <param name="header"> /// A <see cref="BoxHeader" /> object containing the header /// of the box to create. /// </param> /// <param name="handler"> /// A <see cref="IsoHandlerBox" /> object containing the /// handler that applies to the new box. /// </param> /// <returns> /// A newly created <see cref="Box" /> object. /// </returns> public static Box CreateBox(TagLib.File file, BoxHeader header, IsoHandlerBox handler) { return(CreateBox(file, header, BoxHeader.Empty, handler, -1)); }
/// <summary> /// Constructs and initializes a new instance of /// <see /// cref="Box" /> /// with a specified header. /// </summary> /// <param name="header"> /// A <see cref="BoxHeader" /> object describing the new /// instance. /// </param> protected Box(BoxHeader header) : this(header, null) { }
/// <summary> /// Constructs and initializes a new instance of /// <see /// cref="Box" /> /// with a specified header and handler. /// </summary> /// <param name="header"> /// A <see cref="BoxHeader" /> object describing the new /// instance. /// </param> /// <param name="handler"> /// A <see cref="IsoHandlerBox" /> object containing the /// handler that applies to the new instance, or /// <see /// langword="null" /> /// if no handler applies. /// </param> protected Box(BoxHeader header, IsoHandlerBox handler) { this.header = header; data_position = header.Position + header.HeaderSize; Handler = handler; }
/// <summary> /// Parses boxes for a specified range, looking for tags and /// properties. /// </summary> /// <param name="start"> /// A <see cref="long" /> value specifying the seek position /// at which to start reading. /// </param> /// <param name="end"> /// A <see cref="long" /> value specifying the seek position /// at which to stop reading. /// </param> /// <param name="handler"> /// A <see cref="IsoHandlerBox" /> object that applied to the /// range being searched. /// </param> /// <param name="parents"> /// A <see cref="T:List" /> of <see cref="BoxHeader" /> parents. /// </param> private void ParseTagAndProperties(long start, long end, IsoHandlerBox handler, List <BoxHeader> parents) { BoxHeader header; for (var position = start; position < end; position += header.TotalBoxSize) { header = new BoxHeader(file, position); var type = header.BoxType; if (type == BoxType.Moov) { ParseTagAndProperties(header.HeaderSize + position, header.TotalBoxSize + position, handler, AddParent(parents, header)); } else if (type == BoxType.Mdia || type == BoxType.Minf || type == BoxType.Stbl || type == BoxType.Trak) { ParseTagAndProperties( header.HeaderSize + position, header.TotalBoxSize + position, handler, AddParent(parents, header)); } else if (type == BoxType.Stsd) { stsd_boxes.Add(BoxFactory.CreateBox( file, header, handler)); } else if (type == BoxType.Hdlr) { handler = BoxFactory.CreateBox(file, header, handler) as IsoHandlerBox; } else if (MovieHeaderBox == null && type == BoxType.Mvhd) { MovieHeaderBox = BoxFactory.CreateBox(file, header, handler) as IsoMovieHeaderBox; } else if (type == BoxType.Udta) { var udtaBox = BoxFactory.CreateBox(file, header, handler) as IsoUserDataBox; // Since we can have multiple udta boxes, save the parent for each one var new_parents = AddParent( parents, header); udtaBox.ParentTree = new_parents.ToArray(); udta_boxes.Add(udtaBox); } else if (type == BoxType.Mdat) { mdat_start = position; MdatEndPosition = position + header.TotalBoxSize; } if (header.TotalBoxSize == 0) { break; } } }