首页 > 解决方案 > videoview 中的 xamarin.android 视频流

问题描述

我正在使用链接加密我的视频并将其存储在我的应用程序文件夹中。但是对于大视频来说,2GB,解密然后播放需要很长时间。所以用户必须等待 1.5-2 分钟才能解密选定的视频然后播放。

为此,我搜索了离线视频流。我发现了这个。我有同样的场景,但我不是下载,而是从画廊加密视频。我使用了不同的加密算法。

当我尝试上面的链接时,每次进入 while 循环时我的连接都会丢失。在捕获中,我得到Connection is reset错误。我也没有在那里得到一些变量。比如, total,readbytepos变量。有人可以解释一下吗?

我真的很想同时解密和播放视频。所以用户体验会很好。

谢谢你。

编辑 这是我的示例代码:

using Android.App;
using Android.Widget;
using Android.OS;
using Android.Support.V7.App;
using Java.IO;
using Javax.Crypto;
using Javax.Crypto.Spec;
using System;
using System.IO;
using Java.Net;
using System.Threading.Tasks;

namespace SecretCalc
{
[Activity(Label = "@string/app_name", Theme = "@style/AppTheme", 
MainLauncher = true)]
public class MainActivity : AppCompatActivity
{
    VideoView video;
    Button encrypt, decrypt;
    private string sKey = "0123456789abcdef";//key,
    private string ivParameter = "1020304050607080";
    string path = "/sdcard/Download/";
    string destpath = "/sdcard/test/";
    string filename = "video1.mp4";
    Stream outputStream;
    string date = "20180922153533.mp4"; // Already Encrypted File Name

    protected override void OnCreate(Bundle savedInstanceState)
    {
        base.OnCreate(savedInstanceState);

        // Set our view from the "main" layout resource
        SetContentView(Resource.Layout.activity_main);

        video = FindViewById<VideoView>(Resource.Id.videoView);
        encrypt = FindViewById<Button>(Resource.Id.btnEncrypt);
        decrypt = FindViewById<Button>(Resource.Id.btnDecrypt);

        encrypt.Click += Encrypt_Click;
        decrypt.Click += Decrypt_ClickAsync;
    }


    private async void Decrypt_ClickAsync(object sender, EventArgs e)
    {
        video.SetVideoPath("http://0.0.0.0:9990/");
        video.Prepared += Video_Prepared;

        await Task.Run(() =>
        {
            try
            {
                ServerSocket serverSocket = new ServerSocket();
                serverSocket.Bind(new InetSocketAddress("0.0.0.0", 9990));

                // this is a blocking call, control will be blocked until client sends the request
                Socket finalAccept = serverSocket.Accept();
                outputStream = finalAccept.OutputStream;
            }
            catch (Exception ex)
            {
            }
        });

        await Task.Run(() => DecryptThroughSocket());

    }

    private void Video_Prepared(object sender, EventArgs e)
    {
        video.Start();
    }

    private bool DecryptThroughSocket()
    {
        try
        {
            byte[] raw = System.Text.Encoding.Default.GetBytes(sKey);
            byte[] iv = System.Text.Encoding.Default.GetBytes(ivParameter);

            int count = 0, pos = 0, total = 0, readbyte;

            byte[] data = new byte[1024 * 1024];
            readbyte = data.Length;
            long lenghtOfFile = new Java.IO.File(Path.Combine(path, date)).Length();

            FileInputStream inputStream = new FileInputStream(Path.Combine(destpath, date));

            while ((count = inputStream.Read(data, 0, readbyte)) != -1)
            {
                if (count < readbyte)
                {
                    if ((lenghtOfFile - total) > readbyte)
                    {
                        while (true)
                        {
                            int seccount = inputStream.Read(data, pos, (readbyte - pos));
                            pos = pos + seccount;
                            if (pos == readbyte)
                            {
                                break;
                            }
                        }
                    }
                }

                // encrypt data read before writing to output stream
                byte[] decryptedData = decryptFun(raw, iv, data);
                outputStream.Write(decryptedData,0,decryptedData.Length);
            }
        }
        catch (Exception ex)
        {

            return false;
        }
        return true;
    }

    private void Encrypt_Click(object sender, EventArgs e)
    {
        try
        {
            FileInputStream inputStream = new FileInputStream(System.IO.Path.Combine(path, filename));

            date = DateTime.Now.ToString("yyyyMMddHHmmss") + ".mp4";

            DirectoryInfo dir = new DirectoryInfo(destpath);

            if (!dir.Exists)
            {
                Directory.CreateDirectory(destpath);
            }

            FileOutputStream outputStream = new FileOutputStream(System.IO.Path.Combine(destpath, date));

            byte[] raw = System.Text.Encoding.Default.GetBytes(sKey);
            byte[] iv = System.Text.Encoding.Default.GetBytes(ivParameter);

            int count = 0, pos = 0, total = 0, readbyte;

            byte[] data = new byte[1024 * 1024];
            readbyte = data.Length;
            long lenghtOfFile = new Java.IO.File(Path.Combine(path, filename)).Length();

            while ((count = inputStream.Read(data, 0, readbyte)) != -1)
            {
                if (count < readbyte)
                {
                    if ((lenghtOfFile - total) > readbyte)
                    {
                        while (true)
                        {
                            int seccount = inputStream.Read(data, pos, (readbyte - pos));
                            pos = pos + seccount;
                            if (pos == readbyte)
                            {
                                break;
                            }
                        }
                    }
                }

                total += count;

                // encrypt data read before writing to output stream
                byte[] encryptedData = encryptFun(raw, iv, data);
                outputStream.Write(encryptedData);
            }
        }
        catch (Exception ex)
        {
        }
    }

    public static byte[] encryptFun(byte[] key, byte[] iv, byte[] clear)
    {
        SecretKeySpec skeySpec = new SecretKeySpec(key, "AES");
        Cipher cipher = Cipher.GetInstance("AES/CTR/NoPadding");

        IvParameterSpec ivspec = new IvParameterSpec(iv);

        cipher.Init(CipherMode.EncryptMode, skeySpec, ivspec);
        byte[] encrypted = cipher.DoFinal(clear);
        return encrypted;
    }

    public static byte[] decryptFun(byte[] key, byte[] iv, byte[] encrypted)
    {
        SecretKeySpec skeySpec = new SecretKeySpec(key, "AES");
        Cipher cipher = Cipher.GetInstance("AES/CTR/NoPadding");

        IvParameterSpec ivspec = new IvParameterSpec(iv);
        cipher.Init(CipherMode.DecryptMode, skeySpec, ivspec);

        byte[] decrypted = cipher.DoFinal(encrypted);
        return decrypted;
    }
}
}

标签: androidxamarinencryptionxamarin.android

解决方案


推荐阅读