Skip to content

Commit

Permalink
Add reset SMTC functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
datasone committed Mar 12, 2022
1 parent 69c5213 commit f36a407
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 13 deletions.
55 changes: 45 additions & 10 deletions MPVMediaControl/MediaController.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
using System;
using System.IO;
using System.Linq;
using System.Threading;
using Windows.Media;
using Windows.Media.Playback;
Expand All @@ -11,9 +10,9 @@ namespace MPVMediaControl
{
public class MediaController
{
private readonly SystemMediaTransportControls _controls;
private readonly SystemMediaTransportControlsDisplayUpdater _updater;
private readonly MediaPlayer _mediaPlayer;
private SystemMediaTransportControls _controls;
private SystemMediaTransportControlsDisplayUpdater _updater;
private MediaPlayer _mediaPlayer;

public readonly int Pid;

Expand Down Expand Up @@ -54,9 +53,14 @@ public void Cleanup()
System.IO.File.Delete(ShotPath);
}
}

public MCMediaFile Clone()
{
return this.MemberwiseClone() as MCMediaFile;
}
}

private readonly MCMediaFile _file = new MCMediaFile();
private MCMediaFile _file = new MCMediaFile();

public MCMediaFile File
{
Expand Down Expand Up @@ -140,9 +144,8 @@ public PlayState State
}
}

public MediaController(int pid)
public void InitSMTC()
{
this.Pid = pid;
_mediaPlayer = new MediaPlayer();
_controls = _mediaPlayer.SystemMediaTransportControls;
_mediaPlayer.CommandManager.IsEnabled = false;
Expand All @@ -155,13 +158,45 @@ public MediaController(int pid)
_controls.IsNextEnabled = true;
_controls.IsPreviousEnabled = true;

State = PlayState.Stop;
State = _state;

if (_file.Path != null)
{
File = _file;
}
}

public MediaController(int pid, bool initSMTC)
{
this.Pid = pid;
_state = PlayState.Stop;

if (initSMTC)
{
InitSMTC();
}
}

public void Cleanup()
public MediaController DuplicateSelf()
{
_file?.Cleanup();
var newObj = new MediaController(Pid, false);
newObj._file = _file.Clone();
newObj._state = _state;
return newObj;
}

public void Cleanup(bool cleanFile)
{
if (cleanFile)
{
_file?.Cleanup();
}
_updater.ClearAll();

// Ensure objects collected while "resetting SMTC"
_updater = null;
_controls = null;
_mediaPlayer = null;
}

public void UpdateShotPath(string path)
Expand Down
29 changes: 26 additions & 3 deletions MPVMediaControl/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System.Drawing;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace MPVMediaControl
Expand Down Expand Up @@ -47,6 +48,7 @@ public MyAppContext()
Icon = new Icon(SystemIcons.Application, 32, 32),
ContextMenu = new ContextMenu(new []
{
new MenuItem("Reset SMTC", ResetControllers),
new MenuItem("Exit", Exit)
}),
Visible = true
Expand All @@ -61,7 +63,7 @@ public MediaController GetController(int pid)
{
if (_controllers.FindIndex(c => c.Pid == pid) == -1)
{
_controllers.Add(new MediaController(pid));
_controllers.Add(new MediaController(pid, true));
return _controllers.Last();
}

Expand All @@ -71,17 +73,38 @@ public MediaController GetController(int pid)
public void RemoveController(int pid)
{
var controller = _controllers.Find(c => c.Pid == pid);
controller.Cleanup();
controller.Cleanup(true);
_controllers.Remove(controller);
}

private async void ResetControllers(object sender, EventArgs e)
{
var newControllers = _controllers.Select(c => c.DuplicateSelf()).ToList();

_controllers.ForEach(c => c.Cleanup(false));
_controllers.Clear();

// We need to manually trigger GC to remove MusicPlayer instances and prevent duplicate SMTC controls
GC.Collect();

_controllers.AddRange(newControllers);

// There is a bug in Windows where the control is not visible (but exists and is able to interact) if the info is updated too fast
// Sleep for a bit to prevent this
foreach (var controller in _controllers)
{
await Task.Delay(400);
controller.InitSMTC();
}
}

private void Exit(object sender, EventArgs e)
{
_trayIcon.Visible = false;

PipeServer.Cleanup();

_controllers.ForEach(i => i.Cleanup());
_controllers.ForEach(i => i.Cleanup(true));

Application.Exit();
Environment.Exit(0);
Expand Down

0 comments on commit f36a407

Please sign in to comment.