예제 #1
0
        // Save the file.
        public void Save()
        {
            if (listBox == null)
            {
                throw new TagLibException(TagLibError.Mpeg4TagSaveFailed);
            }
            //InvalidOperationException("Could not save AppleTag: listBox is not defined");

            // Try to get into write mode.
            try
            {
                file.Mode = FileAccessMode.Write;
            }
            catch (TagLibException)
            {
                return;
            }

            // Make a file box.
            Mpeg4FileBox fileBox = new Mpeg4FileBox(file);

            // Get the MovieBox.
            Mpeg4IsoMovieBox moovBox = (Mpeg4IsoMovieBox)fileBox.FindChildDeep("moov");

            // If we have a movie box...
            if (moovBox != null)
            {
                // Set up how much, where, and what to replace, and who to tell
                // about it.
                ulong      originalSize = 0;
                long       position     = -1;
                ByteVector data         = null;
                Mpeg4Box   parent       = null;

                // Get the old ItemList (the one we're replacing.
                Mpeg4AppleItemListBox old_ilst_box = (Mpeg4AppleItemListBox)moovBox.FindChildDeep("ilst");

                // If it exists.
                if (old_ilst_box != null)
                {
                    // We stick ourself in the meta box and slate to overwrite it.
                    parent       = old_ilst_box.Parent;
                    originalSize = parent.BoxSize;
                    position     = parent.NextBoxPosition - (long)originalSize;

                    parent.ReplaceChild(old_ilst_box, listBox);
                    data = parent.Render();

                    parent = parent.Parent;
                }
                else
                {
                    // There is not old ItemList. See if we can get a MetaBox.
                    Mpeg4IsoMetaBox metaBox = (Mpeg4IsoMetaBox)moovBox.FindChildDeep("meta");

                    //If we can...
                    if (metaBox != null)
                    {
                        // Stick the child in here and slate to overwrite...
                        metaBox.AddChild(listBox);

                        originalSize = metaBox.BoxSize;
                        position     = metaBox.NextBoxPosition - (long)originalSize;
                        data         = metaBox.Render();
                        parent       = metaBox.Parent;
                    }
                    else
                    {
                        // There'field no MetaBox. Create one and add the ItemList.
                        metaBox = new Mpeg4IsoMetaBox("hdlr", null);
                        metaBox.AddChild(listBox);

                        // See if we can get a UserDataBox.
                        Mpeg4IsoUserDataBox udtaBox = (Mpeg4IsoUserDataBox)moovBox.FindChildDeep("udta");

                        // If we can...
                        if (udtaBox != null)
                        {
                            // We'll stick the MetaBox at the end and overwrite it.
                            originalSize = 0;
                            position     = udtaBox.NextBoxPosition;
                            data         = metaBox.Render();
                            parent       = udtaBox;
                        }
                        else
                        {
                            // If not even the UserDataBox exists, create it and add
                            // our MetaBox.
                            udtaBox = new Mpeg4IsoUserDataBox();
                            udtaBox.AddChild(metaBox);

                            // Since UserDataBox is a child of MovieBox, we'll just
                            // insert it at the end.
                            originalSize = 0;
                            position     = moovBox.NextBoxPosition;
                            data         = udtaBox.Render();
                            parent       = moovBox;
                        }
                    }
                }

                // If we have data and somewhere to put it..
                if (data != null && position >= 0)
                {
                    // Figure out the size difference.
                    long sizeDifference = (long)data.Count - (long)originalSize;

                    // Insert the new data.
                    file.Insert(data, position, (long)(originalSize));

                    // If there is a size difference, resize all parent headers.
                    if (sizeDifference != 0)
                    {
                        while (parent != null)
                        {
                            parent.OverwriteHeader(sizeDifference);
                            parent = parent.Parent;
                        }

                        // ALSO, VERY IMPORTANTLY, YOU MUST UPDATE EVERY 'stco'.

                        foreach (Mpeg4Box box in moovBox.Children)
                        {
                            if (box.BoxType == "trak")
                            {
                                Mpeg4IsoChunkLargeOffsetBox co64Box = (Mpeg4IsoChunkLargeOffsetBox)box.FindChildDeep("co64");
                                if (co64Box != null)
                                {
                                    co64Box.UpdateOffset(sizeDifference);
                                }

                                Mpeg4IsoChunkOffsetBox stcoBox = (Mpeg4IsoChunkOffsetBox)box.FindChildDeep("stco");
                                if (stcoBox != null)
                                {
                                    stcoBox.UpdateOffset((int)sizeDifference);
                                }
                            }
                        }
                    }

                    // Be nice and close the stream.
                    file.Mode = FileAccessMode.Closed;
                    return;
                }
            }
            else
            {
                throw new TagLibException(TagLibError.Mpeg4StreamDoesNotHaveMoovTag);
            }
            //new ApplicationException("stream does not have MOOV tag");

            // We're at the end. Close the stream and admit defeat.
            file.Mode = FileAccessMode.Closed;
            throw new TagLibException(TagLibError.Mpeg4CouldNotSaveAppleTag);
            //ApplicationException("Could not complete AppleTag save");
        }
예제 #2
0
        // Read the file.
        private void Read(ReadStyle propertiesStyle)
        {
            // Create a dummie outer box, as perscribed by the specs.
            Mpeg4FileBox file_box = new Mpeg4FileBox(this);

            // Find the movie box and item text. If the movie box doen'type exist, an
            // exception will be thrown on the next call, but if there is no movie
            // box, the file can'type possibly be valid.
            Mpeg4IsoMovieBox      moov_box = (Mpeg4IsoMovieBox)file_box.FindChildDeep("moov");
            Mpeg4AppleItemListBox ilst_box = (Mpeg4AppleItemListBox)moov_box.FindChildDeep("ilst");

            // If we have a ItemListBox, deparent it.
            if (ilst_box != null)
            {
                ilst_box.RemoveFromParent();
            }

            // Create the tag.
            tag = new Mpeg4AppleTag(ilst_box, this);

            // If we're not reading properties, we're done.
            if (propertiesStyle == ReadStyle.None)
            {
                return;
            }

            // Get the movie header box.
            Mpeg4IsoMovieHeaderBox   mvhd_box     = (Mpeg4IsoMovieHeaderBox)moov_box.FindChildDeep("mvhd");
            Mpeg4IsoAudioSampleEntry sample_entry = null;

            // Find a TrackBox with a sound Handler.
            foreach (Mpeg4Box box in moov_box.Children)
            {
                if (box.BoxType == "trak")
                {
                    // If the handler isn'type sound, it could be metadata or video or
                    // any number of other things.
                    Mpeg4IsoHandlerBox hdlr_box = (Mpeg4IsoHandlerBox)box.FindChildDeep("hdlr");
                    if (hdlr_box == null || hdlr_box.HandlerType != "soun")
                    {
                        continue;
                    }

                    // This track SHOULD contain at least one sample entry.
                    sample_entry = (Mpeg4IsoAudioSampleEntry)box.FindChildDeep(typeof(Mpeg4IsoAudioSampleEntry));
                    break;
                }
            }

            // If we have a MovieHeaderBox, deparent it.
            if (mvhd_box != null)
            {
                mvhd_box.RemoveFromParent();
            }

            // If we have a SampleEntry, deparent it.
            if (sample_entry != null)
            {
                sample_entry.RemoveFromParent();
            }

            // Read the properties.
            properties = new Mpeg4Properties(mvhd_box, sample_entry, propertiesStyle);
        }