diff --git a/HttpKeys/App.xaml.cs b/HttpKeys/App.xaml.cs
index f0e5026..6a1f0a6 100644
--- a/HttpKeys/App.xaml.cs
+++ b/HttpKeys/App.xaml.cs
@@ -1,22 +1,78 @@
using System.Windows;
+using NAudio.CoreAudioApi;
using Application = System.Windows.Application;
namespace HttpKeys;
+[Flags]
+public enum MicMode
+{
+ None = 0,
+ Any = 1 << 0,
+ Ts = 1 << 1,
+}
+
///
/// Interaction logic for App.xaml
///
public partial class App : Application
{
+ private Dictionary _trayIcons = new();
+
private NotifyIcon _trayIcon;
+
+ private const string TsDeviceId =
+ "{0.0.1.00000000}.{cf287ff4-c39e-4b09-bc8d-b927c7d59779}";
+ public void UpdateIcon()
+ {
+ using var enumerator = new MMDeviceEnumerator();
+
+ var devices = enumerator
+ .EnumerateAudioEndPoints(DataFlow.Capture, DeviceState.Active)
+ .Select(d => new
+ {
+ Id = d.ID,
+ Muted = d.AudioEndpointVolume.Mute
+ })
+ .ToList();
+
+ if (devices.Count == 0)
+ {
+ _trayIcon.Icon = _trayIcons[MicMode.None];
+ return;
+ }
+
+ bool tsMuted = devices.Any(x =>
+ string.Equals(x.Id, TsDeviceId, StringComparison.OrdinalIgnoreCase) && x.Muted);
+
+ bool anyMuted = devices.Any(x =>
+ !string.Equals(x.Id, TsDeviceId, StringComparison.OrdinalIgnoreCase) && x.Muted);
+
+ MicMode mode = MicMode.None;
+
+ if (tsMuted)
+ mode |= MicMode.Ts;
+
+ if (anyMuted)
+ mode |= MicMode.Any;
+
+
+ _trayIcon.Icon = _trayIcons[mode];
+ }
+
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
+
+ _trayIcons.Add(MicMode.Ts | MicMode.Any, new Icon("micro_off.ico"));
+ _trayIcons.Add(MicMode.None, new Icon("micro_on.ico"));
+ _trayIcons.Add(MicMode.Ts, new Icon("micro_ts.ico"));
+ _trayIcons.Add(MicMode.Any, new Icon("micro_any.ico"));
_trayIcon = new NotifyIcon
{
- Icon = new System.Drawing.Icon("app.ico"),
+ Icon = _trayIcons[MicMode.None],
Visible = true,
Text = "My WPF Tray App"
};
diff --git a/HttpKeys/HttpKeys.csproj b/HttpKeys/HttpKeys.csproj
index 9b070f9..b05d2cb 100644
--- a/HttpKeys/HttpKeys.csproj
+++ b/HttpKeys/HttpKeys.csproj
@@ -13,6 +13,22 @@
PreserveNewest
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+
+
+
diff --git a/HttpKeys/Listener.cs b/HttpKeys/Listener.cs
index 8e5933f..0d86923 100644
--- a/HttpKeys/Listener.cs
+++ b/HttpKeys/Listener.cs
@@ -9,7 +9,7 @@ namespace HttpKeys;
class Params
{
public string ActionId { get; set; } = null!;
- public string State { get; set; } = null!;
+ public bool IsOn { get; set; }
public bool ToggleChanged { get; set; }
}
@@ -52,22 +52,34 @@ public class Listener
var p = JsonSerializer.Deserialize(body, options);
if (p == null)
continue;
+
+ Log(body);
+
- Log("---- REQUEST ----");
- Log("URL: " + p.ActionId);
- Log("URL: " + p.State);
- Log("URL: " + p.ToggleChanged);
+ if(p.ActionId == "globalmute")
+ MicController.ToggleAllMicsSimple(p.IsOn);
- var responseBytes = "OK"u8.ToArray();
- ctx.Response.StatusCode = 200;
- ctx.Response.ContentType = "text/plain; charset=utf-8";
- await ctx.Response.OutputStream.WriteAsync(responseBytes);
- ctx.Response.Close();
+ if (p.ActionId == "tsmute")
+ MicController.ToggleTsMicsSimple(p.IsOn);
+
+ await WriteText(ctx, 200, "OK");
}
catch (Exception ex)
{
Log("Error: " + ex.Message);
+ await WriteText(ctx, 500, "Error");
}
}
}
+
+ private static async Task WriteText(HttpListenerContext ctx, int statusCode, string text)
+ {
+ var bytes = Encoding.UTF8.GetBytes(text);
+ ctx.Response.StatusCode = statusCode;
+ ctx.Response.ContentType = "text/plain; charset=utf-8";
+ ctx.Response.ContentLength64 = bytes.Length;
+ await ctx.Response.OutputStream.WriteAsync(bytes, 0, bytes.Length);
+ ctx.Response.OutputStream.Close();
+ ctx.Response.Close();
+ }
}
\ No newline at end of file
diff --git a/HttpKeys/MainWindow.xaml.cs b/HttpKeys/MainWindow.xaml.cs
index 2ff298b..7d1418b 100644
--- a/HttpKeys/MainWindow.xaml.cs
+++ b/HttpKeys/MainWindow.xaml.cs
@@ -1,15 +1,6 @@
using System.Collections.ObjectModel;
using System.ComponentModel;
-using System.Text;
using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Data;
-using System.Windows.Documents;
-using System.Windows.Input;
-using System.Windows.Media;
-using System.Windows.Media.Imaging;
-using System.Windows.Navigation;
-using System.Windows.Shapes;
namespace HttpKeys;
diff --git a/HttpKeys/MicController.cs b/HttpKeys/MicController.cs
new file mode 100644
index 0000000..a993812
--- /dev/null
+++ b/HttpKeys/MicController.cs
@@ -0,0 +1,95 @@
+using NAudio.CoreAudioApi;
+using Application = System.Windows.Application;
+
+namespace HttpKeys;
+
+public static class MicController
+{
+ public static void PrintCaptureDevices()
+ {
+ using var enumerator = new MMDeviceEnumerator();
+ var devices = enumerator.EnumerateAudioEndPoints(DataFlow.Capture, DeviceState.All);
+
+ foreach (var device in devices)
+ {
+ Console.WriteLine("===================================");
+ Console.WriteLine($"Name: {device.FriendlyName}");
+ Console.WriteLine($"ID: {device.ID}");
+ Console.WriteLine($"State:{device.State}");
+ Console.WriteLine();
+ }
+ }
+
+ ///
+ /// Управляет всеми активными микрофонами.
+ /// isOn = true → микрофоны включены (Mute = false)
+ /// isOn = false → микрофоны выключены (Mute = true)
+ ///
+ public static void ToggleAllMicsSimple(bool isOn)
+ {
+ using var enumerator = new MMDeviceEnumerator();
+ var devices = enumerator.EnumerateAudioEndPoints(DataFlow.Capture, DeviceState.Active);
+
+ foreach (var device in devices)
+ {
+ var endpoint = device.AudioEndpointVolume;
+
+ bool shouldBeMuted = !isOn;
+
+ // Если уже в нужном состоянии — ничего не делаем
+ if (endpoint.Mute == shouldBeMuted)
+ continue;
+
+ endpoint.Mute = shouldBeMuted;
+ }
+
+ var app = Application.Current;
+ app.Dispatcher.Invoke(() =>(app as App)?.UpdateIcon());
+ }
+
+ ///
+ /// Управляет конкретным микрофоном по ID.
+ ///
+ public static void ToggleTsMicsSimple(bool isOn)
+ {
+ SetMicStateById(
+ "{0.0.1.00000000}.{cf287ff4-c39e-4b09-bc8d-b927c7d59779}",
+ isOn
+ );
+
+ var app = Application.Current;
+ app.Dispatcher.Invoke(() =>(app as App)?.UpdateIcon());
+ }
+
+ private static void SetMicStateById(string deviceId, bool isOn)
+ {
+ using var enumerator = new MMDeviceEnumerator();
+
+ MMDevice device;
+
+ try
+ {
+ device = enumerator.GetDevice(deviceId);
+ }
+ catch
+ {
+ return;
+ }
+
+ if (device.DataFlow != DataFlow.Capture)
+ return;
+
+ if (device.State != DeviceState.Active)
+ return;
+
+ var endpoint = device.AudioEndpointVolume;
+
+ bool shouldBeMuted = !isOn;
+
+ // Уже в нужном состоянии — выходим
+ if (endpoint.Mute == shouldBeMuted)
+ return;
+
+ endpoint.Mute = shouldBeMuted;
+ }
+}
\ No newline at end of file
diff --git a/HttpKeys/micro_any.ico b/HttpKeys/micro_any.ico
new file mode 100644
index 0000000..cd4bfc8
Binary files /dev/null and b/HttpKeys/micro_any.ico differ
diff --git a/HttpKeys/micro_off.ico b/HttpKeys/micro_off.ico
new file mode 100644
index 0000000..a763c39
Binary files /dev/null and b/HttpKeys/micro_off.ico differ
diff --git a/HttpKeys/micro_on.ico b/HttpKeys/micro_on.ico
new file mode 100644
index 0000000..85cc1a3
Binary files /dev/null and b/HttpKeys/micro_on.ico differ
diff --git a/HttpKeys/micro_ts.ico b/HttpKeys/micro_ts.ico
new file mode 100644
index 0000000..0a351e0
Binary files /dev/null and b/HttpKeys/micro_ts.ico differ
diff --git a/Plugin/ru.wildtail.httpkeys.sdPlugin/icons/DiscordMute.png b/Plugin/ru.wildtail.httpkeys.sdPlugin/icons/DiscordMute.png
deleted file mode 100644
index 3410ca1..0000000
Binary files a/Plugin/ru.wildtail.httpkeys.sdPlugin/icons/DiscordMute.png and /dev/null differ
diff --git a/Plugin/ru.wildtail.httpkeys.sdPlugin/icons/DiscordMuteMicro.png b/Plugin/ru.wildtail.httpkeys.sdPlugin/icons/DiscordMuteMicro.png
deleted file mode 100644
index 617a2a4..0000000
Binary files a/Plugin/ru.wildtail.httpkeys.sdPlugin/icons/DiscordMuteMicro.png and /dev/null differ
diff --git a/Plugin/ru.wildtail.httpkeys.sdPlugin/icons/DiscordUnmute.png b/Plugin/ru.wildtail.httpkeys.sdPlugin/icons/DiscordUnmute.png
deleted file mode 100644
index 1b0dccd..0000000
Binary files a/Plugin/ru.wildtail.httpkeys.sdPlugin/icons/DiscordUnmute.png and /dev/null differ
diff --git a/Plugin/ru.wildtail.httpkeys.sdPlugin/icons/DiscordUnmuteMicro.png b/Plugin/ru.wildtail.httpkeys.sdPlugin/icons/DiscordUnmuteMicro.png
deleted file mode 100644
index 83f5043..0000000
Binary files a/Plugin/ru.wildtail.httpkeys.sdPlugin/icons/DiscordUnmuteMicro.png and /dev/null differ
diff --git a/Plugin/ru.wildtail.httpkeys.sdPlugin/icons/SystemMuteMicro.png b/Plugin/ru.wildtail.httpkeys.sdPlugin/icons/SystemMuteMicro.png
deleted file mode 100644
index f2dd086..0000000
Binary files a/Plugin/ru.wildtail.httpkeys.sdPlugin/icons/SystemMuteMicro.png and /dev/null differ
diff --git a/Plugin/ru.wildtail.httpkeys.sdPlugin/icons/SystemUnmuteMicro.png b/Plugin/ru.wildtail.httpkeys.sdPlugin/icons/SystemUnmuteMicro.png
deleted file mode 100644
index b1144cb..0000000
Binary files a/Plugin/ru.wildtail.httpkeys.sdPlugin/icons/SystemUnmuteMicro.png and /dev/null differ
diff --git a/Plugin/ru.wildtail.httpkeys.sdPlugin/icons/TalkMuteMicro.png b/Plugin/ru.wildtail.httpkeys.sdPlugin/icons/TalkMuteMicro.png
deleted file mode 100644
index a2bbba6..0000000
Binary files a/Plugin/ru.wildtail.httpkeys.sdPlugin/icons/TalkMuteMicro.png and /dev/null differ
diff --git a/Plugin/ru.wildtail.httpkeys.sdPlugin/icons/TalkUnmuteMicro.png b/Plugin/ru.wildtail.httpkeys.sdPlugin/icons/TalkUnmuteMicro.png
deleted file mode 100644
index f696717..0000000
Binary files a/Plugin/ru.wildtail.httpkeys.sdPlugin/icons/TalkUnmuteMicro.png and /dev/null differ
diff --git a/Plugin/ru.wildtail.httpkeys.sdPlugin/icons/TeamspeakMuteMicro.png b/Plugin/ru.wildtail.httpkeys.sdPlugin/icons/TeamspeakMuteMicro.png
deleted file mode 100644
index ef0eb4e..0000000
Binary files a/Plugin/ru.wildtail.httpkeys.sdPlugin/icons/TeamspeakMuteMicro.png and /dev/null differ
diff --git a/Plugin/ru.wildtail.httpkeys.sdPlugin/icons/TeamspeakUnmuteMicro.png b/Plugin/ru.wildtail.httpkeys.sdPlugin/icons/TeamspeakUnmuteMicro.png
deleted file mode 100644
index 9a5c4b2..0000000
Binary files a/Plugin/ru.wildtail.httpkeys.sdPlugin/icons/TeamspeakUnmuteMicro.png and /dev/null differ
diff --git a/Plugin/ru.wildtail.httpkeys.sdPlugin/main.js b/Plugin/ru.wildtail.httpkeys.sdPlugin/main.js
index 3e46681..c585081 100644
--- a/Plugin/ru.wildtail.httpkeys.sdPlugin/main.js
+++ b/Plugin/ru.wildtail.httpkeys.sdPlugin/main.js
@@ -3,21 +3,12 @@ let uuid = null;
let ctxSettings = new Map();
const ACTION_MAP = {
- "ru.wildtail.httpkeys.discord_micro_mute": {
- actionId: "discord_micro_mute"
+ "ru.wildtail.httpkeys.globalmute": {
+ actionId: "globalmute"
},
- "ru.wildtail.httpkeys.discord_mute": {
- actionId: "discord_mute"
+ "ru.wildtail.httpkeys.tsmute": {
+ actionId: "tsmute"
},
- "ru.wildtail.httpkeys.teamspeak_micro_mute": {
- actionId: "teamspeak_micro_mute"
- },
- "ru.wildtail.httpkeys.talk_micro_mute": {
- actionId: "talk_micro_mute"
- },
- "ru.wildtail.httpkeys.system_micro_mute": {
- actionId: "system_micro_mute"
- }
};
// подключение от D6
@@ -42,6 +33,17 @@ function connectElgatoStreamDeckSocket(inPort, inUUID, inRegisterEvent, inInfo)
const s = (payload && payload.settings) || { isOn: false };
ctxSettings.set(context, s);
setState(context, s.isOn ? 1 : 0);
+
+ const cfg = ACTION_MAP[action];
+ if (!cfg) return;
+
+ post("http://127.0.0.1:16888/press", {
+ actionUUID: action,
+ actionId: cfg.actionId,
+ toggleChanged: false,
+ isOn: !s.isOn,
+ });
+
return;
}
@@ -84,13 +86,8 @@ function handleKeyDown(action, context) {
post("http://127.0.0.1:16888/press", {
actionUUID: action,
actionId: cfg.actionId,
-
toggleChanged: prevState !== newState,
- state: newState ? "on" : "off",
-
- isOn: newState,
- context: context,
- timestamp: Date.now()
+ isOn: !newState,
});
}
diff --git a/Plugin/ru.wildtail.httpkeys.sdPlugin/manifest.json b/Plugin/ru.wildtail.httpkeys.sdPlugin/manifest.json
index 7ec115e..3c1837f 100644
--- a/Plugin/ru.wildtail.httpkeys.sdPlugin/manifest.json
+++ b/Plugin/ru.wildtail.httpkeys.sdPlugin/manifest.json
@@ -15,99 +15,38 @@
"Actions": [
{
- "Name": "Discord Mute Micro",
- "UUID": "ru.wildtail.httpkeys.discord_micro_mute",
+ "Name": "Global Mute Micro",
+ "UUID": "ru.wildtail.httpkeys.globalmute",
"Icon": "icon",
- "Tooltip": "Toggle Discord Mute Micro",
+ "Tooltip": "Global Mute Micro",
"PropertyInspectorPath": "index.html",
"States": [
{
- "Image": "icons/DiscordUnmuteMicro",
+ "Image": "icons/micro_on",
"TitleAlignment": "middle",
"FontSize": "12"
},
{
- "Image": "icons/DiscordMuteMicro",
+ "Image": "icons/micro_off",
"TitleAlignment": "middle",
"FontSize": "12"
}
]
},
-
- {
- "Name": "Discord Mute",
- "UUID": "ru.wildtail.httpkeys.discord_mute",
- "Icon": "icon",
- "Tooltip": "Toggle Discord Full Mute",
- "PropertyInspectorPath": "index.html",
- "States": [
- {
- "Image": "icons/DiscordUnmute",
- "TitleAlignment": "middle",
- "FontSize": "12"
- },
- {
- "Image": "icons/DiscordMute",
- "TitleAlignment": "middle",
- "FontSize": "12"
- }
- ]
- },
-
{
- "Name": "Teamspeak Mute Micro",
- "UUID": "ru.wildtail.httpkeys.teamspeak_micro_mute",
+ "Name": "Teamspeacks Mute Micro",
+ "UUID": "ru.wildtail.httpkeys.tsmute",
"Icon": "icon",
- "Tooltip": "Toggle Teamspeak Mute Micro",
+ "Tooltip": "Teamspeacks Mute Micro",
"PropertyInspectorPath": "index.html",
"States": [
{
- "Image": "icons/TeamspeakUnmuteMicro",
+ "Image": "icons/groupmicro_on",
"TitleAlignment": "middle",
"FontSize": "12"
},
{
- "Image": "icons/TeamspeakMuteMicro",
- "TitleAlignment": "middle",
- "FontSize": "12"
- }
- ]
- },
-
- {
- "Name": "Talk Mute Micro",
- "UUID": "ru.wildtail.httpkeys.talk_micro_mute",
- "Icon": "icon",
- "Tooltip": "Toggle Talk Mute",
- "PropertyInspectorPath": "index.html",
- "States": [
- {
- "Image": "icons/TalkUnmuteMicro",
- "TitleAlignment": "middle",
- "FontSize": "12"
- },
- {
- "Image": "icons/TalkMuteMicro",
- "TitleAlignment": "middle",
- "FontSize": "12"
- }
- ]
- },
-
- {
- "Name": "System Mute Micro",
- "UUID": "ru.wildtail.httpkeys.system_micro_mute",
- "Icon": "icon",
- "Tooltip": "Toggle System Mute Micro",
- "PropertyInspectorPath": "index.html",
- "States": [
- {
- "Image": "icons/SystemUnmuteMicro",
- "TitleAlignment": "middle",
- "FontSize": "12"
- },
- {
- "Image": "icons/SystemMuteMicro",
+ "Image": "icons/groupmicro_off",
"TitleAlignment": "middle",
"FontSize": "12"
}