locked
[UWP]How can we play partially decrypted video into media element. RRS feed

  • Question

  • I am downloading a large 3GB file and encrypting into chunks and save into app local. Then when playing decrypting same file into chunks and after completing decrypted file only I am able to play.

    Is it possible if I decrypted first chunks and give to player for playing and next decryption going on as it is then give next chunks part for playing and so on.. Motive is when I start decrypting media element start going to play video don't wait till decrypting completely.

    My Code is-

           private void Encrypt(Stream input, Stream output, String password, String salt)
            {
                output.Position = 0;
                byte[] buffer = new byte[1024 * 1024];
                int bytesRead;
                while ((bytesRead = input.Read(buffer, 0, buffer.Length)) > 0)
                {
                    var tmp = AES_Encrypt(buffer, password, salt);
                    output.Write(tmp, 0, tmp.Length);
                }
            }

            public byte[] AES_Encrypt(byte[] bytesToBeEncrypted, String pass, String salt)
            {
                byte[] encryptedBytes = null;
                byte[] passByte = Encoding.ASCII.GetBytes(pass);
                byte[] saltBytes = Encoding.ASCII.GetBytes(salt);
                Aes aesEn = Aes.Create();
                aesEn.Padding = PaddingMode.None;
                aesEn.Mode = CipherMode.CBC;
                ICryptoTransform encryptor = aesEn.CreateEncryptor(passByte, saltBytes);
                using (MemoryStream ms = new MemoryStream())
                {
                    using (var cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write))
                    {
                        cs.Write(bytesToBeEncrypted, 0, bytesToBeEncrypted.Length);
                    }
                    encryptedBytes = ms.ToArray();
                }
                return encryptedBytes;
            }

            private async Task Decrypt(Stream input, Stream output, String password, String salt)
            {
                input.Position = 0;
                byte[] buffer = new byte[1024 * 1024];
                int bytesRead;
                while ((bytesRead = await input.ReadAsync(buffer, 0, buffer.Length)) > 0)
                {
                    var tmp = AES_Decrypt(buffer, password, salt);

                    await output.WriteAsync(tmp, 0, tmp.Length);

                   // I want to give to player here for saving time.

                }

                Uri pathUri = new Uri("ms-appx:///Content/de5146");
                media.Source = MediaSource.CreateFromUri(pathUri);
            }

            public byte[] AES_Decrypt(byte[] bytesToBeDecrypted, String pass, String salt)
            {
                byte[] decryptedBytes = null;
                byte[] passByte = Encoding.ASCII.GetBytes(pass);
                byte[] saltBytes = Encoding.ASCII.GetBytes(salt);
                Aes aesEn = Aes.Create();
                aesEn.Padding = PaddingMode.None;
                aesEn.Mode = CipherMode.CBC;
                ICryptoTransform decryptor = aesEn.CreateDecryptor(passByte, saltBytes);
                using (MemoryStream ms = new MemoryStream())
                {
                    using (var cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Write))
                    {
                        cs.Write(bytesToBeDecrypted, 0, bytesToBeDecrypted.Length);
                    }
                    decryptedBytes = ms.ToArray();
                    ms.Flush();
                }
                return decryptedBytes;
            }

      

    sandeep chauhan


    Friday, April 5, 2019 2:29 PM

All replies

  • I am reading large video file more than 1 GB or 2 GB, I am getting Out of memory exception when reading in 2nd line in below code.

         var fileForEncryption = await folder.GetFileAsync(fileName);
         IBuffer data = await FileIO.ReadBufferAsync(fileForEncryption);
         IBuffer securedData = EncryptAes_CBC(PDSConstants.ENCRYPTION_PWD, PDSConstants.ENCRYPTION_SALT, data);
         var encryptedFile = await folder.CreateFileAsync(
         fileName, CreationCollisionOption.ReplaceExisting);
         await FileIO.WriteBufferAsync(encryptedFile, securedData);


    sandeep chauhan

    Thursday, April 4, 2019 6:52 AM
  • A 32-bit application has a very difficult time allocating 1 GB or more of continuous memory. See http://www.gamasutra.com/view/feature/3602/sponsored_feature_ram_vram_and_.php
    Thursday, April 4, 2019 11:36 PM
  • Thanks for reply!

    My app is for 64 bit device.

    I am able to get stream buffer into chunks and encrypt then save into app local, same doing in case of decryption but its taking time due to large file size approx. 3GB file. Is there any way to do it smooth means while we decrypting the file same time assing to Media Payer like that... so that save time.


    sandeep chauhan

    Friday, April 5, 2019 6:34 AM
  • Hi Sandeep,

    Again, you do not want to get the stream in chunks from local storage and decrypt and play and get next chunks. While this might appear to work it is not a good solution and you will run into additional problems with it. You should investigate using the Microsoft PlayReady technology to facilitate encrypting and decoding the video for you. That is the correct way to solve the issue of encrypting and decoding protected video in the Windows environment. 

    Microsoft PlayReady

    https://docs.microsoft.com/en-us/playready/

    Microsoft PlayReady sample

    https://github.com/Microsoft/Windows-universal-samples/tree/master/Samples/PlayReady

    I hope this helps,

    James


    Windows SDK Technologies - Microsoft Developer Services - http://blogs.msdn.com/mediasdkstuff/

    Friday, April 5, 2019 9:07 PM