在Python中使用Mac的语音输入

5 投票
2 回答
3510 浏览
提问于 2025-04-20 09:17

有没有人知道怎么用Mac自带的语音输入工具来创建可以在Python中使用的字符串?

要启动语音输入,你需要在任何文本编辑器里双击Fn键。如果是这样,有没有办法把这个按键命令和输入命令结合起来?比如说:

第一步:模拟双击Fn键,启动语音输入工具,然后 第二步:使用语音转文本的内容来创建一个变量,也就是 text_string = input(“开始语音输入:”)

在这个讨论串里(我可以在没有图形界面的情况下使用OS X 10.8的语音识别/语音输入吗?),有个用户说他用 CGEventCreateKeyboardEvent(src, 0x3F, true) 找到了办法,但没有提供代码。

有没有什么想法?如果能提供代码示例就更好了。

更新:感谢下面的建议,我已经导入了AppScript。我试着写了这样的代码,但没有成功:

from appscript import app, its
se = app('System Events')
proc = app.processes[its.frontmost == True]
mi = proc.menu_bars[1].menu_bar_items['Edit'].menus[1].menu_items['Start Dictation']
user_voice_text = input(mi.click())
print(user_voice_text)

有没有办法让我打开语音输入工具,让它作为字符串的输入?

更新2:

这是我想要创建的程序的一个简单示例:

Ideally i want to launch the program, and then have it ask me: "what is 1 + 1?"
Then I want the program to turn on the dictation tool, and I want the program to record my voice, with me answering "two".
The dictation-to-text function will then pass the string value = "two" to my program, and an if statement is then used to say back "correct" or "incorrect".

我想在不使用键盘输入的情况下给程序传递命令。

2 个回答

-1

苹果的语音输入政策是封闭的。只有苹果公司才能编写使用语音输入等辅助技术的代码。如果你想写出能实现你想要功能的代码,那就换用Linux系统吧。

3

首先,FnFn 语音输入是 NSText(或者可能是 NSTextView)这个 Cocoa 控件的一个功能。如果你有这样的控件,语音输入的文本会被插入到这个控件中。(它还会使用控件中已有的文本作为上下文。)从使用 NSTextView 的应用程序的角度来看,如果你只是创建一个标准的编辑菜单,开始语音输入的选项会被添加到菜单的最后面,并且 FnFn 是一个快捷键,任何被语音输入的内容都会像键盘输入、粘贴或拖动的内容一样出现在控件中。

所以,如果你没有图形用户界面(GUI)应用程序,启用语音输入就没有意义,因为你没有办法接收输入。

如果你有一个 GUI 应用程序,最简单的方法就是通过 NSMenu 获取菜单项,然后点击这个选项。

你几乎肯定在使用某种 GUI 库,比如 PyQt 或 Tkinter,这些库有自己访问应用程序菜单的方法。如果没有,你可以直接通过 Cocoa 来实现(使用 PyObjC——这个是苹果预装的 Python 中自带的,但如果你使用的是第三方 Python,你需要 pip install 安装它):

import AppKit
mb = AppKit.NSApp.mainMenu()
edit = mb.itemWithTitle_('Edit').submenu()
sd = edit.indexOfItemWithTitle_('Start Dictation')
edit.performActionForItemAtIndex_(sd)

但是如果你在终端中运行一个控制台程序(无论是 Terminal.app 还是像 iTerm 这样的替代品),你运行的应用程序有自己的文本控件和编辑菜单,你可以利用它的菜单。

问题是,除非用户允许,否则你没有权限去控制其他应用程序。在旧版本的 OS X 中,只需全局开启“辅助脚本以便无障碍访问”即可。从 10.10 开始,系统偏好设置的安全与隐私选项卡中有一个无障碍选项,列出了拥有权限的应用程序。幸运的是,如果你的应用不在列表中,第一次尝试使用无障碍功能时,会弹出一个对话框,如果用户点击它,会打开系统偏好设置,显示那个选项,并把你的应用添加到列表中,复选框是禁用的,用户只需点击复选框即可。

实现这个功能的 AppleScript 是:

tell application "System Events"
    click (menu item "Start Dictation" of menu of menu bar item "Edit" 
        of menu bar of (first process whose frontmost is true))
end tell

在 Python 中实现相同功能的“正确”方法是通过 ScriptingBridge,你可以通过 PyObjC 访问它……但使用第三方库 appscript 会简单得多:

from appscript import app, its
se = app('System Events')
proc = app.processes[its.frontmost == True]
mi = proc.menu_bars[1].menu_bar_items['Edit'].menus[1].menu_items['Start Dictation']
mi.click()

如果你真的想要发送 Fn 键两次,生成和发送键盘事件的 API 是 Quartz 事件服务 的一部分,虽然这是一个 CoreFoundation 的 C API,而不是 Cocoa 的 ObjC API,但它也被 PyObjC 封装了。文档可能有点难以理解,但基本上,思路是你创建一个合适类型的事件,然后将其发送到特定的应用程序、事件捕捉点或捕捉位置。因此,你可以这样创建并发送一个系统范围的 Fn 键按下事件:

evt = Quartz.CGEventCreateKeyboardEvent(None, 63, True)
Quartz.CGEventPost(Quartz.kCGSessionEventTap, evt)

要发送一个键抬起事件,只需将 True 改为 False

撰写回答