如何触发Windows音量显示?

8

当在Windows上按下标准键盘增加音量的键时,会出现一个小窗口在左上角显示音量以及可能有关正在播放媒体的信息。我正在寻找一种方法来触发该窗口而不改变音量状态,最好能够轻松地与Autohotkey集成。


1
@ifconfig 最终目标是通过使用SoundSet(+1)将音量增加1%并显示标准音量OSD。我已经使音量更改工作,但它不会触发音量显示,因此出现了这个问题。您建议的切换音量上下会将音量舍入为偶数,从而无法更改音量。切换静音,另一种带来显示的方法会导致音频中断。我正在寻找一种命令或dll或某种非键盘输入方式来显示音量。 - Matthew Sundberg
2
@ifconfig,问题在于如果音量从12开始(记住媒体键会四舍五入),然后你向上切换(将其四舍五入为14),然后向下切换(回到12),然后使用AHK加1,变成13,下一次尝试通过向上切换增加音量时,它会四舍五入为14,然后回到12,然后你又回到了13。这就是为什么我想要绕过媒体键,仅使用AHK SoundSet的+/-1来改变音量。因此,如何在“不改变音量状态”的情况下显示音量显示器,这就是我的问题。 - Matthew Sundberg
我不知道是否有一种方法可以仅显示窗口,但我知道用于与媒体播放方面交互的API仅适用于存储应用程序,而不是桌面应用程序。 - Anders
@Anders,尽管你不知道如何做到这一点,但我认为这是一个完全有效的问题。但它更多地与WinAPI相关,而不是AutoHotkey特定的。 - LogicDaemon
1
@LogicDaemon 我从未说过它无效,我只是认为与之相关的文档化API仅适用于现代应用程序。 - Anders
显示剩余5条评论
4个回答

4

Windows 8引入了Media​Control class,允许现代应用程序连接到系统播放控制。在Windows 8.1和10中,它被System​Media​Transport​Controls class所取代。

虽然它支持“手动控制系统媒体传输控件”,但似乎没有一种方法可以显示/隐藏叠加层,特别是不能从桌面应用程序中实现。

在未记录的领域中,我找到了叠加层的类名,从而找到了HideVolumeOSD。不幸的是,类名相当通用,因此您可能还需要查看窗口的大小才能确定是否为音量叠加层。

我不知道只是显示窗口是否有效,Windows不希望它可见,除非响应键盘和播放事件。HideVolumeOSD应用程序使用keybd_event(音量增加/减少)来触发它,但正如评论中所指出的那样,这会有问题...


2

我设置了一个AutoHotkey脚本,用于发送音量增加和音量减小的命令(使用快捷键ctrl+pgdn)。

^PgDn::
   Send {Volume_Up}
   Send {Volume_Down}
   return     

很不幸,如果将其设置为奇数值,这将破坏当前的音量,因为“Volume_Up”和“Volume_Down”会将当前音量四舍五入然后增加2,正如问题评论中所提到的那样。例如,从音量13开始,“Volume_Up”会四舍五入到14,然后增加到16,然后“Volume_Down”将其设置为14,从而改变了初始值。 - Matthew Sundberg

1
使用音量控制键时所需的行为可以通过存储当前音量,发送媒体按键,然后将音量更新为存储值+/- 1(或+0,如果只是寻求显示OSD)来实现。
当音量<=3时模拟“音量减小”存在一种特殊情况。发送的“音量减小”按键触发静音,但可以通过手动将静音设置为关闭,或预设音量为4来适应这种情况,从而防止舍入为0.选择哪种方法取决于您喜欢短暂的可能更大声音(预设为4)还是在将音量降低到<=3的值时进行短暂的静音(关闭静音后)。
以下代码使用AHK v2。
; Prefix with '$' so as to prevent self triggering, since internally sending Volume_Up
$Volume_Up::{
    ; Get the current volume. SoundGetVolume returns a float which often needs rounding
    volume:=Round(SoundGetVolume())
    ; Send the Volume_Up key, so the media display is triggered
    Send "{Volume_Up}"
    ; Indiscriminately set the volume manually to volume+1
    SoundSetVolume(volume+1)
}

; Much the same as above, yet when sending Volume_Down at volumes <=3 the volume
;   is rounded down to 0 which triggers mute. The volume is then set properly,
;   yet remains muted. In order to not hear a cut in the audio, you need to set
;   the volume to 4 when (1<volume<=3) so that the Volume_Down doesn't round it
;   down to 0, or disable the mute afterwards (if volume > 1). This causes a
;   brief volume spike or mute blip, respectively. Currently the volume spike option
;   is uncommented.
$Volume_Down::{
    volume:=Round(SoundGetVolume())

    ; Bumping the volume before sending the Volume_Down to prevent mute blip (if needed)
    if(1 < volume and volume <= 3){
        SoundSetVolume(4)
    }

    Send "{Volume_Down}"
    SoundSetVolume(volume-1)

    ; ; Disable accidental triggering of mute when volume >= 3 after sending Volume_Down
    ; if(volume > 1) {
    ;   SoundSetMute(0)
    ; }
}

如问题所问,只需按以下步骤触发OSD。按音量键,然后快速重置音量即可显示它,但如果当前静音,则需要考虑以防止声音中断。由于双重切换Volume_Mute会导致声音输出间隙,因此使用音量键。

; Trigger the on screen display of the volume bar by hitting Volume_Up and
;   then quickly resetting the volume. If muted and send Volume_Up, we will
;   hear audio at original volume for a brief second. To prevent this, we
;   can set the volume to 0 and send Volume_Down instead.
^PgUp::{
    volume:=Round(SoundGetVolume())
    muted:=SoundGetMute()

    ; Trigger the display with a volume key (might briefly bump the volume if unmuted)
    if (muted or volume == 0) {
        SoundSetVolume(0)
        Send "{Volume_Down}"
    } else {
        Send "{Volume_Up}"
    }

    ; Reset to the original volume and mute status
    SoundSetMute(muted)
    SoundSetVolume(volume)
}

所有的代码都是一样的,只是没有注释:
$Volume_Up::{
    volume:=Round(SoundGetVolume())
    Send "{Volume_Up}"
    SoundSetVolume(volume+1)
}

$Volume_Down::{
    volume:=Round(SoundGetVolume())
    if(1 < volume and volume <= 3){
        SoundSetVolume(4)
    }
    Send "{Volume_Down}"
    SoundSetVolume(volume-1)
}

^PgUp::{
    volume:=Round(SoundGetVolume())
    muted:=SoundGetMute()
    if (muted or volume == 0) {
        SoundSetVolume(0)
        Send "{Volume_Down}"
    } else {
        Send "{Volume_Up}"
    }
    SoundSetMute(muted)
    SoundSetVolume(volume)
}

0

在Anna Wang的回答(https://dev59.com/yqPia4cB1Zd3GeqP5OLp#62012058)的基础上进行构建。

即使音量值为奇数,这将恢复该音量。

^PgDn:: ;Ctrl+Page Down
  SoundGet, original_volume
  SendInput {Volume_Down}  
  SoundSet, original_volume
return

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接