Esempio n. 1
0
    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;
    }