additions

This commit is contained in:
2025-10-12 10:59:34 +09:00
parent 4d551bd74f
commit e94c4a1841
563 changed files with 12541 additions and 5787 deletions

View File

@@ -0,0 +1,166 @@
using System;
using System.IO;
using System.Text;
using System.Threading;
namespace VideoReader
{
public static class DetailedLogger
{
private static readonly object _lockObject = new object();
private static string _logFilePath;
private static bool _isInitialized = false;
public static void Initialize()
{
if (_isInitialized) return;
var timestamp = DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss");
_logFilePath = $"videoreader_detailed_{timestamp}.log";
lock (_lockObject)
{
try
{
File.WriteAllText(_logFilePath, $"=== VideoReader Global Edition Detailed Log ===\n");
File.AppendAllText(_logFilePath, $"Session started: {DateTime.Now:yyyy-MM-dd HH:mm:ss.fff}\n");
File.AppendAllText(_logFilePath, $"Process ID: {Environment.ProcessId}\n");
File.AppendAllText(_logFilePath, $"Machine: {Environment.MachineName}\n");
File.AppendAllText(_logFilePath, $"User: {Environment.UserName}\n");
File.AppendAllText(_logFilePath, "==============================================\n\n");
_isInitialized = true;
Console.WriteLine($"Detailed logging initialized: {_logFilePath}");
}
catch (Exception ex)
{
Console.WriteLine($"Failed to initialize logging: {ex.Message}");
}
}
}
public static void LogConnection(string message)
{
WriteLog("CONNECTION", message);
}
public static void LogPacket(string direction, byte[] data, string description = "")
{
var hexData = BitConverter.ToString(data).Replace("-", " ");
var asciiData = GetAsciiRepresentation(data);
var logMessage = new StringBuilder();
logMessage.AppendLine($"Direction: {direction}");
logMessage.AppendLine($"Size: {data.Length} bytes");
if (!string.IsNullOrEmpty(description))
logMessage.AppendLine($"Description: {description}");
logMessage.AppendLine($"HEX: {hexData}");
logMessage.AppendLine($"ASCII: {asciiData}");
logMessage.AppendLine($"Binary dump:");
// Форматированный hex dump как в hex editor
for (int i = 0; i < data.Length; i += 16)
{
var offset = $"{i:X8}";
var hexLine = new StringBuilder();
var asciiLine = new StringBuilder();
for (int j = 0; j < 16; j++)
{
if (i + j < data.Length)
{
hexLine.Append($"{data[i + j]:X2} ");
asciiLine.Append(data[i + j] >= 32 && data[i + j] <= 126 ? (char)data[i + j] : '.');
}
else
{
hexLine.Append(" ");
asciiLine.Append(" ");
}
}
logMessage.AppendLine($"{offset}: {hexLine} | {asciiLine}");
}
WriteLog("PACKET", logMessage.ToString());
}
public static void LogPhoneConnection(string phoneInfo, string action)
{
WriteLog("PHONE", $"Action: {action} | Phone: {phoneInfo}");
}
public static void LogError(string error, Exception ex = null)
{
var message = error;
if (ex != null)
{
message += $"\nException: {ex.GetType().Name}: {ex.Message}";
message += $"\nStackTrace: {ex.StackTrace}";
}
WriteLog("ERROR", message);
}
public static void LogDebug(string message)
{
WriteLog("DEBUG", message);
}
public static void LogInfo(string message)
{
WriteLog("INFO", message);
}
private static void WriteLog(string level, string message)
{
if (!_isInitialized) Initialize();
var timestamp = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");
var threadId = Thread.CurrentThread.ManagedThreadId;
var logEntry = $"[{timestamp}] [{level}] [Thread-{threadId}] {message}\n";
lock (_lockObject)
{
try
{
File.AppendAllText(_logFilePath, logEntry);
// Дублируем важные сообщения в консоль
if (level == "CONNECTION" || level == "PHONE" || level == "ERROR")
{
Console.WriteLine($"[{level}] {message}");
}
}
catch (Exception ex)
{
Console.WriteLine($"Logging failed: {ex.Message}");
}
}
}
private static string GetAsciiRepresentation(byte[] data)
{
var result = new StringBuilder();
foreach (var b in data)
{
if (b >= 32 && b <= 126)
result.Append((char)b);
else
result.Append('.');
}
return result.ToString();
}
public static void LogStatistics()
{
var stats = new StringBuilder();
stats.AppendLine("=== SESSION STATISTICS ===");
stats.AppendLine($"Session ended: {DateTime.Now:yyyy-MM-dd HH:mm:ss.fff}");
stats.AppendLine($"Log file: {_logFilePath}");
stats.AppendLine($"Total memory: {GC.GetTotalMemory(false)} bytes");
stats.AppendLine("==========================");
WriteLog("STATS", stats.ToString());
}
}
}

View File

@@ -0,0 +1,414 @@
using System;
using System.Collections.Concurrent;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Security.Cryptography;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace VideoReader
{
internal class InOutSocket
{
public int bitrateout = 0;
public int bitratein = 0;
private static byte[] keyByte = MD5("73!2#qweaSdzxc4r");
private static byte[] ivByte = MD5("0_=op[l:',./vf73");
private bool open;
private ServerConfig config;
private ConcurrentQueue<byte[]> outbuffer = new ConcurrentQueue<byte[]>();
private BinaryWriter bw;
private ConcurrentQueue<byte[]> output = new ConcurrentQueue<byte[]>();
private bool noblock = true;
// Новые поля для детального логгирования
private TcpClient tcpClient;
private NetworkStream networkStream;
private Thread receiveThread;
private Thread sendThread;
private bool isRunning = false;
private long packetCounter = 0;
private DateTime connectionStartTime;
public bool opened
{
get { return open; }
set { open = value; }
}
public InOutSocket()
{
config = ServerConfig.LoadConfig();
DetailedLogger.LogConnection($"InOutSocket initialized with server: {config.ServerAddress}:{config.Port}");
DetailedLogger.LogDebug($"Encryption keys initialized - Key: {BitConverter.ToString(keyByte)}, IV: {BitConverter.ToString(ivByte)}");
}
private static byte[] MD5(string input)
{
using (var md5 = System.Security.Cryptography.MD5.Create())
{
return md5.ComputeHash(Encoding.UTF8.GetBytes(input));
}
}
public void Connect()
{
try
{
connectionStartTime = DateTime.Now;
DetailedLogger.LogConnection($"Starting connection to {config.ServerAddress}:{config.Port}...");
// DNS Resolution
DetailedLogger.LogDebug($"Resolving DNS for {config.ServerAddress}...");
var addresses = Dns.GetHostAddresses(config.ServerAddress);
DetailedLogger.LogDebug($"DNS resolved to {addresses.Length} addresses: {string.Join(", ", addresses.Select(a => a.ToString()))}");
// TCP Connection
tcpClient = new TcpClient();
tcpClient.ReceiveTimeout = 30000; // 30 seconds
tcpClient.SendTimeout = 30000;
var connectTask = tcpClient.ConnectAsync(config.ServerAddress, config.Port);
var sw = Stopwatch.StartNew();
DetailedLogger.LogConnection($"Attempting TCP connection to {config.ServerAddress}:{config.Port}...");
connectTask.Wait(10000); // 10 second timeout
if (!tcpClient.Connected)
{
throw new Exception($"Failed to connect within timeout");
}
sw.Stop();
DetailedLogger.LogConnection($"TCP connection established in {sw.ElapsedMilliseconds}ms");
networkStream = tcpClient.GetStream();
DetailedLogger.LogDebug($"Network stream obtained, available: {networkStream.DataAvailable}");
// Send authorization bytes (as per original protocol)
DetailedLogger.LogDebug("Sending authorization bytes...");
networkStream.WriteByte(0); // Receiver type
networkStream.WriteByte((byte)config.Channel); // Channel number
networkStream.Flush();
DetailedLogger.LogConnection($"Authorization sent: ReceiverType=0, Channel={config.Channel}");
// Start monitoring threads
isRunning = true;
receiveThread = new Thread(ReceiveLoop) { IsBackground = true, Name = "ReceiveThread" };
sendThread = new Thread(SendLoop) { IsBackground = true, Name = "SendThread" };
receiveThread.Start();
sendThread.Start();
DetailedLogger.LogConnection("Monitoring threads started");
// Send initial handshake
SendInitialHandshake();
opened = true;
DetailedLogger.LogConnection("Connection established successfully");
}
catch (Exception ex)
{
DetailedLogger.LogError($"Connection failed: {ex.Message}", ex);
opened = false;
Cleanup();
throw;
}
}
public void Disconnect()
{
DetailedLogger.LogConnection("Starting disconnect procedure...");
isRunning = false;
opened = false;
try
{
// Send disconnect packet if possible
if (networkStream != null && tcpClient != null && tcpClient.Connected)
{
var disconnectPacket = Encoding.UTF8.GetBytes("DISCONNECT");
SendPacket(disconnectPacket, "Disconnect command");
}
}
catch (Exception ex)
{
DetailedLogger.LogError($"Error sending disconnect packet: {ex.Message}");
}
Cleanup();
var totalTime = DateTime.Now - connectionStartTime;
DetailedLogger.LogConnection($"Disconnected from server (session duration: {totalTime.TotalSeconds:F1}s, packets processed: {packetCounter})");
}
private void Cleanup()
{
try
{
networkStream?.Close();
networkStream?.Dispose();
tcpClient?.Close();
tcpClient?.Dispose();
// Wait for threads to finish
receiveThread?.Join(2000);
sendThread?.Join(2000);
DetailedLogger.LogDebug("Connection cleanup completed");
}
catch (Exception ex)
{
DetailedLogger.LogError($"Error during cleanup: {ex.Message}");
}
}
private void SendInitialHandshake()
{
try
{
DetailedLogger.LogConnection("Sending initial handshake...");
// Создаем пакет авторизации
var handshakeData = new byte[64];
var channelBytes = BitConverter.GetBytes(config.Channel);
var serverTypeBytes = Encoding.UTF8.GetBytes(config.ServerType.PadRight(16).Substring(0, 16));
Array.Copy(channelBytes, 0, handshakeData, 0, 4);
Array.Copy(serverTypeBytes, 0, handshakeData, 4, 16);
// Добавляем timestamp
var timestamp = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
var timestampBytes = BitConverter.GetBytes(timestamp);
Array.Copy(timestampBytes, 0, handshakeData, 20, 8);
SendPacket(handshakeData, "Initial handshake");
}
catch (Exception ex)
{
DetailedLogger.LogError($"Failed to send handshake: {ex.Message}", ex);
}
}
private void SendPacket(byte[] data, string description)
{
try
{
var encryptedData = EncryptData(data);
DetailedLogger.LogPacket("OUTGOING", encryptedData, description);
networkStream.Write(encryptedData, 0, encryptedData.Length);
networkStream.Flush();
Interlocked.Add(ref bitrateout, encryptedData.Length);
Interlocked.Increment(ref packetCounter);
DetailedLogger.LogDebug($"Packet sent successfully ({encryptedData.Length} bytes)");
}
catch (Exception ex)
{
DetailedLogger.LogError($"Failed to send packet: {ex.Message}", ex);
}
}
private void ReceiveLoop()
{
DetailedLogger.LogDebug("Receive thread started");
var buffer = new byte[8192];
while (isRunning && tcpClient?.Connected == true)
{
try
{
if (networkStream.DataAvailable)
{
var bytesRead = networkStream.Read(buffer, 0, buffer.Length);
if (bytesRead > 0)
{
var receivedData = new byte[bytesRead];
Array.Copy(buffer, receivedData, bytesRead);
ProcessReceivedPacket(receivedData);
Interlocked.Add(ref bitratein, bytesRead);
Interlocked.Increment(ref packetCounter);
}
}
Thread.Sleep(10); // Небольшая задержка чтобы не грузить CPU
}
catch (Exception ex)
{
if (isRunning) // Только логгируем если не идет остановка
{
DetailedLogger.LogError($"Error in receive loop: {ex.Message}");
}
break;
}
}
DetailedLogger.LogDebug("Receive thread stopped");
}
private void SendLoop()
{
DetailedLogger.LogDebug("Send thread started");
while (isRunning && tcpClient?.Connected == true)
{
try
{
if (outbuffer.TryDequeue(out byte[] dataToSend))
{
SendPacket(dataToSend, "Queued data");
}
Thread.Sleep(10);
}
catch (Exception ex)
{
if (isRunning)
{
DetailedLogger.LogError($"Error in send loop: {ex.Message}");
}
break;
}
}
DetailedLogger.LogDebug("Send thread stopped");
}
private void ProcessReceivedPacket(byte[] rawData)
{
try
{
DetailedLogger.LogPacket("INCOMING", rawData, "Raw received data");
// Пытаемся расшифровать данные
var decryptedData = DecryptData(rawData);
if (decryptedData != null)
{
DetailedLogger.LogPacket("DECRYPTED", decryptedData, "Decrypted data");
AnalyzePacketContent(decryptedData);
}
else
{
DetailedLogger.LogDebug("Failed to decrypt packet, analyzing as plain data");
AnalyzePacketContent(rawData);
}
}
catch (Exception ex)
{
DetailedLogger.LogError($"Error processing received packet: {ex.Message}", ex);
}
}
private void AnalyzePacketContent(byte[] data)
{
try
{
var dataStr = Encoding.UTF8.GetString(data);
// Проверяем на подключение телефона
if (dataStr.Contains("PHONE") || dataStr.Contains("DEVICE") || dataStr.Contains("CONNECT"))
{
DetailedLogger.LogPhoneConnection(dataStr, "Phone connection detected in packet");
}
// Проверяем другие типы пакетов
if (dataStr.Contains("VIDEO"))
{
DetailedLogger.LogDebug("Video data packet detected");
}
else if (dataStr.Contains("AUDIO"))
{
DetailedLogger.LogDebug("Audio data packet detected");
}
else if (dataStr.Contains("HEARTBEAT") || dataStr.Contains("PING"))
{
DetailedLogger.LogDebug("Heartbeat/ping packet detected");
}
else if (dataStr.Contains("AUTH") || dataStr.Contains("LOGIN"))
{
DetailedLogger.LogConnection("Authentication packet detected");
}
// Логгируем содержимое пакета
DetailedLogger.LogDebug($"Packet content analysis: {dataStr.Substring(0, Math.Min(100, dataStr.Length))}...");
}
catch (Exception ex)
{
DetailedLogger.LogDebug($"Could not analyze packet as text: {ex.Message}");
}
}
private byte[] EncryptData(byte[] data)
{
try
{
using (var aes = Aes.Create())
{
aes.Key = keyByte;
aes.IV = ivByte;
aes.Mode = CipherMode.CBC;
aes.Padding = PaddingMode.PKCS7;
using (var encryptor = aes.CreateEncryptor())
using (var ms = new MemoryStream())
using (var cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write))
{
cs.Write(data, 0, data.Length);
cs.FlushFinalBlock();
return ms.ToArray();
}
}
}
catch (Exception ex)
{
DetailedLogger.LogError($"Encryption failed: {ex.Message}");
return data; // Возвращаем оригинальные данные если шифрование не удалось
}
}
private byte[] DecryptData(byte[] data)
{
try
{
using (var aes = Aes.Create())
{
aes.Key = keyByte;
aes.IV = ivByte;
aes.Mode = CipherMode.CBC;
aes.Padding = PaddingMode.PKCS7;
using (var decryptor = aes.CreateDecryptor())
using (var ms = new MemoryStream(data))
using (var cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Read))
using (var result = new MemoryStream())
{
cs.CopyTo(result);
return result.ToArray();
}
}
}
catch (Exception ex)
{
DetailedLogger.LogDebug($"Decryption failed (data might not be encrypted): {ex.Message}");
return null;
}
}
public void QueueDataForSending(byte[] data)
{
outbuffer.Enqueue(data);
DetailedLogger.LogDebug($"Data queued for sending ({data.Length} bytes)");
}
}
}

81
desktop_global/Program.cs Normal file
View File

@@ -0,0 +1,81 @@
using System;
using System.Threading;
using System.Text;
namespace VideoReader
{
public class Program
{
public static void Main(string[] args)
{
Console.WriteLine("VideoReader Global Edition v1.0");
Console.WriteLine("===================================");
Console.WriteLine();
// Инициализируем детальное логгирование
DetailedLogger.Initialize();
DetailedLogger.LogInfo("Application started");
try
{
// Загружаем конфигурацию
var config = ServerConfig.LoadConfig();
DetailedLogger.LogInfo($"Loaded server configuration: {config.ServerAddress}:{config.Port}");
DetailedLogger.LogInfo($"Channel: {config.Channel}");
DetailedLogger.LogInfo($"Server Type: {config.ServerType}");
Console.WriteLine($"Loaded server configuration: {config.ServerAddress}:{config.Port}");
Console.WriteLine($"Channel: {config.Channel}");
Console.WriteLine($"Server Type: {config.ServerType}");
Console.WriteLine();
// Создаем подключение (без GUI)
var socket = new InOutSocket();
socket.Connect();
Console.WriteLine();
Console.WriteLine("Application running in console mode.");
Console.WriteLine("Commands:");
Console.WriteLine(" 's' - Show statistics");
Console.WriteLine(" 'q' - Quit");
Console.WriteLine(" 'd' - Send test data");
Console.WriteLine("Press any key to exit...");
// Интерактивный режим
while (true)
{
var key = Console.ReadKey(true);
if (key.KeyChar == 'q' || key.KeyChar == 'Q')
{
break;
}
else if (key.KeyChar == 's' || key.KeyChar == 'S')
{
Console.WriteLine($"Statistics: In={socket.bitratein} bytes, Out={socket.bitrateout} bytes");
DetailedLogger.LogInfo($"User requested statistics: In={socket.bitratein}, Out={socket.bitrateout}");
}
else if (key.KeyChar == 'd' || key.KeyChar == 'D')
{
var testData = Encoding.UTF8.GetBytes($"TEST_DATA_{DateTime.Now:HHmmss}");
socket.QueueDataForSending(testData);
Console.WriteLine("Test data queued for sending");
}
}
socket.Disconnect();
DetailedLogger.LogStatistics();
}
catch (Exception ex)
{
Console.WriteLine($"Error: {ex.Message}");
DetailedLogger.LogError($"Application error: {ex.Message}", ex);
Console.WriteLine("Press any key to exit...");
Console.ReadKey();
}
finally
{
DetailedLogger.LogInfo("Application shutdown");
}
}
}
}

View File

@@ -1,18 +0,0 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
[assembly: Guid("9ab99e02-6594-4dea-9abf-21ca96c8ba60")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyCopyright("Copyright © 2016")]
[assembly: ComVisible(false)]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyTitle("VideoView")]
[assembly: AssemblyProduct("VideoView")]
[assembly: AssemblyVersion("1.0.8917.28848")]

View File

@@ -0,0 +1,58 @@
using System;
using System.IO;
using System.Text.Json;
namespace VideoReader
{
public class ServerConfig
{
public string ServerType { get; set; } = "standard";
public string ServerAddress { get; set; } = "vidser.top";
public int Port { get; set; } = 3033;
public int Channel { get; set; } = 0;
public string Description { get; set; } = "Standard VideoReader server configuration";
public static ServerConfig LoadConfig()
{
const string configFile = "server-config.json";
try
{
if (File.Exists(configFile))
{
var json = File.ReadAllText(configFile);
var config = JsonSerializer.Deserialize<ServerConfig>(json);
Console.WriteLine($"Configuration loaded from {configFile}");
return config ?? new ServerConfig();
}
else
{
Console.WriteLine($"Configuration file {configFile} not found, using defaults");
var defaultConfig = new ServerConfig();
SaveConfig(defaultConfig);
return defaultConfig;
}
}
catch (Exception ex)
{
Console.WriteLine($"Error loading configuration: {ex.Message}");
return new ServerConfig();
}
}
public static void SaveConfig(ServerConfig config)
{
const string configFile = "server-config.json";
try
{
var json = JsonSerializer.Serialize(config, new JsonSerializerOptions { WriteIndented = true });
File.WriteAllText(configFile, json);
Console.WriteLine($"Configuration saved to {configFile}");
}
catch (Exception ex)
{
Console.WriteLine($"Error saving configuration: {ex.Message}");
}
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -2,13 +2,12 @@
<PropertyGroup>
<AssemblyName>VideoReader-Global</AssemblyName>
<AssemblyTitle>VideoReader Global Edition</AssemblyTitle>
<GenerateAssemblyInfo>False</GenerateAssemblyInfo>
<OutputType>WinExe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<PlatformTarget>x86</PlatformTarget>
<GenerateAssemblyInfo>True</GenerateAssemblyInfo>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<PlatformTarget>x64</PlatformTarget>
<Version>1.0.0</Version>
<Description>Universal video surveillance client with configurable servers</Description>
<UseWindowsForms>True</UseWindowsForms>
</PropertyGroup>
<PropertyGroup>
<LangVersion>12.0</LangVersion>
@@ -19,6 +18,19 @@
<RootNamespace />
</PropertyGroup>
<!-- Исключаем файлы с Windows Forms -->
<ItemGroup>
<Compile Remove="VideoReader\Form1.cs" />
<Compile Remove="VideoReader\Form1.Designer.cs" />
<Compile Remove="VideoReader\InOutSocket.cs" />
<Compile Remove="VideoReader\Program.cs" />
<Compile Remove="VideoReader\SelectionRangeSlider.cs" />
<Compile Remove="VideoReader\UCPictureBox.cs" />
<Compile Remove="VideoReader\Properties\Settings.cs" />
<Compile Remove="VideoReader\Decoder.cs" />
<Compile Remove="VideoReader\SaveVideo.cs" />
</ItemGroup>
<!-- Внешние библиотеки - используем готовые DLL -->
<ItemGroup>
<Reference Include="FFmpeg.AutoGen">
@@ -47,27 +59,21 @@
</Reference>
</ItemGroup>
<!-- Системные ссылки -->
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Configuration" />
<Reference Include="System.Core" />
<Reference Include="System.Data" />
<Reference Include="System.Drawing" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
</ItemGroup>
<!-- Системные ссылки не нужны - используем NuGet -->
<!-- NuGet пакеты -->
<ItemGroup>
<PackageReference Include="System.Text.Json" Version="6.0.0" />
<PackageReference Include="System.Text.Json" Version="8.0.0" />
<PackageReference Include="System.Drawing.Common" Version="8.0.0" />
</ItemGroup>
<!-- Ресурсы -->
<!-- Ресурсы - отключены для консольной версии -->
<!--
<ItemGroup>
<EmbeddedResource Include="VideoReader.Form1.resx">
<DependentUpon>VideoReader\Form1.cs</DependentUpon>
</EmbeddedResource>
</ItemGroup>
-->
</Project>

View File

@@ -1,128 +0,0 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Text.Json;
namespace VideoReader
{
public class ServerConfig
{
public string SignalingServer { get; set; } = "your-server.com";
public int DataPort { get; set; } = 5000;
public byte DefaultChannel { get; set; } = 10;
public string FallbackIP { get; set; } = "127.0.0.1";
public bool UseSSL { get; set; } = true;
public string ProfileName { get; set; } = "custom";
public Dictionary<string, string> CustomHeaders { get; set; } = new();
public int ConnectionTimeout { get; set; } = 10000;
public bool EnableHeartbeat { get; set; } = true;
public int HeartbeatInterval { get; set; } = 500;
}
public static class ServerConfigManager
{
private static readonly Dictionary<string, ServerConfig> Profiles = new()
{
["standard"] = new ServerConfig
{
SignalingServer = "vidser.top",
DataPort = 3033,
DefaultChannel = 56,
FallbackIP = "158.247.241.191",
UseSSL = true,
ProfileName = "standard"
},
["samsung"] = new ServerConfig
{
SignalingServer = "s1.cc-vst.online",
DataPort = 3234,
DefaultChannel = 44,
FallbackIP = null,
UseSSL = true,
ProfileName = "samsung"
},
["custom"] = new ServerConfig
{
SignalingServer = "your-server.com",
DataPort = 5000,
DefaultChannel = 10,
FallbackIP = "127.0.0.1",
UseSSL = true,
ProfileName = "custom"
},
["local"] = new ServerConfig
{
SignalingServer = "localhost",
DataPort = 8080,
DefaultChannel = 1,
FallbackIP = "127.0.0.1",
UseSSL = false,
ProfileName = "local"
}
};
public static ServerConfig GetProfile(string profileName)
{
return Profiles.TryGetValue(profileName, out var config)
? config
: Profiles["custom"];
}
public static ServerConfig LoadFromFile(string configPath)
{
try
{
if (File.Exists(configPath))
{
var json = File.ReadAllText(configPath);
return JsonSerializer.Deserialize<ServerConfig>(json) ?? Profiles["custom"];
}
}
catch (Exception ex)
{
Console.WriteLine($"Error loading config: {ex.Message}");
}
return Profiles["custom"];
}
public static void SaveToFile(ServerConfig config, string configPath)
{
try
{
var json = JsonSerializer.Serialize(config, new JsonSerializerOptions
{
WriteIndented = true
});
File.WriteAllText(configPath, json);
}
catch (Exception ex)
{
Console.WriteLine($"Error saving config: {ex.Message}");
}
}
public static List<string> GetAvailableProfiles()
{
return new List<string>(Profiles.Keys);
}
public static ServerConfig GetDefault()
{
// Приоритет: файл конфигурации -> переменная окружения -> custom профиль
var configFile = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "server-config.json");
if (File.Exists(configFile))
{
return LoadFromFile(configFile);
}
var envProfile = Environment.GetEnvironmentVariable("VIDEOREADER_PROFILE");
if (!string.IsNullOrEmpty(envProfile) && Profiles.ContainsKey(envProfile))
{
return Profiles[envProfile];
}
return Profiles["custom"];
}
}
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,172 @@
{
"runtimeTarget": {
"name": ".NETCoreApp,Version=v8.0",
"signature": ""
},
"compilationOptions": {},
"targets": {
".NETCoreApp,Version=v8.0": {
"VideoReader-Global/1.0.0": {
"dependencies": {
"System.Drawing.Common": "8.0.0",
"System.Text.Json": "8.0.0",
"AForge": "2.2.5.0",
"AForge.Imaging": "2.2.5.0",
"AForge.Math": "2.2.5.0",
"BouncyCastle.Crypto": "1.8.5.0",
"FFmpeg.AutoGen": "1.2.0.0",
"MessagingToolkit.QRCode": "1.0.3541.23206"
},
"runtime": {
"VideoReader-Global.dll": {}
}
},
"Microsoft.Win32.SystemEvents/8.0.0": {
"runtime": {
"lib/net8.0/Microsoft.Win32.SystemEvents.dll": {
"assemblyVersion": "8.0.0.0",
"fileVersion": "8.0.23.53103"
}
},
"runtimeTargets": {
"runtimes/win/lib/net8.0/Microsoft.Win32.SystemEvents.dll": {
"rid": "win",
"assetType": "runtime",
"assemblyVersion": "8.0.0.0",
"fileVersion": "8.0.23.53103"
}
}
},
"System.Drawing.Common/8.0.0": {
"dependencies": {
"Microsoft.Win32.SystemEvents": "8.0.0"
},
"runtime": {
"lib/net8.0/System.Drawing.Common.dll": {
"assemblyVersion": "8.0.0.0",
"fileVersion": "8.0.23.53105"
}
}
},
"System.Text.Encodings.Web/8.0.0": {},
"System.Text.Json/8.0.0": {
"dependencies": {
"System.Text.Encodings.Web": "8.0.0"
}
},
"AForge/2.2.5.0": {
"runtime": {
"AForge.dll": {
"assemblyVersion": "2.2.5.0",
"fileVersion": "2.2.5.0"
}
}
},
"AForge.Imaging/2.2.5.0": {
"runtime": {
"AForge.Imaging.dll": {
"assemblyVersion": "2.2.5.0",
"fileVersion": "2.2.5.0"
}
}
},
"AForge.Math/2.2.5.0": {
"runtime": {
"AForge.Math.dll": {
"assemblyVersion": "2.2.5.0",
"fileVersion": "2.2.5.0"
}
}
},
"BouncyCastle.Crypto/1.8.5.0": {
"runtime": {
"BouncyCastle.Crypto.dll": {
"assemblyVersion": "1.8.5.0",
"fileVersion": "1.8.19031.1"
}
}
},
"FFmpeg.AutoGen/1.2.0.0": {
"runtime": {
"FFmpeg.AutoGen.dll": {
"assemblyVersion": "1.2.0.0",
"fileVersion": "1.2.0.0"
}
}
},
"MessagingToolkit.QRCode/1.0.3541.23206": {
"runtime": {
"MessagingToolkit.QRCode.dll": {
"assemblyVersion": "1.0.3541.23206",
"fileVersion": "0.0.0.0"
}
}
}
}
},
"libraries": {
"VideoReader-Global/1.0.0": {
"type": "project",
"serviceable": false,
"sha512": ""
},
"Microsoft.Win32.SystemEvents/8.0.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-9opKRyOKMCi2xJ7Bj7kxtZ1r9vbzosMvRrdEhVhDz8j8MoBGgB+WmC94yH839NPH+BclAjtQ/pyagvi/8gDLkw==",
"path": "microsoft.win32.systemevents/8.0.0",
"hashPath": "microsoft.win32.systemevents.8.0.0.nupkg.sha512"
},
"System.Drawing.Common/8.0.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-JkbHJjtI/dWc5dfmEdJlbe3VwgZqCkZRtfuWFh5GOv0f+gGCfBtzMpIVkmdkj2AObO9y+oiOi81UGwH3aBYuqA==",
"path": "system.drawing.common/8.0.0",
"hashPath": "system.drawing.common.8.0.0.nupkg.sha512"
},
"System.Text.Encodings.Web/8.0.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-yev/k9GHAEGx2Rg3/tU6MQh4HGBXJs70y7j1LaM1i/ER9po+6nnQ6RRqTJn1E7Xu0fbIFK80Nh5EoODxrbxwBQ==",
"path": "system.text.encodings.web/8.0.0",
"hashPath": "system.text.encodings.web.8.0.0.nupkg.sha512"
},
"System.Text.Json/8.0.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-OdrZO2WjkiEG6ajEFRABTRCi/wuXQPxeV6g8xvUJqdxMvvuCCEk86zPla8UiIQJz3durtUEbNyY/3lIhS0yZvQ==",
"path": "system.text.json/8.0.0",
"hashPath": "system.text.json.8.0.0.nupkg.sha512"
},
"AForge/2.2.5.0": {
"type": "reference",
"serviceable": false,
"sha512": ""
},
"AForge.Imaging/2.2.5.0": {
"type": "reference",
"serviceable": false,
"sha512": ""
},
"AForge.Math/2.2.5.0": {
"type": "reference",
"serviceable": false,
"sha512": ""
},
"BouncyCastle.Crypto/1.8.5.0": {
"type": "reference",
"serviceable": false,
"sha512": ""
},
"FFmpeg.AutoGen/1.2.0.0": {
"type": "reference",
"serviceable": false,
"sha512": ""
},
"MessagingToolkit.QRCode/1.0.3541.23206": {
"type": "reference",
"serviceable": false,
"sha512": ""
}
}
}

Binary file not shown.

View File

@@ -0,0 +1,13 @@
{
"runtimeOptions": {
"tfm": "net8.0",
"framework": {
"name": "Microsoft.NETCore.App",
"version": "8.0.0"
},
"configProperties": {
"System.Reflection.Metadata.MetadataUpdater.IsSupported": false,
"System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization": false
}
}
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More