Skip to content

Commit cf74ec8

Browse files
committed
refactor media watch code
revert button detections to older, non-focused session behavior
1 parent 0f6254d commit cf74ec8

8 files changed

Lines changed: 298 additions & 161 deletions

File tree

Artemis.MediaInfo/Artemis.MediaInfo.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
<Platforms>x64</Platforms>
55
<PlatformTarget>x64</PlatformTarget>
66
<IncludeBuildOutput>false</IncludeBuildOutput>
7+
<Nullable>enable</Nullable>
78
</PropertyGroup>
89

910
<ItemGroup>

Artemis.MediaInfo/DataModels/MediaInfoDataModel.cs

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
using System.Collections.Generic;
2-
using Windows.Media;
32
using Windows.Media.Control;
4-
using Artemis.Core;
53
using Artemis.Core.ColorScience;
64
using Artemis.Core.Modules;
75
using WindowsMediaController;
@@ -36,16 +34,6 @@ public class MediaInfoDataModel : DataModel
3634

3735
public string SessionName { get; set; }
3836

39-
public DataModelEvent<MediaChangedEventArgs> MediaChanged { get; } = new();
4037
public ISet<MediaManager.MediaSession> MediaSessions { get; set; }
4138
public ISet<MediaManager.MediaSession> ArtMediaSessions { get; set; }
42-
}
43-
44-
public class MediaChangedEventArgs : DataModelEventArgs
45-
{
46-
public string SessionId { get; set; }
47-
public string Title { get; set; }
48-
public string Artist { get; set; }
49-
public MediaPlaybackType MediaType { get; set; }
50-
public bool HasArt { get; set; }
5139
}
Lines changed: 63 additions & 132 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
1-
using Artemis.Core;
1+
using System;
2+
using Artemis.Core;
23
using Artemis.Core.Modules;
34
using System.Collections.Generic;
45
using System.Linq;
56
using Artemis.MediaInfo.DataModels;
6-
using WindowsMediaController;
7-
using Windows.Media;
87
using Windows.Media.Control;
9-
using Artemis.Core.Properties;
8+
using Artemis.MediaInfo.MediaWatch;
109
using static WindowsMediaController.MediaManager;
1110
using static Artemis.MediaInfo.MediaInfoHelper;
1211

@@ -15,186 +14,118 @@ namespace Artemis.MediaInfo;
1514
[PluginFeature(Name = "MediaInfo")]
1615
public class MediaInfoModule : Module<MediaInfoDataModel>
1716
{
18-
private MediaManager _mediaManager;
17+
private static readonly bool FocusedUpdate = false; //because window's focus events don't work well for everyone :/
1918

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

22-
private readonly ISet<MediaSession> _mediaSessions = new HashSet<MediaSession>(new MediaSessionComparer());
23-
private readonly ISet<MediaSession> _albumArtSessions = new HashSet<MediaSession>(new MediaSessionComparer());
24-
25-
[CanBeNull]
26-
private MediaSession _currentSession;
21+
private readonly MediaWatcher _mediaWatcher = new();
2722

2823
public override void Enable()
2924
{
30-
_mediaSessions.Clear();
31-
_albumArtSessions.Clear();
32-
33-
_mediaManager = new MediaManager();
34-
_mediaManager.OnAnySessionOpened += MediaManager_OnSessionOpened;
35-
_mediaManager.OnAnySessionClosed += MediaManager_OnAnySessionClosed;
36-
_mediaManager.OnFocusedSessionChanged += MediaManagerOnOnFocusedSessionChanged;
37-
_mediaManager.OnAnyMediaPropertyChanged += MediaManager_OnAnyMediaPropertyChanged; //listen for media arts
38-
39-
_mediaManager.Start();
40-
41-
foreach (var (_, mediaSession) in _mediaManager.CurrentMediaSessions)
42-
{
43-
_mediaSessions.Add(mediaSession);
44-
}
45-
}
46-
47-
private void MediaManagerOnOnFocusedSessionChanged(MediaSession mediaSession)
48-
{
49-
if (_currentSession != null)
50-
{
51-
_currentSession.OnPlaybackStateChanged -= MediaSession_OnPlaybackStateChanged;
52-
}
53-
_mediaSessions.Add(mediaSession);
54-
_currentSession = mediaSession;
55-
_mediaManager.OnAnyPlaybackStateChanged += MediaSession_OnPlaybackStateChanged;
56-
MediaSession_OnPlaybackStateChanged(mediaSession, mediaSession.ControlSession.GetPlaybackInfo());
25+
DataModel.MediaSessions = _mediaWatcher.MediaSessions;
26+
DataModel.ArtMediaSessions = _mediaWatcher.AlbumArtSessions;
5727
}
5828

5929
public override void Disable()
6030
{
61-
_albumArtSessions.Clear();
62-
_mediaSessions.Clear();
63-
64-
if (_currentSession != null)
65-
{
66-
_currentSession.OnPlaybackStateChanged -= MediaSession_OnPlaybackStateChanged;
67-
}
68-
69-
_mediaManager.OnAnyMediaPropertyChanged -= MediaManager_OnAnyMediaPropertyChanged;
70-
_mediaManager.OnFocusedSessionChanged -= MediaManagerOnOnFocusedSessionChanged;
71-
_mediaManager.OnAnySessionClosed -= MediaManager_OnAnySessionClosed;
72-
_mediaManager.OnAnySessionOpened -= MediaManager_OnSessionOpened;
73-
_mediaManager.Dispose();
74-
_mediaManager = null;
31+
//unused
7532
}
7633

7734
public override void Update(double deltaTime) {}
7835

7936
public override void ModuleActivated(bool isOverride)
8037
{
81-
DataModel.MediaSessions = _mediaSessions;
82-
DataModel.ArtMediaSessions = _albumArtSessions;
38+
_mediaWatcher.FocusedMediaChanged += MediaWatcherOnFocusedMediaChanged;
39+
_mediaWatcher.ArtStateChanged += MediaWatcherOnArtStateChanged;
40+
_mediaWatcher.StartListening().Wait();
8341
}
8442
public override void ModuleDeactivated(bool isOverride) {
85-
//unused
86-
}
87-
88-
private void MediaManager_OnSessionOpened(MediaSession mediaSession)
89-
{
90-
DataModel.HasMedia = true;
91-
_mediaSessions.Add(mediaSession);
43+
_mediaWatcher.StopListening();
44+
_mediaWatcher.FocusedMediaChanged -= MediaWatcherOnFocusedMediaChanged;
45+
_mediaWatcher.ArtStateChanged -= MediaWatcherOnArtStateChanged;
9246
}
9347

94-
private void MediaManager_OnAnySessionClosed(MediaSession mediaSession)
48+
private void MediaWatcherOnFocusedMediaChanged(object? sender, FocusedMediaChangedEventArgs e)
9549
{
96-
_currentSession.OnPlaybackStateChanged -= MediaSession_OnPlaybackStateChanged;
97-
_mediaSessions.Remove(mediaSession);
98-
_albumArtSessions.Remove(mediaSession);
99-
if (_currentSession.Id == mediaSession.Id)
100-
{
101-
_currentSession = _mediaManager.GetFocusedSession();
102-
}
103-
UpdateButtons(_currentSession);
104-
UpdateArtState();
50+
var mediaSession = e.MediaSession;
51+
UpdateButtons(mediaSession, e.PlaybackInfo);
10552
}
10653

107-
private async void MediaManager_OnAnyMediaPropertyChanged(MediaSession mediaSession,
108-
GlobalSystemMediaTransportControlsSessionMediaProperties mediaProperties)
54+
private void UpdateButtons(MediaSession? mediaSession,
55+
GlobalSystemMediaTransportControlsSessionPlaybackInfo? playbackInfo)
10956
{
110-
if (mediaSession.ControlSession == null)
57+
if (mediaSession == null)
11158
{
112-
MediaManager_OnAnySessionClosed(mediaSession);
59+
DataModel.HasMedia = false;
60+
DataModel.HasNextMedia = false;
61+
DataModel.HasPreviousMedia = false;
62+
DataModel.MediaPlaying = false;
63+
DataModel.MediaState = GlobalSystemMediaTransportControlsSessionPlaybackStatus.Closed;
64+
DataModel.SessionName = "";
11365
return;
11466
}
115-
try
116-
{
117-
if (mediaProperties.Thumbnail is null)
118-
{
119-
_albumArtSessions.Remove(mediaSession);
120-
return;
121-
}
67+
DataModel.HasMedia = true;
12268

123-
DataModel.ArtColors = await ReadMediaColors(mediaProperties);
124-
_albumArtSessions.Add(mediaSession);
125-
}
126-
catch
69+
if (FocusedUpdate)
12770
{
128-
_albumArtSessions.Remove(mediaSession);
71+
FocusedModelUpdate(mediaSession, playbackInfo);
12972
}
130-
finally
73+
else
13174
{
132-
UpdateArtState();
133-
DataModel.MediaChanged.Trigger(new MediaChangedEventArgs
134-
{
135-
SessionId = mediaSession.Id,
136-
Title = mediaProperties.Title,
137-
Artist = mediaProperties.Artist,
138-
MediaType = mediaProperties.PlaybackType ?? MediaPlaybackType.Unknown,
139-
HasArt = mediaProperties.Thumbnail is not null
140-
});
75+
AnySessionModelUpdate(mediaSession, playbackInfo);
14176
}
14277
}
14378

144-
private void MediaSession_OnPlaybackStateChanged(MediaSession mediaSession,
145-
GlobalSystemMediaTransportControlsSessionPlaybackInfo playbackInfo)
79+
private void FocusedModelUpdate(MediaSession mediaSession,
80+
GlobalSystemMediaTransportControlsSessionPlaybackInfo? playbackInfo)
14681
{
147-
if (playbackInfo == null || playbackInfo.PlaybackStatus == GlobalSystemMediaTransportControlsSessionPlaybackStatus.Closed)
82+
if (playbackInfo == null)
14883
{
149-
MediaManager_OnAnySessionClosed(mediaSession);
150-
return;
84+
playbackInfo = mediaSession.ControlSession.GetPlaybackInfo();
15185
}
15286

153-
_mediaSessions.Add(mediaSession); // Some app like chrome use same id for different tabs.
154-
// So, closing the tab may cause all chroma sessions to be removed. This re-adds them
155-
156-
UpdateButtons(mediaSession);
157-
UpdateArtState();
158-
}
159-
160-
private void UpdateButtons(MediaSession mediaSession)
161-
{
162-
if (mediaSession == null)
163-
{
164-
DataModel.HasMedia = false;
165-
DataModel.HasNextMedia = false;
166-
DataModel.HasPreviousMedia = false;
167-
DataModel.MediaPlaying = false;
168-
DataModel.MediaState = GlobalSystemMediaTransportControlsSessionPlaybackStatus.Closed;
169-
DataModel.SessionName = "";
170-
return;
171-
}
172-
DataModel.HasMedia = true;
173-
174-
var playbackInfo = mediaSession.ControlSession.GetPlaybackInfo();
17587
var playbackControls = playbackInfo.Controls;
88+
17689
DataModel.HasNextMedia = playbackControls.IsNextEnabled;
17790
DataModel.HasPreviousMedia = playbackControls.IsPreviousEnabled;
178-
DataModel.MediaPlaying = playbackInfo.PlaybackStatus == GlobalSystemMediaTransportControlsSessionPlaybackStatus.Playing;
91+
DataModel.MediaPlaying =
92+
playbackInfo.PlaybackStatus == GlobalSystemMediaTransportControlsSessionPlaybackStatus.Playing;
17993
DataModel.MediaState = playbackInfo.PlaybackStatus;
18094
DataModel.SessionName = mediaSession.Id;
18195
}
18296

183-
private void UpdateArtState()
97+
private void AnySessionModelUpdate(MediaSession focusedMediaSession,
98+
GlobalSystemMediaTransportControlsSessionPlaybackInfo? playbackInfo)
18499
{
185-
DataModel.HasArt = _albumArtSessions.Any();
100+
DataModel.HasPreviousMedia = false;
101+
DataModel.MediaPlaying = false;
102+
DataModel.HasNextMedia = false;
103+
DataModel.MediaState = playbackInfo?.PlaybackStatus ?? GlobalSystemMediaTransportControlsSessionPlaybackStatus.Closed;
104+
DataModel.SessionName = focusedMediaSession.Id;
105+
foreach (var mediaSession in _mediaWatcher.MediaSessions)
106+
{
107+
var controls = mediaSession.ControlSession.GetPlaybackInfo().Controls;
108+
DataModel.HasPreviousMedia |= controls.IsPreviousEnabled;
109+
DataModel.MediaPlaying |= !controls.IsPlayEnabled;
110+
DataModel.HasNextMedia |= controls.IsNextEnabled;
111+
}
186112
}
187113

188-
private sealed class MediaSessionComparer : IEqualityComparer<MediaSession>
114+
private async void MediaWatcherOnArtStateChanged(object? sender, ArtStateChangedEventArgs e)
189115
{
190-
public bool Equals(MediaSession x, MediaSession y)
116+
if (e.Thumbnail != null)
191117
{
192-
return x?.Id == y?.Id;
118+
DataModel.ArtColors = await ReadMediaColors(e.Thumbnail);
193119
}
194-
195-
public int GetHashCode(MediaSession obj)
120+
else
196121
{
197-
return obj.Id.GetHashCode();
122+
var mediaSession = _mediaWatcher.AlbumArtSessions.LastOrDefault();
123+
if (mediaSession!= null)
124+
{
125+
var mediaProperties = mediaSession.ControlSession.TryGetMediaPropertiesAsync().GetAwaiter().GetResult();
126+
DataModel.ArtColors = await ReadMediaColors(mediaProperties);
127+
}
198128
}
129+
DataModel.HasArt = _mediaWatcher.AlbumArtSessions.Any();
199130
}
200131
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
using System;
2+
using Windows.Media.Control;
3+
using Windows.Storage.Streams;
4+
using WindowsMediaController;
5+
6+
namespace Artemis.MediaInfo.MediaWatch;
7+
8+
public class MediaAddedEventArgs : EventArgs
9+
{
10+
public MediaManager.MediaSession MediaSession { get; }
11+
12+
public MediaAddedEventArgs(MediaManager.MediaSession mediaSession)
13+
{
14+
MediaSession = mediaSession;
15+
}
16+
}
17+
18+
public class ArtStateChangedEventArgs : EventArgs
19+
{
20+
public MediaManager.MediaSession MediaSession { get; }
21+
public IRandomAccessStreamReference? Thumbnail { get; }
22+
23+
public ArtStateChangedEventArgs(MediaManager.MediaSession mediaSession, IRandomAccessStreamReference? thumbnail)
24+
{
25+
MediaSession = mediaSession;
26+
Thumbnail = thumbnail;
27+
}
28+
}
29+
30+
public class FocusedMediaChangedEventArgs : EventArgs
31+
{
32+
public MediaManager.MediaSession? MediaSession { get; }
33+
public GlobalSystemMediaTransportControlsSessionPlaybackInfo? PlaybackInfo { get; }
34+
35+
public FocusedMediaChangedEventArgs(MediaManager.MediaSession? mediaSession,
36+
GlobalSystemMediaTransportControlsSessionPlaybackInfo? playbackInfo)
37+
{
38+
MediaSession = mediaSession;
39+
PlaybackInfo = playbackInfo;
40+
}
41+
}

0 commit comments

Comments
 (0)