如何在Spotify歌曲最小化的情况下主演它
好吧,所以Windows上的Spotify应用程序没有内置的全局热键支持,即使应用程序窗口当前处于活动状态,也没有非常基本的热键支持。令人沮丧的是,即使窗口处于活动状态,当前播放的歌曲也没有键盘快捷键。
因此,我有一个"自动热键"脚本,可以为我提供播放控制、音量和复制歌曲标题的全局热键(包括em dash修复(,但我在想如何主演当前歌曲时遇到了困难。
更困难的是,我只想让"自动热键"脚本在歌曲还没有主演的情况下主演这首歌。如果它已经主演了,那就别管它了。
我希望所有这些都发生在应用程序在托盘中时,而不打开窗口。
编辑:半工作解决方案
所以我想出了一个合理的解决方案,即使程序被最小化,它也会打开一个上下文菜单,并做所有事情,包括不乱唱歌曲。不幸的是,上下文菜单意味着它将在一瞬间最小化游戏等全屏应用程序。根据游戏的不同,这可能会很痛苦,但这是我能做的最好的事情,没有花哨的DLL调用和其他东西。
#NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases.
SendMode Input ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir% ; Ensures a consistent starting directory.
;|---------------|
;|--[ SOURCES ]--|
;|---------------|
;Base Spotify Script from: http://www.autohotkey.com/board/topic/36239-spotify-global-hotkeys/
;Base Starring Script from: http://superuser.com/questions/324416/any-spotify-tweaks-with-keyboard-shortcut-to-star-tracks
;|------------------|
;|--[ SETTING UP ]--|
;|------------------|
DetectHiddenWindows, On ;Detect Spotify even if it's minimized
#IfWinExist ahk_class SpotifyMainWindow ;Only do the following if Spotify is running
spotify = ahk_class SpotifyMainWindow ;Set variable for Spotify Window Name
;|---------------|
;|--[ HOTKEYS ]--|
;|---------------|
; "CTRL + ALT + PAGEUP" for previous
^!PGUP::
{
ControlSend, ahk_parent, ^{Left}, %spotify%
return
}
; "CTRL + ALT + PAGEDOWN" for next
^!PGDN::
{
ControlSend, ahk_parent, ^{Right}, %spotify%
return
}
; "CTRL + ALT + HOME" for pause
^!Home::
{
ControlSend, ahk_parent, {Space}, %spotify%
return
}
; "CTRL + ALT + END" for track-name
^!End::
{
WinGetTitle, spotify_playing, %spotify% ;Get the title of Spotify which contains the track-name
StringTrimLeft, trimmed_playing, spotify_playing, 10 ;Get rid of extra text and place into 'trimmed_playing'
StringReplace, replaced_playing, trimmed_playing, –, -, All ;Replace en dash with normal dash and place into 'replaced_playing'
clipboard = %replaced_playing% ;Copy the fixed text to clipboard
return
}
; "CTRL + ALT + UP" for volume up
^!Up::
{
ControlSend, ahk_parent, ^{Up}, %spotify%
return
}
; "CTRL + ALT + DOWN" for volume down
^!Down::
{
ControlSend, ahk_parent, ^{Down}, %spotify%
return
}
; "CTRL + ALT + INSERT" for starring the current song
^!Insert::
{
;Store active window and mouse position.
MouseGetPos, , , winID
;Right click near the song title in the "Now Playing" box.
WinGetPos, , , , spotifyHeight, %spotify%
clickX := 100
clickY := spotifyHeight-70
ControlClick, x%clickX% y%clickY% , %spotify%, , Right, , NA
;Get the contents of the context menu.
WinWait, ahk_class #32768
SendMessage, 0x1E1 ;MN_GETHMENU
allContextMenuInfo := ErrorLevel
;The "Star" command is the 2nd menu item.
;If the song is Unstarred the text is Star, and vice versa. But sometimes some wierd characters are included.
;The only reliable way I found is to check if the first letter is S.
menuText_StarUnstar := GetContextMenuItemText(allContextMenuInfo, 2)
StringGetPos, positionOfS, menuText_StarUnstar, S
;If S is the first letter, star the song.
notStarred := (%positionOfS% = 0)
If notStarred
{
;Arrow down to the Star menu item and press enter.
ControlSend, ahk_parent, {Down}{Down}{Enter}, %spotify%
}
Else
{
;Just close the context menu.
ControlSend, ahk_parent, {Escape}, %spotify%
}
;Restore original window and mouse position.
WinActivate ahk_id %winID%
return
}
;|-----------------|
;|--[ FUNCTIONS ]--|
;|-----------------|
;Context menu helper function.
GetContextMenuItemText(hMenu, nPos)
{
length := DllCall("GetMenuString"
, "UInt", hMenu
, "UInt", nPos
, "UInt", 0 ; NULL
, "Int", 0 ; Get length
, "UInt", 0x0400) ; MF_BYPOSITION
VarSetCapacity(lpString, length + 1)
length := DllCall("GetMenuString"
, "UInt", hMenu
, "UInt", nPos
, "Str", lpString
, "Int", length + 1
, "UInt", 0x0400)
return lpString
}
我修改了一些隐藏在互联网上的现有脚本。其源代码可以在源代码的顶部找到,如果有人想尝试在不出现上下文菜单的情况下使其完全工作,这可能会有所帮助。
正常使用该应用程序时,如何才能播放歌曲
在Spotify上,似乎只有两条路可以让一首歌成为明星。
- 右键单击左下角的相簿艺术,然后使用星形上下文菜单选项
- 右键单击播放列表中的歌曲,然后使用星形上下文菜单选项
为了让事情变得尴尬,如果某个东西已经是星形的,那么星形菜单选项将在完全相同的位置用unstar菜单选项替换。当菜单打开时,它们也有相同的快捷键(t键(。因此,如果不先进行某种检查,就不能只进行盲菜单选择。
那么,我们可以走哪些可能的路线呢
右键单击左下角的相册艺术是唯一逼真的路线。
如果我们可以在最小化的情况下从上下文菜单中读取文本,我们就可以判断文本从"星号"变为"unstar"是否已经标记了某个内容。测试之后,我们可以决定是否按T键来真正主演这首歌。
我还花了一些时间与Window Detective合作,看看我是否可以发送一个相对简单的PostMessage/SendMessage来主演这首歌。但我的经验很少,我不知道如何将它们结合在一起才能得到我想要的结果。
我发现星号和unstar上下文菜单选项实际上是不同的:
Star -> WM_MENUSELECT (0x11F) | item identifier = 11 | flags = NONE | MF_HILITE
Unstar -> WM_MENUSELECT (0x11F) | item identifier = 12 | flags = NONE | MF_HILITE
然而,我不知道如何将PostMessages/SendMessages链接在一起打开菜单,然后只选择项目#11,然后点击回车键。
Spotify在主演某些内容时收到的消息列表
以防万一,这有助于确定是否可以进行PostMessage/SendMessage路由。
->WM_RBUTTONDOWN (0x204)
->WM_RBUTTONUP (0x205)
->WM_MENUSELECT (0x11F)
<-WM_MENUSELECT (0x11F)
->WM_KEYDOWN (0x100)
->WM_MENUSELECT (0x11F)
<-WM_MENUSELECT (0x11F)
->WM_KEYUP (0x101)
后记
我已经搜索了一段时间,试图找到PostMessages/SendMessages用于进行这种上下文菜单选择的好例子,但没有找到任何东西。
谢谢你抽出时间。
当前自动热键脚本
#NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases.
SendMode Input ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir% ; Ensures a consistent starting directory.
; "CTRL + ALT + PAGEUP" for previous
^!PGUP::
{
DetectHiddenWindows, On
ControlSend, ahk_parent, ^{Left}, ahk_class SpotifyMainWindow
DetectHiddenWindows, Off
return
}
; "CTRL + ALT + PAGEDOWN" for next
^!PGDN::
{
DetectHiddenWindows, On
ControlSend, ahk_parent, ^{Right}, ahk_class SpotifyMainWindow
DetectHiddenWindows, Off
return
}
; "CTRL + ALT + HOME" for pause
^!Home::
{
DetectHiddenWindows, On
ControlSend, ahk_parent, {space}, ahk_class SpotifyMainWindow
DetectHiddenWindows, Off
return
}
; "CTRL + ALT + END" for info
^!End::
{
DetectHiddenWindows, On
WinGetTitle, spotify_playing, ahk_class SpotifyMainWindow
DetectHiddenWindows, Off
StringTrimLeft, trimmed_playing, spotify_playing, 10
StringReplace, replaced_playing, trimmed_playing, –, -, All
clipboard = %replaced_playing%
return
}
; "CTRL + ALT + UP" for volume up
^!Up::
{
DetectHiddenWindows, On
ControlSend, ahk_parent, ^{Up}, ahk_class SpotifyMainWindow
DetectHiddenWindows, Off
return
}
; "CTRL + ALT + DOWN" for volume down
^!Down::
{
DetectHiddenWindows, On
ControlSend, ahk_parent, ^{Down}, ahk_class SpotifyMainWindow
DetectHiddenWindows, Off
return
}
/*
PLAN: I want to make this star the current song if it's unstarred
NOTES:
WM_MENUSELECT for star seems to be item identifier 11, unstar is 12
Star -> WM_MENUSELECT (0x11F) | item identifier = 11 | flags = NONE | MF_HILITE
Unstar -> WM_MENUSELECT (0x11F) | item identifier = 12 | flags = NONE | MF_HILITE
*/
; "CTRL + ALT + INSERT" for starring the current song
^!Insert::
{
DetectHiddenWindows, On
DetectHiddenWindows, Off
return
}
我目前在玩游戏时使用的一个非常简单:
MouseGetPos, x, y, origwin
WinActivate, ahk_class SpotifyMainWindow
click 183, 1000 ;
WinActivate, ahk_id %origwin%
MouseMove, %x%, %y%
一个巧妙的替代你的其他代码;Spotify对媒体按钮做出响应,因此这些按钮非常有效:
^!Left::Media_Prev
^!Right::Media_Next
^!Up::Volume_Up
^!Down::Volume_Down
^!Space::Media_Play_Pause
编辑:Spotify改变了他们的布局。+随歌曲标题的长度移动。为了让它更稳定地工作,我将功能更改为右键单击并"保存到您的音乐中">
FavouriteSpotifySong()
{
WinGetPos, , , SPOTIFY_X_AXIS, SPOTIFY_Y_AXIS, ahk_class SpotifyMainWindow
yPos := SPOTIFY_Y_AXIS - 30
ControlClick, X25 Y%yPos%, ahk_class SpotifyMainWindow,, RIGHT
Sleep 75
yPos -= 54
ControlClick, X33 Y%yPos%, ahk_class SpotifyMainWindow
}
SpotifyLove(flag)
{
WinGetActiveTitle, CurOpen
MouseGetPos, MouseX, MouseY
IfWinExist ahk_exe Spotify.exe ; check if spotify is open
winactivate ahk_exe Spotify.exe
else
return
WinWait ahk_exe Spotify.exe
Click, 65 940 0; Spotify has a 60x60 pixel window with the menu in the top left corner. I have not find another way to activate the the main window except for this click. Any other solutions to are much appreciated.
WinGetPos, X, Y, W, H, A ; get the dimensions of the spotify window
; start searching for image in a rectangle. The first point of the rectangle X1,Y1 is 100 pixels above the bottom left corner. The other point of the rectangle X2,Y2 is 600 pixels right of the left edge and along the bottom of the window.
X1 := 0
X2 := 600
Y1 := H - 100
Y2 := H
; imagesearch is really crappy. *70 gives the function some leeway to find the right image in the window. We are searching for the heart.
ImageSearch, OutputVarX, OutputVarY, X1, Y1, X2, Y2, *70 Z:Picturesheart.jpg
; click on heart if we like the song, click on the dislike button and "i dont like this song" otherwise.
A := OutputVarX+15
B := OutputVarY+15
if (flag == 1)
{
Click, %A% %B%
}
else {
HateX := OutputVarX+50
DontLikeSongX := HateX+10
DontLikeSongY := OutputVarY-10
Click, %HateX%, %OutputVarY%
Sleep, 200
Click, %DontLikeSongX%, %DontLikeSongY%
}
; return to previous window with the same mouse position.
WinRestore, %CurOpen%
WinMaximize, %CurOpen%
WinActivate, %CurOpen%
MouseMove, %MouseX%, %MouseY%
}
^+S::
SpotifyLove(1)
Return
;^+d::
;SpotifyLove(0)
;Return
我很久以前在AutoHotKey论坛上发现了这个,最近又回到了AutoHotKey,不得不重新调整,花了一个小时才把它做好。它仍然不完美,因为它正在使用ImageSearch。一定要从spotify应用程序中截取一段空心的片段,并提到它到JPG的路径(在空心截图图像周围尽可能少地使用边框(,并提到其路径。它在95%的情况下都是正确的,但也不能消除短暂打开spotify应用程序的问题,因此在游戏中不太有用。我评论了不喜欢这首歌的部分,因为它根本不起作用。
我设置的快捷方式是:;Ctrl+Shift+S";
编辑:添加Spotify Windows应用程序中empty_cheart的链接。(https://i.stack.imgur.com/0ttCS.jpg)
请记住,由于Spotify中不同标题长度的心脏位置不断变化,因此准确率只有95%左右
在发布这篇文章时,Spotify的当前用户界面也应该在上面的imgur链接中可见。