public byte [] DownloadSong(Hashtable song, Progress ProgressCallback) { int i; Rijndael alg; string strDownloadKey = (string)song["downloadKey"]; if (strDownloadKey == null) { throw new Exception("Can't download song without downloadKey"); } byte [] encData = Request((string)song["URL"], null, null, "downloadKey=" + strDownloadKey, null, ProgressCallback); alg = Rijndael.Create(); alg.Mode = CipherMode.CBC; alg.Padding = PaddingMode.None; MemoryStream cms = new MemoryStream(); byte [] ftyp = Encoding.ASCII.GetBytes("\0\0\0\0ftypM4A \0\0\0\0"); cms.Write(ftyp, 0, ftyp.Length); byte [] Key = HexStringToBytes((string)song["encryptionKey"]); byte [] IV = new byte[16]; Buffer.BlockCopy(encData, 0, IV, 0, 16); ICryptoTransform ct = alg.CreateDecryptor(Key, IV); CryptoStream cs = new CryptoStream(cms, ct, CryptoStreamMode.Write); cs.Write(encData, 16, ((encData.Length - 16) / 16) * 16); cs.Close(); byte [] mp4 = cms.ToArray(); byte [] moov = Encoding.ASCII.GetBytes("moov"); for (i = 0; i < mp4.Length - 4; i++) { if (mp4[i + 0] == moov[0] && mp4[i + 1] == moov[1] && mp4[i + 2] == moov[2] && mp4[i + 3] == moov[3]) { byte [] offb = BitConverter.GetBytes((UInt32)(i - 4)); if (BitConverter.IsLittleEndian) { Array.Reverse(offb, 0, 4); } Buffer.BlockCopy(offb, 0, mp4, 0, offb.Length); break; } } MP4Root root = new MP4Root(); try { root.Parse(new MemoryStream(mp4)); } catch (InvalidBoxSizeException e) { } MP4Box mp4a = root[MP4Types.MP4A]; if (mp4a != null) { MP4Box sinf = mp4a[MP4Types.SINF]; if (sinf != null) { mp4a.Size -= sinf.Size; sinf.Free(); } } return(root.Bytes); }
public byte[] DownloadSong( Hashtable song, Progress ProgressCallback ) { int i; Rijndael alg; string strDownloadKey = (string)song[ "downloadKey" ]; if( strDownloadKey == null ) { throw new Exception( "Can't download song without downloadKey" ); } byte [] encData = Request( (string)song[ "URL" ], null, null, "downloadKey=" + strDownloadKey, null, ProgressCallback ); alg = Rijndael.Create(); alg.Mode = CipherMode.CBC; alg.Padding = PaddingMode.None; MemoryStream cms = new MemoryStream(); byte [] ftyp = Encoding.ASCII.GetBytes( "\0\0\0\0ftypM4A \0\0\0\0" ); cms.Write( ftyp, 0, ftyp.Length ); byte [] Key = HexStringToBytes( (string)song[ "encryptionKey" ] ); byte [] IV = new byte[ 16 ]; Buffer.BlockCopy( encData, 0, IV, 0, 16 ); ICryptoTransform ct = alg.CreateDecryptor( Key, IV ); CryptoStream cs = new CryptoStream( cms, ct, CryptoStreamMode.Write ); cs.Write( encData, 16, ((encData.Length - 16) / 16) * 16 ); cs.Close(); byte [] mp4 = cms.ToArray(); byte [] moov = Encoding.ASCII.GetBytes( "moov" ); for( i = 0; i < mp4.Length - 4; i++ ) { if( mp4[ i + 0 ] == moov[ 0 ] && mp4[ i + 1 ] == moov[ 1 ] && mp4[ i + 2 ] == moov[ 2 ] && mp4[ i + 3 ] == moov[ 3 ] ) { byte [] offb = BitConverter.GetBytes( (UInt32)(i - 4) ); if( BitConverter.IsLittleEndian ) Array.Reverse( offb, 0, 4 ); Buffer.BlockCopy( offb, 0, mp4, 0, offb.Length ); break; } } MP4Root root = new MP4Root(); try { root.Parse( new MemoryStream( mp4 ) ); } catch( InvalidBoxSizeException e ) { } MP4Box mp4a = root[ MP4Types.MP4A ]; if( mp4a != null ) { MP4Box sinf = mp4a[ MP4Types.SINF ]; if( sinf != null ) { mp4a.Size -= sinf.Size; sinf.Free(); } } return root.Bytes; }