Я шифрую свои видео с помощью этой ссылки и сохраняю ее в папке своего приложения. Но для больших видео, скажем, 2 ГБ, расшифровка, а затем воспроизведение занимает много времени. поэтому пользователь должен подождать 1,5-2 минуты, чтобы расшифровать выбранное видео и затем воспроизвести его.
Для этого я искал потоковое видео в автономном режиме. И я нашел это . У меня такой же сценарий, но вместо загрузки я шифрую видео из галереи. и я использовал другой алгоритм шифрования.
Когда я попробовал вышеуказанную ссылку, мое соединение теряется при каждом входе в цикл while. В улове я получаю Connection is reset
ошибку. Также я не получил некоторые переменные там. например, total
, readbyte
и pos
переменные. Кто-нибудь может объяснить, пожалуйста?
Я действительно хочу расшифровывать и воспроизводить видео одновременно. так что пользовательский опыт будет хорошим.
Спасибо.
EDIT
Вот мой пример кода:
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;
}
}
}