Skip to content

Commit

Permalink
improvements to media states
Browse files Browse the repository at this point in the history
added WindowsInfo module with dimming and lock states
  • Loading branch information
Aytackydln committed Sep 15, 2022
1 parent fb050b8 commit 1db32ca
Show file tree
Hide file tree
Showing 5 changed files with 138 additions and 22 deletions.
2 changes: 2 additions & 0 deletions Artemis.MediaInfo/Artemis.MediaInfo.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Windows.Compatibility" Version="6.0.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
<PackageReference Include="Serilog" Version="2.12.0" />
<PackageReference Include="SkiaSharp" Version="2.88.1-preview.1" />

<PackageReference Update="@(PackageReference)" IncludeAssets="compile;build" />
Expand Down
12 changes: 12 additions & 0 deletions Artemis.MediaInfo/DataModels/WindowsInfoDataModel.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using Artemis.Core.Modules;

namespace Artemis.MediaInfo.DataModels;

public class WindowsInfoDataModel : DataModel
{
[DataModelProperty(Name = "Session Is Locked")]
public bool SessionLocked { get; set; }

[DataModelProperty(Name = "Night Lights Enabled")]
public bool NightLightsEnabled { get; set; }
}
58 changes: 37 additions & 21 deletions Artemis.MediaInfo/MediaInfoModule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,13 @@
using Artemis.MediaInfo.DataModels;
using WindowsMediaController;
using System;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using Windows.Media;
using Windows.Storage.Streams;
using SkiaSharp;
using Artemis.Core.Services;
using Windows.Media.Control;
using static WindowsMediaController.MediaManager;

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

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

private readonly HashSet<MediaManager.MediaSession> _mediaSessions = new(new MediaSessionComparer());
private readonly HashSet<MediaManager.MediaSession> _albumArtSessions = new(new MediaSessionComparer());
private readonly HashSet<MediaSession> _mediaSessions = new(new MediaSessionComparer());
private readonly HashSet<MediaSession> _albumArtSessions = new(new MediaSessionComparer());

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

_mediaSessions.Clear();
_albumArtSessions.Clear();
foreach (var (_, mediaSession) in _mediaManager.CurrentMediaSessions)
{
_mediaSessions.Add(mediaSession);
mediaSession.ControlSession.TryGetMediaPropertiesAsync().AsTask().ContinueWith(task =>
{
if (task.Result.Thumbnail != null)
{
_albumArtSessions.Add(mediaSession);
}
});
}

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

private void MediaManager_OnSessionOpened(MediaManager.MediaSession mediaSession)
private void MediaManager_OnSessionOpened(MediaSession mediaSession)
{
DataModel.HasMedia = true;
_mediaSessions.Add(mediaSession);

UpdateButtons();
}

private void MediaManager_OnAnySessionClosed(MediaManager.MediaSession mediaSession)
private void MediaManager_OnAnySessionClosed(MediaSession mediaSession)
{
_mediaSessions.Remove(mediaSession);
_albumArtSessions.Remove(mediaSession);

UpdateButtons();
}

private async void MediaManager_OnAnyMediaPropertyChanged(MediaManager.MediaSession mediaSession,
private async void MediaManager_OnAnyMediaPropertyChanged(MediaSession mediaSession,
GlobalSystemMediaTransportControlsSessionMediaProperties mediaProperties)
{
DataModel.MediaChanged.Trigger(new MediaChangedEventArgs
Expand All @@ -110,16 +119,7 @@ private async void MediaManager_OnAnyMediaPropertyChanged(MediaManager.MediaSess
return;
}

var imageStream = await mediaProperties.Thumbnail.OpenReadAsync();
var fileBytes = new byte[imageStream.Size];

using DataReader reader = new DataReader(imageStream);
await reader.LoadAsync((uint)imageStream.Size);
reader.ReadBytes(fileBytes);

using SKBitmap skbm = SKBitmap.Decode(fileBytes);
SKColor[] skClrs = _colorQuantizer.Quantize(skbm.Pixels, 256);
DataModel.ArtColors = _colorQuantizer.FindAllColorVariations(skClrs, true);
DataModel.ArtColors = await ReadMediaColors(mediaProperties);
DataModel.HasArt = true;
_albumArtSessions.Add(mediaSession);
}
Expand All @@ -131,7 +131,23 @@ private async void MediaManager_OnAnyMediaPropertyChanged(MediaManager.MediaSess
}
}

private void MediaManager_OnAnyPlaybackStateChanged(MediaManager.MediaSession mediaSession,
private async Task<ColorSwatch> ReadMediaColors(GlobalSystemMediaTransportControlsSessionMediaProperties mediaProperties)
{
var imageStream = await mediaProperties.Thumbnail.OpenReadAsync();
var fileBytes = new byte[imageStream.Size];

using (var reader = new DataReader(imageStream))
{
await reader.LoadAsync((uint)imageStream.Size);
reader.ReadBytes(fileBytes);
}

using SKBitmap bitmap = SKBitmap.Decode(fileBytes);
SKColor[] skClrs = _colorQuantizer.Quantize(bitmap.Pixels, 256);
return _colorQuantizer.FindAllColorVariations(skClrs, true);;
}

private void MediaManager_OnAnyPlaybackStateChanged(MediaSession mediaSession,
GlobalSystemMediaTransportControlsSessionPlaybackInfo playbackInfo)
{
UpdateButtons();
Expand All @@ -151,14 +167,14 @@ private void UpdateButtons()
DataModel.HasArt = _albumArtSessions.Count > 0;
}

private class MediaSessionComparer : IEqualityComparer<MediaManager.MediaSession>
private class MediaSessionComparer : IEqualityComparer<MediaSession>
{
public bool Equals(MediaManager.MediaSession x, MediaManager.MediaSession y)
public bool Equals(MediaSession x, MediaSession y)
{
return x?.Id == y?.Id;
}

public int GetHashCode(MediaManager.MediaSession obj)
public int GetHashCode(MediaSession obj)
{
return obj.Id.GetHashCode();
}
Expand Down
86 changes: 86 additions & 0 deletions Artemis.MediaInfo/WindowsInfoModule.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
using System.Collections.Generic;
using System.Management;
using System.Security.Principal;
using Artemis.Core.Modules;
using Artemis.MediaInfo.DataModels;
using Microsoft.Win32;

namespace Artemis.MediaInfo;

public class WindowsInfoModule: Module<WindowsInfoDataModel>
{
private const string BlueLightReductionStateKey = @"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\CloudStore\\" +
@"Store\\DefaultAccount\\Current\\default$windows.data.bluelightreduction.bluelightreductionstate\\" +
@"windows.data.bluelightreduction.bluelightreductionstate";

private ManagementEventWatcher _nightLightStateWatcher;

public override void Enable()
{
StartListenNightLight();
UpdateNightLight();
StartListenLockState();
}

public override void Disable()
{
_nightLightStateWatcher.EventArrived -= _nightLightStateWatcher_Changed;
_nightLightStateWatcher.Stop();
_nightLightStateWatcher.Dispose();
_nightLightStateWatcher = null;
SystemEvents.SessionSwitch -= OnSessionSwitch;
}

public override void Update(double deltaTime)
{
}

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

private void StartListenLockState()
{
SystemEvents.SessionSwitch += OnSessionSwitch;
}

private void OnSessionSwitch(object sender, SessionSwitchEventArgs e)
{
DataModel.SessionLocked = e.Reason switch
{
SessionSwitchReason.SessionLock => true,
SessionSwitchReason.SessionUnlock => false,
_ => DataModel.SessionLocked
};
}

private void StartListenNightLight()
{
var currentUser = WindowsIdentity.GetCurrent();
ManagementScope scope = new ManagementScope("\\\\.\\root\\default");
var quertString = string.Format(
"SELECT * FROM RegistryValueChangeEvent WHERE Hive='HKEY_USERS' AND KeyPath='{0}\\\\{1}' AND ValueName='{2}'",
currentUser.User.Value, BlueLightReductionStateKey.Replace("\\", "\\\\"), "Data");
var query = new WqlEventQuery(quertString);
_nightLightStateWatcher = new ManagementEventWatcher(scope, query);
_nightLightStateWatcher.EventArrived += _nightLightStateWatcher_Changed;
_nightLightStateWatcher.Start();
}

private void _nightLightStateWatcher_Changed(object sender, EventArrivedEventArgs e)
{
UpdateNightLight();
}

private void UpdateNightLight()
{
using var key = Registry.CurrentUser.OpenSubKey(BlueLightReductionStateKey);
var data = key?.GetValue("Data");
if (data is null)
{
DataModel.NightLightsEnabled = false;
return;
}

var byteData = (byte[]) data;
DataModel.NightLightsEnabled = byteData.Length > 24 && byteData[23] == 0x10 && byteData[24] == 0x00;
}
}
2 changes: 1 addition & 1 deletion Artemis.MediaInfo/plugin.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@
"Main": "Artemis.MediaInfo.dll",
"Name": "Media Info",
"Repository": "https://github.com/Aytackydln/Artemis.MediaInfo",
"Version": "0.0.4.1",
"Version": "0.0.5.0",
"Platforms":"Windows"
}

0 comments on commit 1db32ca

Please sign in to comment.