diff --git a/Jukebox_Mascot/App.config b/Jukebox_Mascot/App.config
index 193aecc..ea2564f 100644
--- a/Jukebox_Mascot/App.config
+++ b/Jukebox_Mascot/App.config
@@ -1,6 +1,18 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Jukebox_Mascot/App.xaml.cs b/Jukebox_Mascot/App.xaml.cs
index f8d0786..6964baa 100644
--- a/Jukebox_Mascot/App.xaml.cs
+++ b/Jukebox_Mascot/App.xaml.cs
@@ -1,10 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.Configuration;
-using System.Data;
-using System.Linq;
-using System.Threading.Tasks;
-using System.Windows;
+using System.Windows;
namespace Jukebox_Mascot
{
diff --git a/Jukebox_Mascot/Config.txt b/Jukebox_Mascot/Config.txt
index 105253f..15d289c 100644
--- a/Jukebox_Mascot/Config.txt
+++ b/Jukebox_Mascot/Config.txt
@@ -1,4 +1,4 @@
-//RiceShower//Tachyon//Tokai//Oguri//Pasa
+//RiceShower//Tachyon//Teio//Oguri//Pasa
START_CHAR=Tachyon
ALLOW_RANDOM_MASCOT=false
ALLOW_MUSIC_NOTES=true
diff --git a/Jukebox_Mascot/Jukebox_Mascot.csproj b/Jukebox_Mascot/Jukebox_Mascot.csproj
index 1bcd43a..c446a50 100644
--- a/Jukebox_Mascot/Jukebox_Mascot.csproj
+++ b/Jukebox_Mascot/Jukebox_Mascot.csproj
@@ -1,105 +1,35 @@
-
-
-
+
- Debug
- AnyCPU
- {6D5FB859-0563-40B6-B20C-B91EE10D592C}
+ net48
WinExe
- Jukebox_Mascot
- Jukebox_Mascot
- v4.8
- 512
- {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
- 4
- true
- true
-
-
- AnyCPU
- true
- full
- false
- bin\Debug\
- DEBUG;TRACE
- prompt
- 4
-
-
- AnyCPU
- pdbonly
- true
- bin\Release\
- TRACE
- prompt
- 4
+ true
+ true
+ true
icon2.ico
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
- 4.0
-
-
-
-
-
-
- MSBuild:Compile
- Designer
-
-
- MSBuild:Compile
- Designer
-
-
- App.xaml
- Code
-
-
- MainWindow.xaml
- Code
-
-
-
-
- Code
-
-
- True
- True
- Resources.resx
-
-
- True
- Settings.settings
- True
-
-
- ResXFileCodeGenerator
- Resources.Designer.cs
-
-
- SettingsSingleFileGenerator
- Settings.Designer.cs
-
-
-
-
-
-
PreserveNewest
@@ -107,6 +37,9 @@
PreserveNewest
+
+ PreserveNewest
+
PreserveNewest
@@ -175,5 +108,8 @@
PreserveNewest
-
+
+
+
+
\ No newline at end of file
diff --git a/Jukebox_Mascot/MainWindow.xaml.cs b/Jukebox_Mascot/MainWindow.xaml.cs
index 058962b..3d8d706 100644
--- a/Jukebox_Mascot/MainWindow.xaml.cs
+++ b/Jukebox_Mascot/MainWindow.xaml.cs
@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
+using System.IO;
using System.Linq;
using System.Windows;
using System.Windows.Forms;
@@ -9,8 +10,8 @@
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Threading;
-using System.IO;
-using System.Data.SqlTypes;
+using Windows.Media.Control;
+using WindowsMediaController;
namespace Jukebox_Mascot
{
@@ -62,6 +63,8 @@ public partial class MainWindow : Window
private bool ALLOW_RANDOM_MASCOT = true;
private bool ALLOW_MUSIC_NOTES = true;
private bool IS_RANDOM = false;
+ private bool OTHER_MEDIA_TRACKED = false;
+ private string OTHER_MEDIA_CURRENT_TRACK = "";
private double SCROLL_POS;
@@ -69,7 +72,8 @@ public partial class MainWindow : Window
private List MUSIC_FILES = new List();
private MediaPlayer PLAYER;
-
+ private MediaManager MEDIA_MANAGER;
+ private MediaManager.MediaSession CURRENT_SESSION;
private BitmapImage LoadSprite(string filefolder, string fileName, string rootFolder = "Characters")
{
string path = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "SpriteSheet", rootFolder, filefolder, fileName);
@@ -124,7 +128,7 @@ private void FatalError(string message, string title = "Error")
TRAY_ICON?.Dispose();
System.Windows.Application.Current.Shutdown();
}
- private int PlayAnimation(BitmapImage sheet,int currentFrame,int frameCount,int frameWidth,int frameHeight,System.Windows.Controls.Image targetImage,bool reverse = false)
+ private int PlayAnimation(BitmapImage sheet, int currentFrame, int frameCount, int frameWidth, int frameHeight, System.Windows.Controls.Image targetImage, bool reverse = false)
{
if (sheet == null)
return currentFrame;
@@ -138,7 +142,7 @@ private int PlayAnimation(BitmapImage sheet,int currentFrame,int frameCount,int
targetImage.Source = new CroppedBitmap(sheet, new Int32Rect(x, y, frameWidth, frameHeight));
if (!reverse)
- {
+ {
return (currentFrame + 1) % frameCount;
}
else
@@ -157,14 +161,82 @@ private int PlayAnimation(BitmapImage sheet,int currentFrame,int frameCount,int
}
}
+ private void UpdateMediaProperties(MediaManager.MediaSession sender, GlobalSystemMediaTransportControlsSessionMediaProperties mediaProperties)
+ {
+ if (mediaProperties == null)
+ {
+ OTHER_MEDIA_CURRENT_TRACK = "";
+ }
+ GC.Collect(0);
+
+ if (CURRENT_SESSION == sender)
+ {
+ // Get the name and the artist of the current track
+ string title = string.IsNullOrEmpty(mediaProperties.Title) ? "Unkown Title" : mediaProperties.Title;
+ string artist = string.IsNullOrEmpty(mediaProperties.Artist) ? "Unknown Artist" : mediaProperties.Artist;
+ OTHER_MEDIA_CURRENT_TRACK = $"🎵 Now Playing: {title} by {artist} 🎵";
+
+ this.Dispatcher.Invoke(() =>
+ {
+ ScrollingText.Text = OTHER_MEDIA_CURRENT_TRACK;
+ ReopenScrollingBorder();
+ if (ALLOW_RANDOM_MASCOT)
+ {
+ SwitchToRandomCharacter();
+ }
+ if (PLAY_INTRO_ON_NEW_SONG)
+ {
+ JukeBoxSprite.Source = null;
+ IS_INTRO = true;
+ CURRENT_INTRO_FRAME = 0;
+ CURRENT_JUKEBOX_FRAME = 0;
+ }
+ });
+ }
+ }
+
+ private void SenderPlaybackStateChanged(MediaManager.MediaSession sender, GlobalSystemMediaTransportControlsSessionPlaybackInfo args)
+ {
+ switch (args.PlaybackStatus)
+ {
+ /*
+ * This allows for different outcomes based on:
+ * if the media is closed, opened, changing, stopped, playing, or paused.
+ * So it can be used for different animations or actions, which would be cool.
+ */
+ case GlobalSystemMediaTransportControlsSessionPlaybackStatus.Playing:
+ case GlobalSystemMediaTransportControlsSessionPlaybackStatus.Changing:
+ CURRENT_SESSION = sender;
+ /*
+ * Calling this here when it is already being listened to seems redundant but it is needed for when the user pauses/unpauses or starts a new song
+ * The listener exists for automatic changes, such as spotify going to the next playlist.
+ */
+ UpdateMediaProperties(sender, sender.ControlSession.TryGetMediaPropertiesAsync().AsTask().Result);
+ break;
+ default:
+ break;
+ }
+ }
+
+ private void InitializeMediaManager()
+ {
+ MEDIA_MANAGER = new MediaManager();
+
+ MEDIA_MANAGER.OnAnyPlaybackStateChanged += SenderPlaybackStateChanged;
+ MEDIA_MANAGER.OnAnyMediaPropertyChanged += UpdateMediaProperties;
+
+ // Start listening
+ MEDIA_MANAGER.Start();
+ }
+
private void InitializeAnimations()
{
- MASTER_TIMER = new DispatcherTimer { Interval = TimeSpan.FromMilliseconds(FRAME_RATE)};
+ MASTER_TIMER = new DispatcherTimer { Interval = TimeSpan.FromMilliseconds(FRAME_RATE) };
MASTER_TIMER.Tick += (s, e) =>
{
if (IS_INTRO)
{
- CURRENT_INTRO_FRAME = PlayAnimation(INTRO_SHEET, CURRENT_INTRO_FRAME, INTRO_FRAME_COUNT,FRAME_WIDTH, FRAME_HEIGHT, SpriteImage);
+ CURRENT_INTRO_FRAME = PlayAnimation(INTRO_SHEET, CURRENT_INTRO_FRAME, INTRO_FRAME_COUNT, FRAME_WIDTH, FRAME_HEIGHT, SpriteImage);
if (CURRENT_INTRO_FRAME == 0)
{
@@ -223,10 +295,10 @@ private void InitializeMusic()
private void LoadTrack(int index)
{
if (index < 0 || index >= MUSIC_FILES.Count)
- {
+ {
return;
}
-
+
string filePath = MUSIC_FILES[index];
PLAYER.Open(new Uri(filePath));
@@ -247,13 +319,12 @@ private void LoadTrack(int index)
}
}
-
private void PlayMusic() => PLAYER.Play();
private void PauseMusic() => PLAYER.Pause();
private void NextTrack()
{
- if(MUSIC_FILES.Count <= 0)
+ if (MUSIC_FILES.Count <= 0)
{
return;
}
@@ -294,10 +365,7 @@ private void ReopenScrollingBorder()
else
{
openTimer.Stop();
- string filePath = MUSIC_FILES[CURRENT_TRACK_INDEX];
- string songName = System.IO.Path.GetFileNameWithoutExtension(filePath);
- ScrollingText.Text = $"🎵 Now Playing: {songName} 🎵";
- ScrollingText.Visibility = Visibility.Visible;
+ ScrollingText.Visibility = Visibility.Visible;
StartScrolling();
}
};
@@ -348,6 +416,7 @@ private void ResetApp()
{
TRAY_ICON.Visible = false;
string exePath = Process.GetCurrentProcess().MainModule.FileName;
+ SaveMasterConfig();
Process.Start(exePath);
System.Windows.Application.Current.Shutdown();
}
@@ -356,7 +425,9 @@ private void CloseApp()
{
TRAY_ICON.Visible = false;
TRAY_ICON?.Dispose();
+ MEDIA_MANAGER?.Dispose();
MASTER_TIMER.Stop();
+ SaveMasterConfig();
System.Windows.Application.Current.Shutdown();
}
private void SetupTrayIcon()
@@ -367,24 +438,62 @@ private void SetupTrayIcon()
TRAY_ICON.Text = "Jukebox";
var menu = new ContextMenuStrip();
- menu.Items.Add("Play", null, (s, e) => PlayMusic());
- menu.Items.Add("Pause", null, (s, e) => PauseMusic());
- menu.Items.Add("Next Track", null, (s, e) => NextTrack());
- var randomChar = new ToolStripMenuItem("Random Characters") { CheckOnClick = true };
+ // Save the buttons in variables so that they can be disabled/enabled later if needed
+ var playButton = new ToolStripMenuItem("Play") { Enabled = !OTHER_MEDIA_TRACKED };
+ playButton.Click += (sender, e) => PlayMusic();
+
+ var pauseButton = new ToolStripMenuItem("Pause") { Enabled = !OTHER_MEDIA_TRACKED };
+ pauseButton.Click += (sender, e) => PauseMusic();
+
+ var nextButton = new ToolStripMenuItem("Next Track") { Enabled = !OTHER_MEDIA_TRACKED };
+ nextButton.Click += (sender, e) => NextTrack();
+
+ var randomChar = new ToolStripMenuItem("Random Characters") { CheckOnClick = true, Checked = ALLOW_RANDOM_MASCOT };
randomChar.CheckedChanged += (s, e) =>
{
ALLOW_RANDOM_MASCOT = randomChar.Checked;
};
- var randomItem = new ToolStripMenuItem("Random Music") { CheckOnClick = true };
+ var randomItem = new ToolStripMenuItem("Random Music") { CheckOnClick = true, Enabled = !OTHER_MEDIA_TRACKED };
randomItem.CheckedChanged += (s, e) =>
- {
+ {
IS_RANDOM = randomItem.Checked;
};
+ var otherMediaToggle = new ToolStripMenuItem("Track Other Media") { CheckOnClick = true, Checked = OTHER_MEDIA_TRACKED };
+ otherMediaToggle.CheckedChanged += (s, e) =>
+ {
+ OTHER_MEDIA_TRACKED = otherMediaToggle.Checked;
+
+ // If the spotify tracker is enabled, stop the user from using the built in music player
+ playButton.Enabled = !OTHER_MEDIA_TRACKED;
+ pauseButton.Enabled = !OTHER_MEDIA_TRACKED;
+ nextButton.Enabled = !OTHER_MEDIA_TRACKED;
+ randomItem.Enabled = !OTHER_MEDIA_TRACKED;
+
+ // Pause the music if tracking spotify
+ if (OTHER_MEDIA_TRACKED)
+ {
+ PauseMusic();
+
+ if (MEDIA_MANAGER == null)
+ {
+ InitializeMediaManager();
+ }
+ }
+ else
+ {
+ MEDIA_MANAGER?.Dispose();
+ }
+ };
+
+ menu.Items.Add(playButton);
+ menu.Items.Add(pauseButton);
+ menu.Items.Add(nextButton);
menu.Items.Add(randomItem);
- menu.Items.Add(randomChar);
+ menu.Items.Add(randomChar);
+ menu.Items.Add(otherMediaToggle);
menu.Items.Add(new ToolStripSeparator());
menu.Items.Add("Reappear", null, (s, e) => ResetApp());
menu.Items.Add("Close", null, (s, e) => CloseApp());
@@ -403,9 +512,10 @@ public MainWindow()
LoadConfigChar();
SetupTrayIcon();
LoadSpritesSheet();
- LoadMascotList();
+ LoadMascotList();
InitializeAnimations();
InitializeMusic();
+ if (OTHER_MEDIA_TRACKED) InitializeMediaManager();
}
private void JukeBoxSprite_Click(object sender, MouseButtonEventArgs e)
{
@@ -413,8 +523,8 @@ private void JukeBoxSprite_Click(object sender, MouseButtonEventArgs e)
CURRENT_MASCOT_INDEX = (CURRENT_MASCOT_INDEX + 1) % MASCOTS.Count;
START_CHAR = MASCOTS[CURRENT_MASCOT_INDEX];
-
-
+
+
INTRO_SHEET = null;
DANCE_SHEET = null;
SpriteImage.Source = null;
@@ -429,7 +539,7 @@ private void JukeBoxSprite_Click(object sender, MouseButtonEventArgs e)
SpriteLabel.Content = $"Mascot: {START_CHAR}";
- }
+ }
private void SwitchToRandomCharacter()
{
if (MASCOTS == null || MASCOTS.Count == 0)
@@ -459,6 +569,22 @@ private void SwitchToRandomCharacter()
JukeBoxSprite.Source = null;
}
+ private void SaveMasterConfig()
+ {
+ string path = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Config.txt");
+
+ var lines = new List
+ {
+ $"START_CHAR={START_CHAR}",
+ $"ALLOW_RANDOM_MASCOT={ALLOW_RANDOM_MASCOT}",
+ $"ALLOW_MUSIC_NOTES={ALLOW_MUSIC_NOTES}",
+ $"SPRITE_SPEED={FRAME_RATE}",
+ $"TRACK_OTHER_MEDIA={OTHER_MEDIA_TRACKED}"
+ };
+
+ File.WriteAllLines(path, lines);
+ }
+
private void LoadMasterConfig()
{
string path = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Config.txt");
@@ -486,34 +612,42 @@ private void LoadMasterConfig()
switch (key.ToUpper())
{
case "START_CHAR":
- {
- START_CHAR = value;
- break;
- }
+ {
+ START_CHAR = value;
+ break;
+ }
case "ALLOW_RANDOM_MASCOT":
- {
- if (bool.TryParse(value, out bool boolValue))
{
- ALLOW_RANDOM_MASCOT = boolValue;
+ if (bool.TryParse(value, out bool boolValue))
+ {
+ ALLOW_RANDOM_MASCOT = boolValue;
+ }
+ break;
}
- break;
- }
case "ALLOW_MUSIC_NOTES":
- {
- if (bool.TryParse(value, out bool boolValue2))
{
- ALLOW_MUSIC_NOTES = boolValue2;
+ if (bool.TryParse(value, out bool boolValue2))
+ {
+ ALLOW_MUSIC_NOTES = boolValue2;
+ }
+ break;
}
- break;
- }
case "SPRITE_SPEED":
- {
- if (int.TryParse(value, out int intValue))
{
- FRAME_RATE = intValue;
+ if (int.TryParse(value, out int intValue))
+ {
+ FRAME_RATE = intValue;
+ }
+ break;
+ }
+ case "TRACK_OTHER_MEDIA":
+ {
+ if (bool.TryParse(value, out bool boolValue3))
+ {
+ OTHER_MEDIA_TRACKED = boolValue3;
+ }
+ break;
}
- break;
- }
}
}
}
diff --git a/Jukebox_Mascot/Properties/AssemblyInfo.cs b/Jukebox_Mascot/Properties/AssemblyInfo.cs
deleted file mode 100644
index a6eb798..0000000
--- a/Jukebox_Mascot/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,55 +0,0 @@
-using System.Reflection;
-using System.Resources;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-using System.Windows;
-
-// General Information about an assembly is controlled through the following
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-[assembly: AssemblyTitle("Jukebox_Mascot")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("Jukebox_Mascot")]
-[assembly: AssemblyCopyright("Copyright © 2025")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-// Setting ComVisible to false makes the types in this assembly not visible
-// to COM components. If you need to access a type in this assembly from
-// COM, set the ComVisible attribute to true on that type.
-[assembly: ComVisible(false)]
-
-//In order to begin building localizable applications, set
-//CultureYouAreCodingWith in your .csproj file
-//inside a . For example, if you are using US english
-//in your source files, set the to en-US. Then uncomment
-//the NeutralResourceLanguage attribute below. Update the "en-US" in
-//the line below to match the UICulture setting in the project file.
-
-//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]
-
-
-[assembly: ThemeInfo(
- ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
- //(used if a resource is not found in the page,
- // or application resource dictionaries)
- ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
- //(used if a resource is not found in the page,
- // app, or any theme specific resource dictionaries)
-)]
-
-
-// Version information for an assembly consists of the following four values:
-//
-// Major Version
-// Minor Version
-// Build Number
-// Revision
-//
-// You can specify all the values or you can default the Build and Revision Numbers
-// by using the '*' as shown below:
-// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/Jukebox_Mascot/icon.ico b/Jukebox_Mascot/icon.ico
new file mode 100644
index 0000000..c51d61e
Binary files /dev/null and b/Jukebox_Mascot/icon.ico differ
diff --git a/README.md b/README.md
index be6922c..76c5cf6 100644
--- a/README.md
+++ b/README.md
@@ -1,9 +1,10 @@
-# Jukebox_Mascot
+# Jukebox_Mascot 
+
A desktop jukebox mascot app built with C# (WPF), Mostly related to Umamusume, but can be edited through the spritesheet.
Perfect for having a little dancing gremlin to waste your time while procrastinating.
# Installation | Windows Only
-Download latest here: [Download](https://github.com/KurtVelasco/JukeBox/releases/download/v1.0/JukeBox_V1.0.zip)
+Download latest here: [Download](https://github.com/MojLovesApples/JukeBox/releases/download/V1.1/Jukebox_Mascot_V1.1.zip)
You can Insta-Change the character by clicking the Jukebox
@@ -17,7 +18,7 @@ ALLOW_RANDOM_MASCOT = //Change sprite for every music change
ALLOW_MUSIC_NOTES = //Show the floating music note
SPRITE_SPEED = <30...> //change the rate (milisecond) when animating the sprites
```
-
+
