屏幕保护程序结束后音频继续播放
Audio keeps playing after screensaver ends
我正在制作带有(可选)音频的屏幕保护程序。但是每当我通过滑动鼠标停用它时,音频都会继续播放几秒钟。但是,在系统首选项中单击预览时不会发生这种情况。我的理论是,当在预览中移动鼠标时,屏幕保护进程会立即被终止,但当它不是 运行 预览时则不会。有没有一种方法可以让我感应到鼠标 activity 并通过 运行 函数自行停止音频?
我在下面提供了一些代码:
https://gist.github.com/MaxTechnics/3d4280fabc4da53b6df1022864d1bf23
如果需要,将提供更多。提前致谢!
更新:我认为这是问题的主要部分,因为音频永远不会及时停止
// MARK: - Lifecycle
extension VideoView {
override func startAnimation() {
super.startAnimation()
manager.player.play()
}
override func stopAnimation() {
super.stopAnimation()
manager.player.pause()
}
}
经过一些调整后,虽然我们无法拦截键盘(也不应该可靠地检测到退出),但实际上可以在屏幕保护程序中收听一些分布式通知,告诉我们用户何时登录,并使用它来调用我们的代码以停止 animations/sound,因为在我们被有效杀死和用户返回桌面之间存在相当大的延迟。
我确实在此处的此答案中找到了一些事件:Monitoring Screensaver Events in OSX 虽然它有点过时,但这些事件仍然会被触发,并且可以在屏幕保护程序中拦截,尽管有沙盒。我确实发现了一些新的,尽管它们可能对其他用途很有趣。
无论如何,这对我有用:
class AerialView: ScreenSaverView {
...
func setNotifications {
DistributedNotificationCenter.default.addObserver(self, selector: #selector(AerialView.willStop(_:)), name: Notification.Name("com.apple.screensaver.willstop"), object: nil)
}
@objc func willStop(_ aNotification: Notification) {
NSLog("############ willStop")
// Put your stop audio/animation code here
}
}
(您必须自己调用 setNotifications 或将该代码放在其他地方)。
实际上,有多个事件在屏幕保护程序退出时一个接一个地触发:
com.apple.screensaver.willstop
com.apple.screensaver.didstop
com.apple.screenIsUnlocked
com.apple.screenLockUIIsShown
这是这些事件的一些记录
2021-04-27 14:52:00.564 : ############ screenLockUIIsShown
2021-04-27 14:52:01.873 : ############ screenIsUnlocked
2021-04-27 14:52:01.873 : ############ willStop
2021-04-27 14:52:01.879 : ############ didStop
第一个事件是我按下一个键,大约1.5秒后手表解锁解锁屏幕,你可以看到3个事件被连续触发。
在那种情况下,屏幕保护程序的实际终止只发生在 14:52:07。
为了完整起见,一些新事件用于检测登录 UI 何时启动和关闭(可能对其他一些事情有用)。这是在 11.4 中,我不知道这些事件是否在以前版本的 macOS 中触发。按射击顺序:
com.apple.shieldWindowRaised
com.apple.screenIsLocked
com.apple.screenLockUIIsShown
com.apple.screenLockUIIsHidden
com.apple.shieldWindowLowered
com.apple.screenIsUnlocked
我正在制作带有(可选)音频的屏幕保护程序。但是每当我通过滑动鼠标停用它时,音频都会继续播放几秒钟。但是,在系统首选项中单击预览时不会发生这种情况。我的理论是,当在预览中移动鼠标时,屏幕保护进程会立即被终止,但当它不是 运行 预览时则不会。有没有一种方法可以让我感应到鼠标 activity 并通过 运行 函数自行停止音频? 我在下面提供了一些代码: https://gist.github.com/MaxTechnics/3d4280fabc4da53b6df1022864d1bf23 如果需要,将提供更多。提前致谢!
更新:我认为这是问题的主要部分,因为音频永远不会及时停止
// MARK: - Lifecycle
extension VideoView {
override func startAnimation() {
super.startAnimation()
manager.player.play()
}
override func stopAnimation() {
super.stopAnimation()
manager.player.pause()
}
}
经过一些调整后,虽然我们无法拦截键盘(也不应该可靠地检测到退出),但实际上可以在屏幕保护程序中收听一些分布式通知,告诉我们用户何时登录,并使用它来调用我们的代码以停止 animations/sound,因为在我们被有效杀死和用户返回桌面之间存在相当大的延迟。
我确实在此处的此答案中找到了一些事件:Monitoring Screensaver Events in OSX 虽然它有点过时,但这些事件仍然会被触发,并且可以在屏幕保护程序中拦截,尽管有沙盒。我确实发现了一些新的,尽管它们可能对其他用途很有趣。
无论如何,这对我有用:
class AerialView: ScreenSaverView {
...
func setNotifications {
DistributedNotificationCenter.default.addObserver(self, selector: #selector(AerialView.willStop(_:)), name: Notification.Name("com.apple.screensaver.willstop"), object: nil)
}
@objc func willStop(_ aNotification: Notification) {
NSLog("############ willStop")
// Put your stop audio/animation code here
}
}
(您必须自己调用 setNotifications 或将该代码放在其他地方)。
实际上,有多个事件在屏幕保护程序退出时一个接一个地触发:
com.apple.screensaver.willstop
com.apple.screensaver.didstop
com.apple.screenIsUnlocked
com.apple.screenLockUIIsShown
这是这些事件的一些记录
2021-04-27 14:52:00.564 : ############ screenLockUIIsShown
2021-04-27 14:52:01.873 : ############ screenIsUnlocked
2021-04-27 14:52:01.873 : ############ willStop
2021-04-27 14:52:01.879 : ############ didStop
第一个事件是我按下一个键,大约1.5秒后手表解锁解锁屏幕,你可以看到3个事件被连续触发。
在那种情况下,屏幕保护程序的实际终止只发生在 14:52:07。
为了完整起见,一些新事件用于检测登录 UI 何时启动和关闭(可能对其他一些事情有用)。这是在 11.4 中,我不知道这些事件是否在以前版本的 macOS 中触发。按射击顺序:
com.apple.shieldWindowRaised
com.apple.screenIsLocked
com.apple.screenLockUIIsShown
com.apple.screenLockUIIsHidden
com.apple.shieldWindowLowered
com.apple.screenIsUnlocked