Exemplo n.º 1
0
        private static object GetBoxAsObject(Stream stream, int size, MP4DataType type)
        {
            byte[] buffer = new byte[size];
            if (stream.Read(buffer, 0, buffer.Length) != buffer.Length)
            {
                throw new MetaParseException("Unable to read full MP4 box content");
            }

            switch (type)
            {
            case MP4DataType.UInt8_a:
            case MP4DataType.UInt8_b:
                if (buffer.Length != 1)
                {
                    throw new MetaParseException($"Box content type {type} require data to be a single byte. number of bytes: {buffer.Length}.");
                }
                return((int)buffer[0]);

            case MP4DataType.Text:
                if (buffer.Length == 0)
                {
                    return(String.Empty);
                }
                byte[] text = buffer.TakeWhile(c => c != '\0').ToArray();
                return(iso_8859_1.GetString(text));

            default:
                throw new NotImplementedException($"Unsupported box content type: {type}");
            }
        }
Exemplo n.º 2
0
        private static Dictionary <MP4Tag, object> ParseIlstChild(Stream stream, string type)
        {
            Dictionary <MP4Tag, object> tags = new Dictionary <MP4Tag, object>();

            byte[] childHeader = new byte[8];
            if (stream.Read(childHeader, 0, childHeader.Length) != childHeader.Length)
            {
                throw new MetaParseException($"Unable to read full MP4 \"ilst.{type}\" header");
            }

            int childSize = BitConverter.ToInt32(childHeader.Take(4).Reverse().ToArray(), 0);

            if (childSize < 8)
            {
                return(tags);
            }
            childSize -= 8;
            string childType = iso_8859_1.GetString(childHeader, 4, 4);

            if (childType != "data")
            {
                throw new MetaParseException($"MP4 \"ilst.{type}\" must have a child of type \"data\", actual: \"{childType}\"");
            }

            byte[] childFlags = new byte[4];
            if (stream.Read(childFlags, 0, childFlags.Length) != childFlags.Length)
            {
                throw new MetaParseException($"Unable to read full MP4 \"ilst.{type}.{childType}\" flags");
            }

            stream.Position += 4; // Ignore null bytes
            childSize       -= 8;

            MP4DataType dataType = (MP4DataType)childFlags[3];

            switch (type)
            {
            case "©alb":
                tags[MP4Tag.Album] = GetBoxAsObject(stream, childSize, dataType);
                break;

            case "©art":
                tags[MP4Tag.Artist] = GetBoxAsObject(stream, childSize, dataType);
                break;

            case "©cmt":
                tags[MP4Tag.Comment] = GetBoxAsObject(stream, childSize, dataType);
                break;

            case "©day":
                tags[MP4Tag.Year] = GetBoxAsObject(stream, childSize, dataType);
                break;

            case "©nam":
                tags[MP4Tag.Title] = GetBoxAsObject(stream, childSize, dataType);
                break;

            case "©gen":
            case "gnre":
                tags[MP4Tag.Genre] = GetBoxAsObject(stream, childSize, dataType);
                break;

            case "trkn":
                tags[MP4Tag.TrackNumber] = GetBoxAsObject(stream, childSize, dataType);
                break;

            case "disk":
                tags[MP4Tag.DiscNumber] = GetBoxAsObject(stream, childSize, dataType);
                break;

            case "©wrt":
                tags[MP4Tag.Composer] = GetBoxAsObject(stream, childSize, dataType);
                break;

            case "©too":
                tags[MP4Tag.Encoder] = GetBoxAsObject(stream, childSize, dataType);
                break;

            case "tmpo":
                tags[MP4Tag.BPM] = GetBoxAsObject(stream, childSize, dataType);
                break;

            case "cprt":
                tags[MP4Tag.Copyright] = GetBoxAsObject(stream, childSize, dataType);
                break;

            case "cpil":
                tags[MP4Tag.Composer] = GetBoxAsObject(stream, childSize, dataType);
                break;

            case "©grp":
                tags[MP4Tag.Grouping] = GetBoxAsObject(stream, childSize, dataType);
                break;

            case "catg":
                tags[MP4Tag.Category] = GetBoxAsObject(stream, childSize, dataType);
                break;

            case "keyw":
                tags[MP4Tag.Keyword] = GetBoxAsObject(stream, childSize, dataType);
                break;

            case "desc":
                tags[MP4Tag.Description] = GetBoxAsObject(stream, childSize, dataType);
                break;

            default:
                Trace.WriteLine($"[MP4Parser] ignoring ilst.{type}.{childType} data");
                stream.Position += childSize;
                break;
            }

            return(tags);
        }