Skip to content

Commit 1db32ca

Browse files
committed
improvements to media states
added WindowsInfo module with dimming and lock states
1 parent fb050b8 commit 1db32ca

5 files changed

Lines changed: 138 additions & 22 deletions

File tree

Artemis.MediaInfo/Artemis.MediaInfo.csproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@
66
</PropertyGroup>
77

88
<ItemGroup>
9+
<PackageReference Include="Microsoft.Windows.Compatibility" Version="6.0.0" />
910
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
11+
<PackageReference Include="Serilog" Version="2.12.0" />
1012
<PackageReference Include="SkiaSharp" Version="2.88.1-preview.1" />
1113

1214
<PackageReference Update="@(PackageReference)" IncludeAssets="compile;build" />
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
using Artemis.Core.Modules;
2+
3+
namespace Artemis.MediaInfo.DataModels;
4+
5+
public class WindowsInfoDataModel : DataModel
6+
{
7+
[DataModelProperty(Name = "Session Is Locked")]
8+
public bool SessionLocked { get; set; }
9+
10+
[DataModelProperty(Name = "Night Lights Enabled")]
11+
public bool NightLightsEnabled { get; set; }
12+
}

Artemis.MediaInfo/MediaInfoModule.cs

Lines changed: 37 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,13 @@
55
using Artemis.MediaInfo.DataModels;
66
using WindowsMediaController;
77
using System;
8-
using System.Text;
98
using System.Threading.Tasks;
10-
using System.Windows;
119
using Windows.Media;
1210
using Windows.Storage.Streams;
1311
using SkiaSharp;
1412
using Artemis.Core.Services;
1513
using Windows.Media.Control;
14+
using static WindowsMediaController.MediaManager;
1615

1716
namespace Artemis.MediaInfo
1817
{
@@ -24,8 +23,8 @@ public class MediaInfoModule : Module<MediaInfoDataModel>
2423

2524
public override List<IModuleActivationRequirement> ActivationRequirements { get; } = new();
2625

27-
private readonly HashSet<MediaManager.MediaSession> _mediaSessions = new(new MediaSessionComparer());
28-
private readonly HashSet<MediaManager.MediaSession> _albumArtSessions = new(new MediaSessionComparer());
26+
private readonly HashSet<MediaSession> _mediaSessions = new(new MediaSessionComparer());
27+
private readonly HashSet<MediaSession> _albumArtSessions = new(new MediaSessionComparer());
2928

3029
public MediaInfoModule(IColorQuantizerService colorQuantizerService)
3130
{
@@ -46,9 +45,17 @@ public override void Enable()
4645
if (!DataModel.HasMedia) return;
4746

4847
_mediaSessions.Clear();
48+
_albumArtSessions.Clear();
4949
foreach (var (_, mediaSession) in _mediaManager.CurrentMediaSessions)
5050
{
5151
_mediaSessions.Add(mediaSession);
52+
mediaSession.ControlSession.TryGetMediaPropertiesAsync().AsTask().ContinueWith(task =>
53+
{
54+
if (task.Result.Thumbnail != null)
55+
{
56+
_albumArtSessions.Add(mediaSession);
57+
}
58+
});
5259
}
5360

5461
DataModel.MediaSessions = _mediaSessions; //debug
@@ -75,21 +82,23 @@ public override void Update(double deltaTime) {}
7582
public override void ModuleActivated(bool isOverride) {}
7683
public override void ModuleDeactivated(bool isOverride) {}
7784

78-
private void MediaManager_OnSessionOpened(MediaManager.MediaSession mediaSession)
85+
private void MediaManager_OnSessionOpened(MediaSession mediaSession)
7986
{
8087
DataModel.HasMedia = true;
8188
_mediaSessions.Add(mediaSession);
89+
90+
UpdateButtons();
8291
}
8392

84-
private void MediaManager_OnAnySessionClosed(MediaManager.MediaSession mediaSession)
93+
private void MediaManager_OnAnySessionClosed(MediaSession mediaSession)
8594
{
8695
_mediaSessions.Remove(mediaSession);
8796
_albumArtSessions.Remove(mediaSession);
8897

8998
UpdateButtons();
9099
}
91100

92-
private async void MediaManager_OnAnyMediaPropertyChanged(MediaManager.MediaSession mediaSession,
101+
private async void MediaManager_OnAnyMediaPropertyChanged(MediaSession mediaSession,
93102
GlobalSystemMediaTransportControlsSessionMediaProperties mediaProperties)
94103
{
95104
DataModel.MediaChanged.Trigger(new MediaChangedEventArgs
@@ -110,16 +119,7 @@ private async void MediaManager_OnAnyMediaPropertyChanged(MediaManager.MediaSess
110119
return;
111120
}
112121

113-
var imageStream = await mediaProperties.Thumbnail.OpenReadAsync();
114-
var fileBytes = new byte[imageStream.Size];
115-
116-
using DataReader reader = new DataReader(imageStream);
117-
await reader.LoadAsync((uint)imageStream.Size);
118-
reader.ReadBytes(fileBytes);
119-
120-
using SKBitmap skbm = SKBitmap.Decode(fileBytes);
121-
SKColor[] skClrs = _colorQuantizer.Quantize(skbm.Pixels, 256);
122-
DataModel.ArtColors = _colorQuantizer.FindAllColorVariations(skClrs, true);
122+
DataModel.ArtColors = await ReadMediaColors(mediaProperties);
123123
DataModel.HasArt = true;
124124
_albumArtSessions.Add(mediaSession);
125125
}
@@ -131,7 +131,23 @@ private async void MediaManager_OnAnyMediaPropertyChanged(MediaManager.MediaSess
131131
}
132132
}
133133

134-
private void MediaManager_OnAnyPlaybackStateChanged(MediaManager.MediaSession mediaSession,
134+
private async Task<ColorSwatch> ReadMediaColors(GlobalSystemMediaTransportControlsSessionMediaProperties mediaProperties)
135+
{
136+
var imageStream = await mediaProperties.Thumbnail.OpenReadAsync();
137+
var fileBytes = new byte[imageStream.Size];
138+
139+
using (var reader = new DataReader(imageStream))
140+
{
141+
await reader.LoadAsync((uint)imageStream.Size);
142+
reader.ReadBytes(fileBytes);
143+
}
144+
145+
using SKBitmap bitmap = SKBitmap.Decode(fileBytes);
146+
SKColor[] skClrs = _colorQuantizer.Quantize(bitmap.Pixels, 256);
147+
return _colorQuantizer.FindAllColorVariations(skClrs, true);;
148+
}
149+
150+
private void MediaManager_OnAnyPlaybackStateChanged(MediaSession mediaSession,
135151
GlobalSystemMediaTransportControlsSessionPlaybackInfo playbackInfo)
136152
{
137153
UpdateButtons();
@@ -151,14 +167,14 @@ private void UpdateButtons()
151167
DataModel.HasArt = _albumArtSessions.Count > 0;
152168
}
153169

154-
private class MediaSessionComparer : IEqualityComparer<MediaManager.MediaSession>
170+
private class MediaSessionComparer : IEqualityComparer<MediaSession>
155171
{
156-
public bool Equals(MediaManager.MediaSession x, MediaManager.MediaSession y)
172+
public bool Equals(MediaSession x, MediaSession y)
157173
{
158174
return x?.Id == y?.Id;
159175
}
160176

161-
public int GetHashCode(MediaManager.MediaSession obj)
177+
public int GetHashCode(MediaSession obj)
162178
{
163179
return obj.Id.GetHashCode();
164180
}
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
using System.Collections.Generic;
2+
using System.Management;
3+
using System.Security.Principal;
4+
using Artemis.Core.Modules;
5+
using Artemis.MediaInfo.DataModels;
6+
using Microsoft.Win32;
7+
8+
namespace Artemis.MediaInfo;
9+
10+
public class WindowsInfoModule: Module<WindowsInfoDataModel>
11+
{
12+
private const string BlueLightReductionStateKey = @"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\CloudStore\\" +
13+
@"Store\\DefaultAccount\\Current\\default$windows.data.bluelightreduction.bluelightreductionstate\\" +
14+
@"windows.data.bluelightreduction.bluelightreductionstate";
15+
16+
private ManagementEventWatcher _nightLightStateWatcher;
17+
18+
public override void Enable()
19+
{
20+
StartListenNightLight();
21+
UpdateNightLight();
22+
StartListenLockState();
23+
}
24+
25+
public override void Disable()
26+
{
27+
_nightLightStateWatcher.EventArrived -= _nightLightStateWatcher_Changed;
28+
_nightLightStateWatcher.Stop();
29+
_nightLightStateWatcher.Dispose();
30+
_nightLightStateWatcher = null;
31+
SystemEvents.SessionSwitch -= OnSessionSwitch;
32+
}
33+
34+
public override void Update(double deltaTime)
35+
{
36+
}
37+
38+
public override List<IModuleActivationRequirement> ActivationRequirements { get; } = new();
39+
40+
private void StartListenLockState()
41+
{
42+
SystemEvents.SessionSwitch += OnSessionSwitch;
43+
}
44+
45+
private void OnSessionSwitch(object sender, SessionSwitchEventArgs e)
46+
{
47+
DataModel.SessionLocked = e.Reason switch
48+
{
49+
SessionSwitchReason.SessionLock => true,
50+
SessionSwitchReason.SessionUnlock => false,
51+
_ => DataModel.SessionLocked
52+
};
53+
}
54+
55+
private void StartListenNightLight()
56+
{
57+
var currentUser = WindowsIdentity.GetCurrent();
58+
ManagementScope scope = new ManagementScope("\\\\.\\root\\default");
59+
var quertString = string.Format(
60+
"SELECT * FROM RegistryValueChangeEvent WHERE Hive='HKEY_USERS' AND KeyPath='{0}\\\\{1}' AND ValueName='{2}'",
61+
currentUser.User.Value, BlueLightReductionStateKey.Replace("\\", "\\\\"), "Data");
62+
var query = new WqlEventQuery(quertString);
63+
_nightLightStateWatcher = new ManagementEventWatcher(scope, query);
64+
_nightLightStateWatcher.EventArrived += _nightLightStateWatcher_Changed;
65+
_nightLightStateWatcher.Start();
66+
}
67+
68+
private void _nightLightStateWatcher_Changed(object sender, EventArrivedEventArgs e)
69+
{
70+
UpdateNightLight();
71+
}
72+
73+
private void UpdateNightLight()
74+
{
75+
using var key = Registry.CurrentUser.OpenSubKey(BlueLightReductionStateKey);
76+
var data = key?.GetValue("Data");
77+
if (data is null)
78+
{
79+
DataModel.NightLightsEnabled = false;
80+
return;
81+
}
82+
83+
var byteData = (byte[]) data;
84+
DataModel.NightLightsEnabled = byteData.Length > 24 && byteData[23] == 0x10 && byteData[24] == 0x00;
85+
}
86+
}

Artemis.MediaInfo/plugin.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,6 @@
66
"Main": "Artemis.MediaInfo.dll",
77
"Name": "Media Info",
88
"Repository": "https://github.com/Aytackydln/Artemis.MediaInfo",
9-
"Version": "0.0.4.1",
9+
"Version": "0.0.5.0",
1010
"Platforms":"Windows"
1111
}

0 commit comments

Comments
 (0)