/// <summary> /// Creates an ID3v2 frame for the given key-value pair. /// </summary> /// <param name="key"></param> /// <param name="value"></param> /// <returns></returns> static byte[] CreateId3v2Frame(string key, string value) { if (string.IsNullOrEmpty(key)) { throw new ArgumentNullException("key"); } if (string.IsNullOrEmpty(value)) { throw new ArgumentNullException("value"); } if (key.Length != 4) { throw new ArgumentOutOfRangeException("key", "key " + key + " must be 4 characters long"); } const byte UnicodeEncoding = 01; // encode text in Unicode byte[] UnicodeOrder = new byte[] { 0xff, 0xfe }; // Unicode byte order mark byte[] language = new byte[] { 0, 0, 0 }; // language is empty (only used in COMM -> comment) byte[] shortDescription = new byte[] { 0, 0 }; // short description is empty (only used in COMM -> comment) byte[] body; if (key == "COMM") // comment { body = ByteArrayExtensions.Concat( new byte[] { UnicodeEncoding }, language, shortDescription, UnicodeOrder, Encoding.Unicode.GetBytes(value)); } else { body = ByteArrayExtensions.Concat( new byte[] { UnicodeEncoding }, UnicodeOrder, Encoding.Unicode.GetBytes(value)); } return(ByteArrayExtensions.Concat( // needs review - have converted to UTF8 as Win 8 has no Encoding.ASCII, // need to check what the rules are for ID3v2 tag identifiers Encoding.UTF8.GetBytes(key), FrameSizeToBytes(body.Length), new byte[] { 0, 0 }, // flags body)); }
/// <summary> /// Creates the Id3v2 tag header and returns is as a byte array. /// </summary> /// <param name="frames">The Id3v2 frames that will be included in the file. This is used to calculate the ID3v2 tag size.</param> /// <returns></returns> static byte[] CreateId3v2TagHeader(IEnumerable <byte[]> frames) { int size = 0; foreach (byte[] frame in frames) { size += frame.Length; } byte[] tagHeader = ByteArrayExtensions.Concat( Encoding.UTF8.GetBytes("ID3"), new byte[] { 3, 0 }, // version new byte[] { 0 }, // flags GetId3TagHeaderSize(size)); return(tagHeader); }