/// <summary>Creates the specified header.</summary> /// <param name="header">The header.</param> /// <param name="flags">The flags.</param> /// <param name="description">The description.</param> /// <param name="type">The type.</param> /// <param name="mimeType">Type of the MIME.</param> /// <param name="imageData">The image data.</param> /// <returns></returns> /// <exception cref="NotSupportedException"></exception> public static ID3v2APICFrame Create(ID3v2Header header, ID3v2FrameFlags flags, string description, ID3v2PictureType type, string mimeType, byte[] imageData) { ID3v2EncodingType encoding = ID3v2Encoding.Select(header, description + mimeType); // header, encoding[1], mimeType+0, pitureType[1], description+0, data byte[] descriptionBytes = ID3v2Encoding.GetBytes(encoding, description, true); byte[] mimeTypeBytes = ID3v2Encoding.GetBytes(encoding, mimeType, true); int contentSize = descriptionBytes.Length + mimeTypeBytes.Length + 1 + 1 + imageData.Length; var frameHeader = ID3v2FrameHeader.Create(header, "APIC", flags, contentSize); using (var ms = new MemoryStream()) { var writer = new DataWriter(ms); writer.Write(frameHeader.Data); writer.Write((byte)encoding); writer.Write(mimeTypeBytes); writer.Write((byte)type); writer.Write(descriptionBytes); writer.Write(imageData); if (frameHeader.HeaderSize + contentSize != ms.Position) { throw new Exception(); } return(new ID3v2APICFrame(new ID3v2Frame(header, ms.ToArray()))); } }
/// <summary>Creates a new ID3v2TextFrame.</summary> /// <param name="header">The header.</param> /// <param name="flags">The flags.</param> /// <param name="id">The identifier.</param> /// <param name="text">The text.</param> /// <returns></returns> /// <exception cref="NotSupportedException"></exception> public static ID3v2TextFrame Create(ID3v2Header header, ID3v2FrameFlags flags, string id, string text) { var encoding = ID3v2Encoding.Select(header, text); // header, encoding[1], name+0 var textBytes = ID3v2Encoding.GetBytes(encoding, text, true); var contentSize = 1 + textBytes.Length; var frameHeader = ID3v2FrameHeader.Create(header, id, flags, contentSize); using var ms = new MemoryStream(); var writer = new DataWriter(ms); writer.Write(frameHeader.Data); writer.Write((byte)encoding); writer.Write(textBytes); return(new ID3v2TextFrame(new ID3v2Frame(header, ms.ToArray()))); }
/// <summary>Creates a new header.</summary> /// <param name="header">The tag header.</param> /// <param name="flags">The flags.</param> /// <param name="data">The data.</param> /// <returns></returns> /// <exception cref="NotSupportedException">Unsupported Header Version.</exception> public static ID3v2XSLTFrame Create(ID3v2Header header, ID3v2FrameFlags flags, byte[] data) { switch (header.Version) { case 3: case 4: break; default: throw new NotSupportedException("Unsupported Header Version"); } var frameHeader = ID3v2FrameHeader.Create(header, "XSLT", flags, data.Length); using var ms = new MemoryStream(); var writer = new DataWriter(ms); writer.Write(frameHeader.Data); writer.Write(data); return(new ID3v2XSLTFrame(new ID3v2Frame(header, ms.ToArray()))); }
/// <summary>Creates a new header.</summary> /// <param name="header">The tag header.</param> /// <param name="flags">The flags.</param> /// <param name="name">The name.</param> /// <param name="value">The value.</param> /// <returns></returns> /// <exception cref="NotSupportedException"></exception> public static ID3v2TXXXFrame Create(ID3v2Header header, ID3v2FrameFlags flags, string name, string value) { var encoding = ID3v2Encoding.Select(header, name + value); // header, encoding[1], name+0, value+0 var nameBytes = ID3v2Encoding.GetBytes(encoding, name, true); var valueBytes = ID3v2Encoding.GetBytes(encoding, value, true); var contentSize = nameBytes.Length + valueBytes.Length + 1; var frameHeader = ID3v2FrameHeader.Create(header, "TXXX", flags, contentSize); using var ms = new MemoryStream(); var writer = new DataWriter(ms); writer.Write(frameHeader.Data); writer.Write((byte)encoding); writer.Write(nameBytes); writer.Write(valueBytes); return(new ID3v2TXXXFrame(new ID3v2Frame(header, ms.ToArray()))); }
/// /// Called whent the parser finds a frame. /// void _OnFoundFrame( ID3v2FrameHeader frameHeader, byte [] contentBuffer ) { if (_debugDump) { _Trace( "[_OnFoundFrame]" ); _Trace( " isValid: " + frameHeader.isValid ); _Trace( " size: " + frameHeader.size ); _Trace( " isCompressed: " + frameHeader.isCompressed ); _Trace( " isEncrypted: " + frameHeader.isEncrypted ); _Trace( " isUnsynchronized: " + frameHeader.isUnsynchronized ); _Trace( " hasDataLength: " + frameHeader.hasDataLength ); _Trace( " frameId: " + frameHeader.frameId ); } if (frameHeader.isEncrypted) { // skip frame _Trace( "Note: Skipping encrypted frame" ); return; } if (frameHeader.isCompressed) { _Trace( "Fixme: Skipping compressed frame" ); return; } // if either this, or ALL frames are unsynchronized, deal with it // "This bit MUST be set if the // frame was altered by the unsynchronisation and SHOULD NOT be set if // unaltered. If all frames in the tag are unsynchronised the // unsynchronisation flag in the tag header SHOULD be set. It MUST NOT // be set if the tag has a frame which is not unsynchronised." int contentSize; if (frameHeader.isUnsynchronized) { _FixUnsynchronized( contentBuffer, frameHeader.size, out contentSize ); } else { contentSize = frameHeader.size; } if (_debugDump) { _Trace( "Found Frame <" + frameHeader.frameId + ">" ); } switch (frameHeader.frameId) { // Some things I think might be useful if they turn up case "RVA2": // Relative volume adjustment case "EQU2": // Relative eq adjustment case "TBPM": // bpm case "TBM": // "" case "TCOM": // composer (useful for classical) case "TCOP": // copyright (yeah, I do care) case "TLEN": // Length in...milliseconds case "TLE": // "" case "TPE2": // performed-by (band/supporting artist) case "TPE3": // performed-by (condustor, etc) case "TRSN": // Internet radio station... case "TIT1": // song category thingy case "TIT3": // Song refinement (op3) // Note: "GEOB" frames include a mime type and are frequently HUGE // _Trace( "Desirable frame not supported :( '" // + frameHeader.frameId // + "'" ); break; case "TYER": case "TYE": tyer = _DecodeTextFrame( contentBuffer, frameHeader.size ); break; case "MCDI": // Music CD identifier -- oh yeah. case "MCI": mcdi = contentBuffer; // binary data break; case "TCON": // content type (ROCK/Classical) case "TCO": // content type (ROCK/Classical) tcon = _DecodeTextFrame( contentBuffer, frameHeader.size ); // Important--get all values from null-separated list here. break; case "TIT2": // song title case "TT2": tit2 = _DecodeTextFrame( contentBuffer, frameHeader.size ); break; case "TPE1": // performed-by (lead performer) case "TP1": // performed-by (lead performer) tpe1 = _DecodeTextFrame( contentBuffer, frameHeader.size ); break; case "TALB": // album title case "TAL": // album title talb = _DecodeTextFrame( contentBuffer, frameHeader.size ); break; case "TRCK": // track number case "TRK": string TRCK = _DecodeTextFrame( contentBuffer, frameHeader.size ); string [] parts = TRCK.Split( '/' ); if (parts.Length > 0) trackIndex = Convert.ToInt32( parts[0] ); if (parts.Length > 1) trackCount = Convert.ToInt32( parts[1] ); break; case "COMM": // tag comment (ID3v1 style) case "COM": comm = _DecodeTextFrame( contentBuffer, frameHeader.size ); break; // // ID3v2.2 and earlier frames are decoded here! // default: // _Trace( "ID3 frame type not supported: '" // + frameHeader.frameId // + "'" ); break; } }