static void Main(string[] args)
        {
            const int indent = 4;

            long totalSize         = 0;
            int  totalBoxes        = 0;
            long mediaData         = 0;
            long totalFreeBoxSpace = 0;

            using (FileStream fs = new FileStream(args[0], FileMode.Open, FileAccess.Read))
            {
                using (Mpeg4TagBoxAwareReader reader = new Mpeg4TagBoxAwareReader(fs))
                {
                    while (reader.Read())
                    {
                        Console.WriteLine("Box {1} @ {2} of size: {3}, ends @ {4} {5}".PadLeft(reader.Depth * indent),
                                          reader.GetTypeAsString(),
                                          reader.BoxPosition,
                                          reader.CalculatedSize + (reader.Size == 0 ? " (0*)" : string.Empty),
                                          reader.BoxPosition + reader.CalculatedSize,
                                          (reader.IsRecognizedType && reader.IsRecognizedVersion.GetValueOrDefault(true)) ? string.Empty : "~");
                        if (reader.Depth == 0)
                        {
                            totalSize += reader.CalculatedSize;
                        }
                        if (reader.TypeString == "mdat")
                        {
                            mediaData = reader.CalculatedSize;
                        }
                        if (reader.TypeString == "free" || reader.TypeString == "skip")
                        {
                            totalFreeBoxSpace += reader.CalculatedSize;
                        }
                        totalBoxes++;
                    }
                    Console.WriteLine("                        (*)denotes length of atom goes to End-of-File");
                    Console.WriteLine();
                    Console.WriteLine(" ~ denotes an unknown box");
                    Console.WriteLine("------------------------------------------------------");
                    Console.WriteLine("Total size: {0} bytes; {1} atoms total.", totalSize, totalBoxes);
                    Console.WriteLine("Media data: {0} bytes; {1} bytes all other boxes ({2} box overhead).", mediaData, totalSize - mediaData, ((totalSize - mediaData) / (double)totalSize).ToString("0.000%"));
                    Console.WriteLine("Total free box space: {0} bytes; {1} waste. Padding avaliable: {2} bytes.", totalFreeBoxSpace, (totalFreeBoxSpace / (double)totalSize).ToString("0.000%"), "?");
                    Console.WriteLine("------------------------------------------------------");
                    Console.ReadLine();
                }
            }
        }
示例#2
0
        static void Main(string[] args)
        {
            string[] moovMeta         = new string[] { "moov", "udta", "meta" };
            string[] appleTagPath     = new string[] { "moov", "udta", "meta", "ilst" };
            bool     foundUserDataBox = false;
            uint?    handlerType      = null;
            Tags     tags             = new Tags();
            Tags     currentTags      = new Tags();

            const string s1 = @"D:\Users\Jonathan\Videos\test.m4v";
            const string s3 = @"D:\Users\Jonathan\Documents\Expression\Expression Encoder\Output\JONATHAN-PC 10-12-2010 4.31.43 AM\d.mp4";
            const string s2 = @"D:\Users\Jonathan\Documents\Visual Studio 2010\Projects\IsoBaseMediaFormatParser\trailer.m4v";

            using (FileStream fs = new FileStream(s3, FileMode.Open, FileAccess.Read))
            {
                using (FileStream output = new FileStream(@"test.m4v", FileMode.Create, FileAccess.Write))
                {
                    Stack <KeyValuePair <uint, bool> > boxes = new Stack <KeyValuePair <uint, bool> >();

                    IsoBaseMediaFileFormatReader reader = new Mpeg4TagBoxAwareReader(fs);
                    IsoBaseMediaFormatWriter     writer = new IsoBaseMediaFormatWriter(output);

                    bool foundMetaPath          = false;
                    bool endOnMetaPath          = false;
                    int  previousMetaPathLength = 0;

                    while (reader.Read())
                    {
                        while (boxes.Count > reader.Depth)
                        {
                            if (boxes.Peek().Value)
                            {
                                writer.WriteEndBox();
                            }
                            boxes.Pop();
                        }

                        if (reader.Depth == boxes.Count)
                        {
                            boxes.Push(new KeyValuePair <uint, bool>(reader.Type, false));
                        }

                        var boxTypes = boxes.Reverse().Select(b => Conversions.GetTypeAsString(b.Key)).ToArray();

                        int onMetaPathLength = OnPath(moovMeta, boxTypes);

                        foundMetaPath    = foundMetaPath || onMetaPathLength > 0;
                        endOnMetaPath    = foundMetaPath && onMetaPathLength < previousMetaPathLength;
                        foundUserDataBox = foundUserDataBox || onMetaPathLength == 2;

                        if (endOnMetaPath)
                        {
                            if ((handlerType.HasValue && Conversions.GetTypeAsString(handlerType.Value) == "mdir"))
                            {
                                foreach (string tag in currentTags.tags.Keys)
                                {
                                    if (!tags.tags.ContainsKey(tag))
                                    {
                                        tags.tags.Add(tag, currentTags.tags[tag]);
                                    }
                                }
                            }

                            if (!foundUserDataBox)
                            {
                                writer.WriteStartBox("udta");
                            }

                            WriteMeta(writer, tags);

                            if (!foundUserDataBox)
                            {
                                writer.WriteEndBox();
                            }
                        }

                        if (reader.GetTypeAsString() == "Xtra")
                        {
                            using (MemoryStream ms = new MemoryStream())
                            {
                                byte[] buffer = new byte[4096];
                                int    byteCount;
                                while ((byteCount = reader.ReadContent(buffer, 0, buffer.Length)) != 0)
                                {
                                    ms.Write(buffer, 0, byteCount);
                                }

                                ms.Position = 0;
                                while (ms.Position < ms.Length)
                                {
                                    var obj = Mpeg4Tagging.WindowsMedia.ContentDescriptor.Parse(ms);
                                    Console.WriteLine("Name: " + obj.Name);
                                    Console.WriteLine("Data: " + obj.GetValueAsObject().ToString() + ":");
                                }
                            }
                        }

                        if (OnPath(moovMeta, boxTypes) == 3 && reader.GetTypeAsString() == "hdlr")
                        {
                            reader.ReadContentAsUnsignedInt32();
                            handlerType = reader.ReadContentAsUnsignedInt32();
                            reader.ReadContent(new byte[12], 0, 12);

                            byte[] buffer    = new byte[reader.Size];
                            int    bytesRead = reader.ReadContent(buffer, 0, buffer.Length);

                            Console.WriteLine("Handler");
                            Console.WriteLine("    Type: " + Conversions.GetTypeAsString(handlerType.Value));
                            Console.WriteLine("    Name: " + Encoding.UTF8.GetString(buffer, 0, bytesRead));
                        }

                        if (OnPath(appleTagPath, boxTypes) >= appleTagPath.Length && reader.GetTypeAsString() == "data")
                        {
                            byte[] flags = new byte[4];
                            reader.Flags.CopyTo(flags, 1);

                            flags = BitConverter.IsLittleEndian ? flags.Reverse().ToArray() : flags;

                            uint flagsValue = BitConverter.ToUInt32(flags, 0);

                            object data = ReadData(reader);

                            /* if (data is byte[])
                             *  Console.WriteLine(BitConverter.ToString(data as byte[]));
                             * else
                             *  Console.WriteLine(data); */

                            currentTags.SetData(Conversions.GetTypeAsString(reader.Container.Value), data);
                        }
                        else if (onMetaPathLength < moovMeta.Length)
                        {
                            Console.WriteLine(string.Join("->", boxTypes));

                            if (reader.IsRecognizedType && reader.IsFullBox)
                            {
                                writer.WriteStartFullBox(reader.Type, reader.Version.Value, reader.Flags);
                            }
                            else
                            {
                                writer.WriteStartBox(reader.Type, reader.UserType);
                            }
                            if (!reader.IsContainer)
                            {
                                int    bytesRead;
                                byte[] buffer = new byte[4096];
                                while ((bytesRead = reader.ReadContent(buffer, 0, buffer.Length)) > 0)
                                {
                                    writer.WriteContent(buffer, 0, bytesRead);
                                }
                            }

                            boxes.Push(new KeyValuePair <uint, bool>(boxes.Pop().Key, true));
                        }

                        previousMetaPathLength = onMetaPathLength;
                    }
                }
            }

            Console.ReadLine();
        }