using Windows.Media.Control; using Windows.Storage.Streams; namespace Hyperbar.Widget.MediaController.Windows; public class MediaController : INotificationHandler>, INotificationHandler>, INotificationHandler>, INotificationHandler>, INotificationHandler>, INotificationHandler>, INotificationHandler>, IDisposable { private readonly IDisposer disposer; private readonly IMediator mediator; private readonly GlobalSystemMediaTransportControlsSession session; private bool isNextEnabled; private bool isPreviousEnabled; private GlobalSystemMediaTransportControlsSessionPlaybackStatus playbackStatus; public MediaController(IMediator mediator, IDisposer disposer, GlobalSystemMediaTransportControlsSession session) { this.mediator = mediator; this.disposer = disposer; this.session = session; disposer.Add(this); mediator.Subscribe(this); session.MediaPropertiesChanged += OnMediaPropertiesChanged; session.PlaybackInfoChanged += OnPlaybackInfoChanged; } public void Dispose() { GC.SuppressFinalize(this); disposer.Dispose(this); } public async Task Handle(Request args, CancellationToken cancellationToken) => await UpdateMediaInformationAsync(); public async Task Handle(Request args, CancellationToken cancellationToken) { await session.TrySkipNextAsync(); await UpdateMediaStateAsync(); } public async Task Handle(Request args, CancellationToken cancellationToken) { await session.TrySkipPreviousAsync(); await UpdateMediaStateAsync(); } public async Task Handle(Request args, CancellationToken cancellationToken) => await UpdateMediaStateAsync(); public async Task Handle(Request args, CancellationToken cancellationToken) => await UpdateMediaStateAsync(); public async Task Handle(Request args, CancellationToken cancellationToken) { GlobalSystemMediaTransportControlsSessionPlaybackInfo playbackInfo = session.GetPlaybackInfo(); if (playbackInfo.PlaybackStatus is GlobalSystemMediaTransportControlsSessionPlaybackStatus.Playing) { await session.TryPauseAsync(); } if (playbackInfo.PlaybackStatus is GlobalSystemMediaTransportControlsSessionPlaybackStatus.Paused) { await session.TryPlayAsync(); } await UpdateMediaStateAsync(); } public async Task Handle(Request args, CancellationToken cancellationToken) => await UpdateMediaStateAsync(); private async void OnMediaPropertiesChanged(GlobalSystemMediaTransportControlsSession sender, MediaPropertiesChangedEventArgs args) { await UpdateMediaInformationAsync(); await UpdateMediaStateAsync(); } private async void OnPlaybackInfoChanged(GlobalSystemMediaTransportControlsSession sender, PlaybackInfoChangedEventArgs args) => await UpdateMediaStateAsync(); private async Task UpdateMediaInformationAsync() { try { GlobalSystemMediaTransportControlsSessionMediaProperties mediaProperties = await session.TryGetMediaPropertiesAsync(); byte[]? buffer = null; if (mediaProperties.Thumbnail is not null) { IRandomAccessStreamWithContentType randomAccessStream = await mediaProperties.Thumbnail.OpenReadAsync(); var stream = randomAccessStream.AsStream(); using MemoryStream memoryStream = new(); await stream.CopyToAsync(memoryStream); buffer = memoryStream.ToArray(); } await mediator.PublishAsync(new Changed(new MediaInformation(mediaProperties.Title, mediaProperties.Artist, buffer))); } catch { } } private async Task UpdateMediaStateAsync() { try { GlobalSystemMediaTransportControlsSessionPlaybackInfo playbackInfo = session.GetPlaybackInfo(); await mediator.PublishAsync(new Changed>(new MediaButton(playbackInfo.PlaybackStatus is GlobalSystemMediaTransportControlsSessionPlaybackStatus.Playing ? new MediaButtonPlaying() : new MediaButtonPaused()))); bool isPreviousEnabled = playbackInfo.Controls.IsPreviousEnabled; if (this.isPreviousEnabled != isPreviousEnabled) { await mediator.PublishAsync(new Changed>(new MediaButton(isPreviousEnabled ? new MediaButtonEnabled() : new MediaButtonDisabled()))); this.isPreviousEnabled = isPreviousEnabled; } bool isNextEnabled = playbackInfo.Controls.IsNextEnabled; if (this.isNextEnabled != isNextEnabled) { await mediator.PublishAsync(new Changed>(new MediaButton(isNextEnabled ? new MediaButtonEnabled() : new MediaButtonDisabled()))); this.isNextEnabled = isNextEnabled; } } catch { } } }