Skip to content

Instantly share code, notes, and snippets.

@bowbahdoe
Last active July 18, 2019 00:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bowbahdoe/86921ce07587ea597e43ba6e965817a4 to your computer and use it in GitHub Desktop.
Save bowbahdoe/86921ce07587ea597e43ba6e965817a4 to your computer and use it in GitHub Desktop.
import ctypes
import time
from pycaw.pycaw import AudioUtilities
import platform
class SpotifyMonitor:
@property
def author(self):
try:
return self._get_info()[0]
except:
return None
@property
def song(self):
try:
return self._get_info()[1]
except:
return None
class WindowsSpotifyMonitor(AbstractSpotifyMonitor):
def _get_info():
import win32gui
windows = []
# Older Spotify versions - simply FindWindow for "SpotifyMainWindow"
windows.append(win32gui.GetWindowText(win32gui.FindWindow("SpotifyMainWindow", None)))
# Newer Spotify versions - create an EnumHandler for EnumWindows and flood the list with Chrome_WidgetWin_0s
def find_spotify_uwp(hwnd, windows):
text = win32gui.GetWindowText(hwnd)
if win32gui.GetClassName(hwnd) == "Chrome_WidgetWin_0" and len(text) > 0:
windows.append(text)
win32gui.EnumWindows(find_spotify_uwp, windows)
while windows.count != 0:
try:
text = windows.pop()
except:
return None
try:
artist, track = text.split(" - ", 1)
return artist, track
except:
pass
@property
def is_advertisement_playing(self):
EnumWindows = ctypes.windll.user32.EnumWindows
EnumWindowsProc = ctypes.WINFUNCTYPE(ctypes.c_bool, ctypes.POINTER(ctypes.c_int), ctypes.POINTER(ctypes.c_int))
GetWindowText = ctypes.windll.user32.GetWindowTextW
GetWindowTextLength = ctypes.windll.user32.GetWindowTextLengthW
IsWindowVisible = ctypes.windll.user32.IsWindowVisible
####### Modules to gather data
titles = [] #Empty list for titles (As String Objects)
def foreach_window(hwnd, lParam):
if IsWindowVisible(hwnd):
length = GetWindowTextLength(hwnd)
buff = ctypes.create_unicode_buffer(length + 1)
GetWindowText(hwnd, buff, length + 1)
titles.append(buff.value)
return True
EnumWindows(EnumWindowsProc(foreach_window), 0)
return "Advertisement" in titles or "Spotify" in titles
class MacSpotifyMonitor(AbstractSpotifyMonitor):
def _get_info():
from Foundation import NSAppleScript
apple_script_code = """
getCurrentlyPlayingTrack()
on getCurrentlyPlayingTrack()
tell application "Spotify"
set currentArtist to artist of current track as string
set currentTrack to name of current track as string
return {currentArtist, currentTrack}
end tell
end getCurrentlyPlayingTrack
"""
s = NSAppleScript.alloc().initWithSource_(apple_script_code)
x = s.executeAndReturnError_(None)
a = str(x[0]).split('"')
return a[1], a[3]
class LinuxSpotifyMonitor(AbstractSpotifyMonitor):
def _get_info():
import dbus
session_bus = dbus.SessionBus()
spotify_bus = session_bus.get_object("org.mpris.MediaPlayer2.spotify",
"/org/mpris/MediaPlayer2")
spotify_properties = dbus.Interface(spotify_bus,
"org.freedesktop.DBus.Properties")
metadata = spotify_properties.Get("org.mpris.MediaPlayer2.Player", "Metadata")
track = str(metadata['xesam:title'])
artist = str(metadata['xesam:artist'][0])
return artist, track
def get_monitor():
if platform.system() == "Windows":
return WindowsSpotifyMonitor()
elif platform.system() == "Darwin":
return MacSpotifyMonitor()
else:
return LinuxSpotifyMonitor()
monitor = get_monitor()
while True:
time.sleep(5)
if monitor.is_advertisement_playing:
sessions = AudioUtilities.GetAllSessions()
for session in sessions:
volume = session.SimpleAudioVolume
volume.SetMute(1, None)
else:
sessions = AudioUtilities.GetAllSessions()
for session in sessions:
volume = session.SimpleAudioVolume
volume.SetMute(0, None)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment