Skip to content

Commit

Permalink
Preparing Backgroundog
Browse files Browse the repository at this point in the history
  • Loading branch information
Taiizor committed Sep 20, 2023
1 parent 3abd6f1 commit e352362
Show file tree
Hide file tree
Showing 7 changed files with 201 additions and 137 deletions.
100 changes: 100 additions & 0 deletions src/Project/Sucrose.Backgroundog/Extension/AudioSession.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
using NPSMLib;
using System.IO;
using SBET = Sucrose.Backgroundog.Extension.Thumbnail;
using SBMI = Sucrose.Backgroundog.Manage.Internal;

namespace Sucrose.Backgroundog.Extension
{
internal class AudioSession
{
private static void SetupEvents()
{
if (SBMI.PlayingSession != null)
{
SBMI.DataSource = SBMI.PlayingSession.ActivateMediaPlaybackDataSource();
SBMI.DataSource.MediaPlaybackDataChanged += (s, e) => SetCurrentSession();
}
}

public static void SessionListChanged()
{
SBMI.PlayingSession = SBMI.SessionManager.CurrentSession;
SetupEvents();
SetCurrentSession();
}

private static void SetCurrentSession()
{
if (SBMI.PlayingSession != null)
{
lock (SBMI.LockObject)
{
MediaObjectInfo MediaDetails = SBMI.DataSource.GetMediaObjectInfo();
MediaPlaybackInfo MediaPlaybackInfo = SBMI.DataSource.GetMediaPlaybackInfo();
MediaTimelineProperties MediaTimeline = SBMI.DataSource.GetMediaTimelineProperties();

string ThumbnailString = null;

using (Stream Thumbnail = SBMI.DataSource.GetThumbnailStream())
{
if (Thumbnail != null)
{
ThumbnailString = SBET.Create(Thumbnail);
Thumbnail.Flush();
}
}

SBMI.AudioData.State = true;
SBMI.AudioData.Title = MediaDetails.Title;
SBMI.AudioData.Artist = MediaDetails.Artist;
SBMI.AudioData.Subtitle = MediaDetails.Subtitle;
SBMI.AudioData.AlbumTitle = MediaDetails.AlbumTitle;
SBMI.AudioData.AlbumArtist = MediaDetails.AlbumArtist;
SBMI.AudioData.TrackNumber = MediaDetails.TrackNumber;
SBMI.AudioData.AlbumTrackCount = MediaDetails.AlbumTrackCount;
SBMI.AudioData.MediaType = MediaPlaybackDataSource.MediaSchemaToMediaPlaybackMode(MediaDetails.MediaClassPrimaryID);

SBMI.AudioData.PID = SBMI.PlayingSession?.PID;
SBMI.AudioData.Hwnd = SBMI.PlayingSession?.Hwnd;
SBMI.AudioData.SourceAppId = SBMI.PlayingSession?.SourceAppId;
SBMI.AudioData.SourceDeviceId = SBMI.PlayingSession?.SourceDeviceId;
SBMI.AudioData.RenderDeviceId = SBMI.PlayingSession?.RenderDeviceId;

SBMI.AudioData.RepeatMode = MediaPlaybackInfo.RepeatMode;
SBMI.AudioData.PropsValid = MediaPlaybackInfo.PropsValid;
SBMI.AudioData.PlaybackRate = MediaPlaybackInfo.PlaybackRate;
SBMI.AudioData.PlaybackMode = MediaPlaybackInfo.PlaybackMode;
SBMI.AudioData.PlaybackCaps = MediaPlaybackInfo.PlaybackCaps;
SBMI.AudioData.PlaybackState = MediaPlaybackInfo.PlaybackState;
SBMI.AudioData.ShuffleEnabled = MediaPlaybackInfo.ShuffleEnabled;
SBMI.AudioData.LastPlayingFileTime = MediaPlaybackInfo.LastPlayingFileTime;

SBMI.AudioData.EndTime = MediaTimeline.EndTime;
SBMI.AudioData.Position = MediaTimeline.Position;
SBMI.AudioData.StartTime = MediaTimeline.StartTime;
SBMI.AudioData.MinSeekTime = MediaTimeline.MinSeekTime;
SBMI.AudioData.MaxSeekTime = MediaTimeline.MaxSeekTime;
SBMI.AudioData.PositionSetFileTime = MediaTimeline.PositionSetFileTime;

SBMI.AudioData.ThumbnailString = ThumbnailString;

if (string.IsNullOrEmpty(ThumbnailString))
{
SBMI.AudioData.ThumbnailAddress = ThumbnailString;
}
else
{
SBMI.AudioData.ThumbnailAddress = "data:image/png;base64," + ThumbnailString;
}
}
}
else
{
lock (SBMI.LockObject)
{
SBMI.AudioData.State = false;
}
}
}
}
}
5 changes: 4 additions & 1 deletion src/Project/Sucrose.Backgroundog/Extension/Data.cs
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,10 @@ public static JObject GetMotherboardInfo()
{
return new JObject
{
{ "Name", SBMI.MotherboardData.Name }
{ "Name", SBMI.MotherboardData.Name },
{ "Product", SBMI.MotherboardData.Product },
{ "Version", SBMI.MotherboardData.Version },
{ "Manufacturer", SBMI.MotherboardData.Manufacturer }
};
}
}
Expand Down
54 changes: 54 additions & 0 deletions src/Project/Sucrose.Backgroundog/Extension/Thumbnail.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
using System.Drawing.Imaging;
using System.IO;
using SBMM = Sucrose.Backgroundog.Manage.Manager;

namespace Sucrose.Backgroundog.Extension
{
internal class Thumbnail
{
public static string Create(Stream stream)
{
using MemoryStream Stream = new();

Stream.Seek(0, SeekOrigin.Begin);
stream.CopyTo(Stream);

if (!SBMM.Windows11_OrGreater)
{
using Bitmap Image = new(Stream);

if (PixelAlpha(Image, 0, 0))
{
return CropImage(Image, 34, 1, 233, 233);
}
}

byte[] Array = Stream.ToArray();

return Convert.ToBase64String(Array);
}

private static bool PixelAlpha(Bitmap Image, int X, int Y)
{
return Image.GetPixel(X, Y).A == 0;
}

private static string CropImage(Bitmap Image, int X, int Y, int Width, int Height)
{
Rectangle Rect = new(X, Y, Width, Height);

using Bitmap CroppedBitmap = new(Rect.Width, Rect.Height, Image.PixelFormat);

Graphics Graphic = Graphics.FromImage(CroppedBitmap);
Graphic.DrawImage(Image, 0, 0, Rect, GraphicsUnit.Pixel);

using MemoryStream Stream = new();

CroppedBitmap.Save(Stream, ImageFormat.Png);

byte[] ByteImage = Stream.ToArray();

return Convert.ToBase64String(ByteImage);
}
}
}
158 changes: 23 additions & 135 deletions src/Project/Sucrose.Backgroundog/Helper/Specification.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
using LibreHardwareMonitor.Hardware;
using NPSMLib;
using Skylark.Enum;
using Skylark.Helper;
using Skylark.Standard.Extension.Storage;
using System.Drawing.Imaging;
using System.IO;
using System.Management;
using SBEAS = Sucrose.Backgroundog.Extension.AudioSession;
using SBEUV = Sucrose.Backgroundog.Extension.UpdateVisitor;
using SBMI = Sucrose.Backgroundog.Manage.Internal;
using SMMM = Sucrose.Manager.Manage.Manager;
Expand Down Expand Up @@ -82,8 +80,10 @@ public static async Task Start()
{
SBMI.AudioManagement = false;

SBMI.SessionManager.SessionListChanged += SessionListChanged;
SBMI.SessionManager.SessionListChanged += (s, e) => SBEAS.SessionListChanged();
}

SBEAS.SessionListChanged();
});

_ = Task.Run(() =>
Expand Down Expand Up @@ -114,6 +114,24 @@ public static async Task Start()
}
});

_ = Task.Run(() =>
{
if (SBMI.MotherboardManagement)
{
SBMI.MotherboardManagement = false;

ManagementObjectSearcher Searcher = new("SELECT * FROM Win32_BaseBoard");

foreach (ManagementObject Object in Searcher.Get().Cast<ManagementObject>())
{
SBMI.MotherboardData.Product = Object["Product"].ToString();
SBMI.MotherboardData.Version = Object["Version"].ToString();
SBMI.MotherboardData.Manufacturer = Object["Manufacturer"].ToString();
break;
}
}
});

_ = Task.Run(() =>
{
SBMI.Computer.Accept(new SBEUV());
Expand Down Expand Up @@ -231,10 +249,7 @@ public static async Task Start()
{
Hardware.Update();

SBMI.MotherboardData = new()
{
Name = Hardware.Name
};
SBMI.MotherboardData.Name = Hardware.Name;
}
}
});
Expand Down Expand Up @@ -267,132 +282,5 @@ public static async Task Start()

await Task.CompletedTask;
}

private static void SessionListChanged(object sender, NowPlayingSessionManagerEventArgs e)
{
SBMI.PlayingSession = SBMI.SessionManager.CurrentSession;
SetupEvents();
PrintCurrentSession();
}

private static void SetupEvents()
{
if (SBMI.PlayingSession != null)
{
SBMI.DataSource = SBMI.PlayingSession.ActivateMediaPlaybackDataSource();
SBMI.DataSource.MediaPlaybackDataChanged += M_MediaPlaybackDataChanged;
}
}

private static void M_MediaPlaybackDataChanged(object sender, MediaPlaybackDataChangedArgs e)
{
PrintCurrentSession();
}

private static void PrintCurrentSession()
{
if (SBMI.PlayingSession != null)
{
lock (SBMI.LockObject)
{
MediaObjectInfo MediaDetails = SBMI.DataSource.GetMediaObjectInfo();
MediaPlaybackInfo MediaPlaybackInfo = SBMI.DataSource.GetMediaPlaybackInfo();
MediaTimelineProperties MediaTimeline = SBMI.DataSource.GetMediaTimelineProperties();

using Stream Thumbnail = SBMI.DataSource.GetThumbnailStream();
string ThumbnailString = Thumbnail is null ? null : CreateThumbnail(Thumbnail);

SBMI.AudioData.State = true;
SBMI.AudioData.Title = MediaDetails.Title;
SBMI.AudioData.Artist = MediaDetails.Artist;
SBMI.AudioData.Subtitle = MediaDetails.Subtitle;
SBMI.AudioData.AlbumTitle = MediaDetails.AlbumTitle;
SBMI.AudioData.AlbumArtist = MediaDetails.AlbumArtist;
SBMI.AudioData.TrackNumber = MediaDetails.TrackNumber;
SBMI.AudioData.AlbumTrackCount = MediaDetails.AlbumTrackCount;
SBMI.AudioData.MediaType = MediaPlaybackDataSource.MediaSchemaToMediaPlaybackMode(MediaDetails.MediaClassPrimaryID);

SBMI.AudioData.PID = SBMI.PlayingSession?.PID;
SBMI.AudioData.Hwnd = SBMI.PlayingSession?.Hwnd;
SBMI.AudioData.SourceAppId = SBMI.PlayingSession?.SourceAppId;
SBMI.AudioData.SourceDeviceId = SBMI.PlayingSession?.SourceDeviceId;
SBMI.AudioData.RenderDeviceId = SBMI.PlayingSession?.RenderDeviceId;

SBMI.AudioData.RepeatMode = MediaPlaybackInfo.RepeatMode;
SBMI.AudioData.PropsValid = MediaPlaybackInfo.PropsValid;
SBMI.AudioData.PlaybackRate = MediaPlaybackInfo.PlaybackRate;
SBMI.AudioData.PlaybackMode = MediaPlaybackInfo.PlaybackMode;
SBMI.AudioData.PlaybackCaps = MediaPlaybackInfo.PlaybackCaps;
SBMI.AudioData.PlaybackState = MediaPlaybackInfo.PlaybackState;
SBMI.AudioData.ShuffleEnabled = MediaPlaybackInfo.ShuffleEnabled;
SBMI.AudioData.LastPlayingFileTime = MediaPlaybackInfo.LastPlayingFileTime;

SBMI.AudioData.EndTime = MediaTimeline.EndTime;
SBMI.AudioData.Position = MediaTimeline.Position;
SBMI.AudioData.StartTime = MediaTimeline.StartTime;
SBMI.AudioData.MinSeekTime = MediaTimeline.MinSeekTime;
SBMI.AudioData.MaxSeekTime = MediaTimeline.MaxSeekTime;
SBMI.AudioData.PositionSetFileTime = MediaTimeline.PositionSetFileTime;

SBMI.AudioData.ThumbnailString = ThumbnailString;

if (string.IsNullOrEmpty(ThumbnailString))
{
SBMI.AudioData.ThumbnailAddress = ThumbnailString;
}
else
{
SBMI.AudioData.ThumbnailAddress = "data:image/png;base64," + ThumbnailString;
}
}
}
else
{
lock (SBMI.LockObject)
{
SBMI.AudioData.State = false;
}
}
}

private static readonly bool isWindows11_OrGreater = Environment.OSVersion.Version.Build >= 22000;

private static string CreateThumbnail(Stream stream)
{
using MemoryStream ms = new();
ms.Seek(0, SeekOrigin.Begin);
stream.CopyTo(ms);
if (!isWindows11_OrGreater)
{
//In Win10 there is transparent borders for some apps
using Bitmap bmp = new(ms);
if (IsPixelAlpha(bmp, 0, 0))
{
return CropImage(bmp, 34, 1, 233, 233);
}
}
byte[] array = ms.ToArray();
return Convert.ToBase64String(array);
}

private static string CropImage(Bitmap bmp, int x, int y, int width, int height)
{
Rectangle rect = new(x, y, width, height);

using Bitmap croppedBitmap = new(rect.Width, rect.Height, bmp.PixelFormat);

Graphics gfx = Graphics.FromImage(croppedBitmap);
gfx.DrawImage(bmp, 0, 0, rect, GraphicsUnit.Pixel);

using MemoryStream ms = new();
croppedBitmap.Save(ms, ImageFormat.Png);
byte[] byteImage = ms.ToArray();
return Convert.ToBase64String(byteImage);
}

private static bool IsPixelAlpha(Bitmap bmp, int x, int y)
{
return bmp.GetPixel(x, y).A == 0;
}
}
}
7 changes: 6 additions & 1 deletion src/Project/Sucrose.Backgroundog/Manage/Internal.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ internal static class Internal

public static Timer InitializeTimer = null;

public static bool MotherboardManagement = true;

public static readonly object LockObject = new();

public static NowPlayingSession PlayingSession = null;
Expand Down Expand Up @@ -168,7 +170,10 @@ internal static class Internal

public static SBSDMDS MotherboardData = new()
{
Name = string.Empty
Name = string.Empty,
Product = string.Empty,
Version = string.Empty,
Manufacturer = string.Empty
};
}
}
2 changes: 2 additions & 0 deletions src/Project/Sucrose.Backgroundog/Manage/Manager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ namespace Sucrose.Backgroundog.Manage
{
internal static class Manager
{
public static bool Windows11_OrGreater => Environment.OSVersion.Version.Build >= 22000;

public static Mutex Mutex => new(true, SMR.BackgroundogMutex);
}
}
Loading

0 comments on commit e352362

Please sign in to comment.