feat: 添加便携模式和打包脚本,精简打包大小

This commit is contained in:
2026-01-17 17:58:37 +08:00
parent c276e9e2b9
commit b0e785bd06
8 changed files with 332 additions and 20 deletions

View File

@@ -2,7 +2,6 @@ using System;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
using Windows.Media.Control;
namespace TimerApp
{
@@ -80,18 +79,8 @@ namespace TimerApp
bool playing = false;
try
{
var sessionManager = await GlobalSystemMediaTransportControlsSessionManager.RequestAsync();
var sessions = sessionManager.GetSessions();
foreach (var session in sessions)
{
var playbackInfo = session.GetPlaybackInfo();
if (playbackInfo.PlaybackStatus == GlobalSystemMediaTransportControlsSessionPlaybackStatus.Playing)
{
playing = true;
break;
}
}
await Task.Yield();
playing = TryIsAudioPlaying();
}
catch
{
@@ -105,5 +94,166 @@ namespace TimerApp
}
});
}
private static bool TryIsAudioPlaying()
{
object? deviceEnumeratorObj = null;
IMMDeviceEnumerator? deviceEnumerator = null;
IMMDevice? device = null;
object? sessionManagerObj = null;
IAudioSessionManager2? sessionManager = null;
IAudioSessionEnumerator? sessionEnumerator = null;
try
{
Type? enumeratorType = Type.GetTypeFromCLSID(CLSID_MMDeviceEnumerator);
if (enumeratorType is null)
return false;
deviceEnumeratorObj = Activator.CreateInstance(enumeratorType);
if (deviceEnumeratorObj is null)
return false;
deviceEnumerator = (IMMDeviceEnumerator)deviceEnumeratorObj;
Marshal.ThrowExceptionForHR(deviceEnumerator.GetDefaultAudioEndpoint(EDataFlow.eRender, ERole.eMultimedia, out device));
Guid iid = typeof(IAudioSessionManager2).GUID;
Marshal.ThrowExceptionForHR(device.Activate(ref iid, CLSCTX.CLSCTX_ALL, IntPtr.Zero, out sessionManagerObj));
if (sessionManagerObj is null)
return false;
sessionManager = (IAudioSessionManager2)sessionManagerObj;
Marshal.ThrowExceptionForHR(sessionManager.GetSessionEnumerator(out sessionEnumerator));
Marshal.ThrowExceptionForHR(sessionEnumerator.GetCount(out int count));
for (int i = 0; i < count; i++)
{
Marshal.ThrowExceptionForHR(sessionEnumerator.GetSession(i, out IAudioSessionControl? sessionControl));
if (sessionControl is null)
continue;
try
{
Marshal.ThrowExceptionForHR(sessionControl.GetState(out AudioSessionState state));
if (state != AudioSessionState.Active)
continue;
if (sessionControl is IAudioMeterInformation meter)
{
Marshal.ThrowExceptionForHR(meter.GetPeakValue(out float peak));
if (peak > 0.001f)
return true;
}
else
{
return true;
}
}
finally
{
Marshal.FinalReleaseComObject(sessionControl);
}
}
return false;
}
catch
{
return false;
}
finally
{
if (sessionEnumerator is not null) Marshal.FinalReleaseComObject(sessionEnumerator);
if (sessionManagerObj is not null) Marshal.FinalReleaseComObject(sessionManagerObj);
if (device is not null) Marshal.FinalReleaseComObject(device);
if (deviceEnumeratorObj is not null) Marshal.FinalReleaseComObject(deviceEnumeratorObj);
}
}
private static readonly Guid CLSID_MMDeviceEnumerator = new Guid("BCDE0395-E52F-467C-8E3D-C4579291692E");
private enum EDataFlow
{
eRender = 0,
eCapture = 1,
eAll = 2
}
private enum ERole
{
eConsole = 0,
eMultimedia = 1,
eCommunications = 2
}
private enum AudioSessionState
{
Inactive = 0,
Active = 1,
Expired = 2
}
[Flags]
private enum CLSCTX : uint
{
CLSCTX_INPROC_SERVER = 0x1,
CLSCTX_INPROC_HANDLER = 0x2,
CLSCTX_LOCAL_SERVER = 0x4,
CLSCTX_REMOTE_SERVER = 0x10,
CLSCTX_ALL = CLSCTX_INPROC_SERVER | CLSCTX_INPROC_HANDLER | CLSCTX_LOCAL_SERVER | CLSCTX_REMOTE_SERVER
}
[ComImport]
[Guid("A95664D2-9614-4F35-A746-DE8DB63617E6")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
private interface IMMDeviceEnumerator
{
int NotImpl1();
int GetDefaultAudioEndpoint(EDataFlow dataFlow, ERole role, out IMMDevice ppDevice);
}
[ComImport]
[Guid("D666063F-1587-4E43-81F1-B948E807363F")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
private interface IMMDevice
{
int Activate(ref Guid iid, CLSCTX dwClsCtx, IntPtr pActivationParams, [MarshalAs(UnmanagedType.IUnknown)] out object ppInterface);
}
[ComImport]
[Guid("77AA99A0-1BD6-484F-8BC7-2C654C9A9B6F")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
private interface IAudioSessionManager2
{
int NotImpl1();
int NotImpl2();
int GetSessionEnumerator(out IAudioSessionEnumerator sessionEnum);
}
[ComImport]
[Guid("E2F5BB11-0570-40CA-ACDD-3AA01277DEE8")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
private interface IAudioSessionEnumerator
{
int GetCount(out int sessionCount);
int GetSession(int sessionCount, out IAudioSessionControl session);
}
[ComImport]
[Guid("F4B1A599-7266-4319-A8CA-E70ACB11E8CD")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
private interface IAudioSessionControl
{
int NotImpl1();
int GetState(out AudioSessionState state);
}
[ComImport]
[Guid("C02216F6-8C67-4B5B-9D00-D008E73E0064")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
private interface IAudioMeterInformation
{
int GetPeakValue(out float peak);
}
}
}