public static async Task <SampleDescriptionBox> CreateAsync(IBinaryStream stream, Box box) { var stsdBox = new SampleDescriptionBox(); stream.Position = box.Offset + 8; stsdBox.Version = await stream.ReadByteAsync().ConfigureAwait(false); stsdBox.Flags = await stream.ReadInt32Async(3, ByteOrder.BigEndian).ConfigureAwait(false); var entriesAmount = await stream.ReadInt32Async(ByteOrder.BigEndian).ConfigureAwait(false); for (var i = 0; i < entriesAmount; i++) { var sampleDescriptionSize = await stream.ReadUInt32Async(ByteOrder.BigEndian).ConfigureAwait(false); var dataFormat = await stream.ReadStringAsync(4).ConfigureAwait(false); stream.Position += 6; var dataReferenceIndex = await stream.ReadUInt16Async(ByteOrder.BigEndian).ConfigureAwait(false); stsdBox.Table.Add(new TableEntry(sampleDescriptionSize, dataFormat, dataReferenceIndex)); /*var version = await stream.ReadUInt16Async(ByteOrder.BigEndian).ConfigureAwait(false); * var revision = await stream.ReadUInt16Async(ByteOrder.BigEndian).ConfigureAwait(false); * var vendor = await stream.ReadUInt32Async(ByteOrder.BigEndian).ConfigureAwait(false); * var channels = await stream.ReadUInt16Async(ByteOrder.BigEndian).ConfigureAwait(false); * var sampleSize = await stream.ReadUInt16Async(ByteOrder.BigEndian).ConfigureAwait(false); * var compressionId = await stream.ReadUInt16Async(ByteOrder.BigEndian).ConfigureAwait(false); * var packetSize = await stream.ReadUInt16Async(ByteOrder.BigEndian).ConfigureAwait(false); * var sampleRate = await stream.ReadUInt16Async(ByteOrder.BigEndian).ConfigureAwait(false);*/ } return(stsdBox); }
internal static async Task <Box> ReadBoxAsync(IBinaryStream stream, UInt32 maxPosition) { var boxes = new List <Box>(); var offset = stream.Position; var length = await stream.ReadUInt32Async(ByteOrder.BigEndian).ConfigureAwait(false); if ((length < 8) || (stream.Position + length - 4 > maxPosition)) { return(null); } var name = await stream.ReadStringAsync(4).ConfigureAwait(false); if (name == "meta") { var version = await stream.ReadByteAsync().ConfigureAwait(false); var flags = await stream.ReadInt32Async(3, ByteOrder.BigEndian).ConfigureAwait(false); } var thisBoxMaxPosition = offset + length; while (stream.Position < thisBoxMaxPosition) { var box = await ReadBoxAsync(stream, thisBoxMaxPosition).ConfigureAwait(false); if (box == null) { boxes.Clear(); stream.Position = thisBoxMaxPosition; break; } boxes.Add(box); } return(new Box(offset, length, name, boxes)); }
public static async Task <ParseResult <Mpeg4File> > ParseAsync(IBinaryStream stream, ParseOptions options) { try { stream.Position = 4; if (await stream.ReadStringAsync(4) != "ftyp") { return(ParseResult <Mpeg4File> .CreateUnknownFormat()); } var file = new Mpeg4File(); stream.Position = 0; var streamLength = await stream.GetLengthAsync().ConfigureAwait(false); while (stream.Position < streamLength) { file.Boxes.Add(await Mpeg4File.ReadBoxAsync(stream, await stream.GetLengthAsync().ConfigureAwait(false))); } if (options == ParseOptions.Metadata) { var mediaData = file.Contains("mdat") ? file["mdat"] : null; var metadataItems = file.Contains("moov.udta.meta.ilst") ? await MetadataItemsBox.CreateAsync(stream, file["moov.udta.meta.ilst"]).ConfigureAwait(false) : null; var mediaHeader = file.Contains("moov.trak.mdia.mdhd") ? await MediaHeaderBox.CreateAsync(stream, file["moov.trak.mdia.mdhd"]).ConfigureAwait(false) : null; file.Metadata = new Mpeg4Metadata(metadataItems?.Cover, mediaHeader?.Duration, mediaHeader?.TimeScale, mediaData?.Length); } return(ParseResult <Mpeg4File> .Create(file)); } catch (Exception exception) { return(ParseResult <Mpeg4File> .Create(exception)); } }
public static async Task <Id3v2> ParseAsync(IBinaryStream stream) { stream.Position += 3; var id3v2 = new Id3v2(); var majorVersion = await stream.ReadByteAsync().ConfigureAwait(false); var revision = await stream.ReadByteAsync().ConfigureAwait(false); var flags = await stream.ReadByteAsync().ConfigureAwait(false); var size = Id3v2.DecodeSize(await stream.ReadUInt32Async(ByteOrder.BigEndian).ConfigureAwait(false)); var endingPosition = stream.Position + size; while (stream.Position < endingPosition) { var frameId = await stream.ReadStringAsync(4).ConfigureAwait(false); if (!Id3v2.IsValidAlphaNumeric(frameId)) { stream.Position = endingPosition; break; } var frameSize = 0U; switch (majorVersion) { case 4: frameSize = Id3v2.DecodeSize(await stream.ReadUInt32Async(ByteOrder.BigEndian).ConfigureAwait(false)); break; case 3: frameSize = await stream.ReadUInt32Async(ByteOrder.BigEndian).ConfigureAwait(false); break; default: throw new NotSupportedException(); } var frameFlags = await stream.ReadUInt16Async(ByteOrder.LittleEndian).ConfigureAwait(false); switch (frameId) { case "TIT2": id3v2.Title = Id3v2.DecodeString(await stream.ReadAsync(frameSize).ConfigureAwait(false)); break; case "TALB": id3v2.Album = Id3v2.DecodeString(await stream.ReadAsync(frameSize).ConfigureAwait(false)); break; case "TOAL": break; case "TPE1": id3v2.Artist = Id3v2.DecodeString(await stream.ReadAsync(frameSize).ConfigureAwait(false)); break; case "TPE2": id3v2.AlbumArtist = Id3v2.DecodeString(await stream.ReadAsync(frameSize).ConfigureAwait(false)); break; case "TRCK": var track = Id3v2.DecodeString(await stream.ReadAsync(frameSize).ConfigureAwait(false)); if (track != null) { id3v2.Track = ParseTrack(track); } break; case "TYER": var year = Id3v2.DecodeString(await stream.ReadAsync(frameSize).ConfigureAwait(false)); if (year != null) { id3v2.Year = ParseYear(year); } break; case "APIC": var readBytes = 0U; var encoding = (FrameEncoding)await stream.ReadByteAsync().ConfigureAwait(false); readBytes++; while (await stream.ReadByteAsync().ConfigureAwait(false) != 0) // MIME type <text string> $00 { readBytes++; } readBytes++; var pictureType = await stream.ReadByteAsync().ConfigureAwait(false); readBytes++; while (await stream.ReadByteAsync().ConfigureAwait(false) != 0) // <text string according to encoding> $00 (00) { readBytes++; } id3v2.Cover = new DataLocation(stream.Position, frameSize - readBytes - 1); stream.Position += frameSize - readBytes - 1; break; case "TCON": case "COMM": default: stream.Position += frameSize; break; } } return(id3v2); }