🎯 告别打字!Ubuntu 20.04 语音转文字完整教程 - 高精确度的离线方案

575 阅读5分钟

官方仓库:github.com/ideasman42/…

效果展示

image.png

🎤 完整中文语音输入系统安装教程

最强大的离线中文语音识别方案 - 支持开始/暂停/恢复/结束/取消五大功能

📋 功能概览

功能快捷键说明
🟢 开始录音Ctrl+Alt+HHello - 开始新的语音录制
🔴 结束录音Ctrl+Alt+UUnit - 结束录制并输出文字
❌ 取消录音Ctrl+Alt+Shift+CCancel - 取消当前录制
⏸️ 暂停录音Ctrl+Alt+Shift+HHalt - 暂停当前录制,可恢复
▶️ 恢复录音Ctrl+Alt+Shift+UUn-pause - 恢复暂停的录制

🚀 一键安装脚本

将下面的脚本保存为 install_voice_input.sh 并执行:

如图(路径随便,在相应路径运行即可)

image.png

#!/bin/bash
# 完整中文语音输入系统一键安装脚本
# 使用方法:bash install_voice_input.sh

set -e

USER_HOME="/home/$USER"
NERD_DIR="$USER_HOME/Downloads/nerd-dictation"
CONFIG_DIR="$USER_HOME/.config/nerd-dictation"
SCRIPTS_DIR="$USER_HOME/bin/voice-input"

echo "🎤 开始安装完整中文语音输入系统..."

# =================== 第1步:安装系统依赖 ===================
echo "📦 第1步:安装系统依赖..."
sudo apt update
sudo apt install -y python3 python3-pip git wget unzip pulseaudio-utils xdotool xclip xbindkeys notify-osd

# =================== 第2步:安装 Python 依赖 ===================
echo "🐍 第2步:安装 Python 依赖..."
pip3 install vosk sounddevice

# =================== 第3步:下载 nerd-dictation ===================
echo "📥 第3步:下载 nerd-dictation..."
mkdir -p "$(dirname "$NERD_DIR")"
if [ ! -d "$NERD_DIR" ]; then
    cd ~/Downloads
    git clone https://github.com/ideasman42/nerd-dictation.git
fi

# =================== 第4步:下载最强中文模型 ===================
echo "🧠 第4步:下载最强中文识别模型 (vosk-model-cn-0.22)..."
cd "$NERD_DIR"

# 如果模型不存在则下载
if [ ! -d "$CONFIG_DIR/model" ]; then
    echo "正在下载 1.5GB 的高精度中文模型,请耐心等待..."
    
    # 下载大型高精度中文模型
    wget -c https://alphacephei.com/vosk/models/vosk-model-cn-0.22.zip
    
    # 解压并配置
    unzip -o vosk-model-cn-0.22.zip
    mkdir -p "$CONFIG_DIR"
    mv vosk-model-cn-0.22 "$CONFIG_DIR/model"
    rm -f vosk-model-cn-0.22.zip
    
    echo "✅ 高精度中文模型安装完成!"
else
    echo "✅ 中文模型已存在,跳过下载"
fi

# =================== 第5步:创建脚本目录 ===================
echo "📁 第5步:创建脚本目录..."
mkdir -p "$SCRIPTS_DIR"

# =================== 第6步:创建状态管理脚本 ===================
echo "⚙️ 第6步:创建功能脚本..."

# 状态文件路径
STATE_FILE="$CONFIG_DIR/recording_state"
LOG_FILE="$CONFIG_DIR/voice_input.log"

# 通用函数脚本
cat > "$SCRIPTS_DIR/common_functions.sh" << 'EOF'
#!/bin/bash
# 语音输入通用函数

STATE_FILE="$HOME/.config/nerd-dictation/recording_state"
LOG_FILE="$HOME/.config/nerd-dictation/voice_input.log"
NERD_DIR="$HOME/Downloads/nerd-dictation"

# 记录日志
log_message() {
    echo "$(date '+%Y-%m-%d %H:%M:%S'): $1" >> "$LOG_FILE"
}

# 获取当前状态
get_recording_state() {
    if [ -f "$STATE_FILE" ]; then
        cat "$STATE_FILE"
    else
        echo "idle"
    fi
}

# 设置状态
set_recording_state() {
    echo "$1" > "$STATE_FILE"
    log_message "状态变更: $1"
}

# 检查进程是否运行
is_nerd_running() {
    pgrep -f "nerd-dictation begin" > /dev/null
}

# 获取活动窗口
save_active_window() {
    xdotool getactivewindow > "$HOME/.config/nerd-dictation/active_window" 2>/dev/null || echo "0" > "$HOME/.config/nerd-dictation/active_window"
}

# 恢复活动窗口
restore_active_window() {
    if [ -f "$HOME/.config/nerd-dictation/active_window" ]; then
        WINDOW_ID=$(cat "$HOME/.config/nerd-dictation/active_window")
        if [ "$WINDOW_ID" != "0" ]; then
            xdotool windowactivate "$WINDOW_ID" 2>/dev/null || true
        fi
    fi
}
EOF

# 1. 开始录音脚本
cat > "$SCRIPTS_DIR/start_recording.sh" << 'EOF'
#!/bin/bash
source "$HOME/bin/voice-input/common_functions.sh"

current_state=$(get_recording_state)

if [ "$current_state" = "recording" ]; then
    notify-send "🎤 语音输入" "已在录音中,请使用 Ctrl+Alt+Shift+H 暂停" -i dialog-warning -t 2000
    exit 1
elif [ "$current_state" = "paused" ]; then
    notify-send "🎤 语音输入" "请使用 Ctrl+Alt+Shift+U 恢复录音" -i dialog-warning -t 2000
    exit 1
fi

cd "$NERD_DIR"

# 保存当前活动窗口
save_active_window

# 开始录音
./nerd-dictation begin --vosk-model-dir="$HOME/.config/nerd-dictation/model" > /dev/null 2>&1 &

if [ $? -eq 0 ]; then
    set_recording_state "recording"
    notify-send "🎤 语音输入" "开始录音 - 按 Ctrl+Alt+Shift+H 暂停" -i audio-input-microphone -t 2000
    log_message "开始录音成功"
else
    notify-send "🎤 语音输入" "启动录音失败" -i dialog-error -t 3000
    log_message "开始录音失败"
    exit 1
fi
EOF

# 2. 暂停录音脚本
cat > "$SCRIPTS_DIR/pause_recording.sh" << 'EOF'
#!/bin/bash
source "$HOME/bin/voice-input/common_functions.sh"

current_state=$(get_recording_state)

if [ "$current_state" != "recording" ]; then
    notify-send "🎤 语音输入" "当前未在录音状态" -i dialog-warning -t 2000
    exit 1
fi

cd "$NERD_DIR"

# 暂停录音(发送暂停信号给进程)
if is_nerd_running; then
    # 发送 SIGTSTP 信号暂停进程
    pkill -TSTP -f "nerd-dictation begin"
    
    set_recording_state "paused"
    notify-send "⏸️ 语音输入" "录音已暂停 - 按 Ctrl+Alt+Shift+U 恢复" -i media-playback-pause -t 2000
    log_message "录音已暂停"
else
    set_recording_state "idle"
    notify-send "🎤 语音输入" "未找到录音进程" -i dialog-warning -t 2000
fi
EOF

# 3. 恢复录音脚本
cat > "$SCRIPTS_DIR/resume_recording.sh" << 'EOF'
#!/bin/bash
source "$HOME/bin/voice-input/common_functions.sh"

current_state=$(get_recording_state)

if [ "$current_state" != "paused" ]; then
    notify-send "🎤 语音输入" "当前未处于暂停状态" -i dialog-warning -t 2000
    exit 1
fi

# 恢复录音进程
if pgrep -f "nerd-dictation begin" > /dev/null; then
    # 发送 SIGCONT 信号恢复进程
    pkill -CONT -f "nerd-dictation begin"
    
    set_recording_state "recording"
    notify-send "▶️ 语音输入" "录音已恢复 - 继续说话" -i media-playback-start -t 2000
    log_message "录音已恢复"
else
    set_recording_state "idle"
    notify-send "🎤 语音输入" "未找到暂停的录音进程" -i dialog-error -t 2000
fi
EOF

# 4. 结束录音脚本
cat > "$SCRIPTS_DIR/end_recording.sh" << 'EOF'
#!/bin/bash
source "$HOME/bin/voice-input/common_functions.sh"

current_state=$(get_recording_state)

if [ "$current_state" = "idle" ]; then
    notify-send "🎤 语音输入" "当前未在录音状态" -i dialog-warning -t 2000
    exit 1
fi

cd "$NERD_DIR"

# 如果是暂停状态,先恢复再结束
if [ "$current_state" = "paused" ]; then
    pkill -CONT -f "nerd-dictation begin" 2>/dev/null || true
    sleep 0.2
fi

# 结束录音并获取结果
RESULT=$(./nerd-dictation end 2>/dev/null)

# 恢复活动窗口焦点
restore_active_window
sleep 0.1

# 处理识别结果
if [ -n "$RESULT" ] && [ "$RESULT" != "" ]; then
    CLEAN_RESULT=$(echo "$RESULT" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
    
    if [ -n "$CLEAN_RESULT" ]; then
        # 输出文字到当前位置
        echo -n "$CLEAN_RESULT" | xdotool type --clearmodifiers --file -
        
        notify-send "✅ 语音输入" "识别成功: $CLEAN_RESULT" -i dialog-information -t 3000
        log_message "识别成功: '$CLEAN_RESULT'"
    else
        notify-send "🎤 语音输入" "识别结果为空" -i dialog-warning -t 2000
        log_message "识别结果为空"
    fi
else
    notify-send "🎤 语音输入" "未识别到语音内容" -i dialog-warning -t 2000
    log_message "未识别到语音"
fi

set_recording_state "idle"
EOF

# 5. 取消录音脚本
cat > "$SCRIPTS_DIR/cancel_recording.sh" << 'EOF'
#!/bin/bash
source "$HOME/bin/voice-input/common_functions.sh"

current_state=$(get_recording_state)

if [ "$current_state" = "idle" ]; then
    notify-send "🎤 语音输入" "当前未在录音状态" -i dialog-warning -t 2000
    exit 1
fi

cd "$NERD_DIR"

# 如果是暂停状态,先恢复再取消
if [ "$current_state" = "paused" ]; then
    pkill -CONT -f "nerd-dictation begin" 2>/dev/null || true
    sleep 0.2
fi

# 取消录音
./nerd-dictation cancel > /dev/null 2>&1

set_recording_state "idle"
notify-send "❌ 语音输入" "录音已取消" -i dialog-information -t 2000
log_message "录音已取消"
EOF

# 设置脚本执行权限
chmod +x "$SCRIPTS_DIR"/*.sh

# =================== 第7步:配置全局快捷键 ===================
echo "⌨️ 第7步:配置全局快捷键..."

# 停止现有的 xbindkeys
pkill xbindkeys 2>/dev/null || true

cat > "$USER_HOME/.xbindkeysrc" << EOF
# 完整中文语音输入快捷键配置
# 五大功能:开始/结束/取消/暂停/恢复
# 设计理念:基础功能用双键,高级功能用三键,避免冲突

# 🟢 开始录音 - Ctrl+Alt+H (Hello)
"$SCRIPTS_DIR/start_recording.sh"
    Control+Alt + h

# 🔴 结束录音 - Ctrl+Alt+U (Unit)
"$SCRIPTS_DIR/end_recording.sh"
    Control+Alt + u

# ❌ 取消录音 - Ctrl+Alt+Shift+C (Cancel)
"$SCRIPTS_DIR/cancel_recording.sh"
    Control+Alt+Shift + c

# ⏸️ 暂停录音 - Ctrl+Alt+Shift+H (Halt)
"$SCRIPTS_DIR/pause_recording.sh"
    Control+Alt+Shift + h

# ▶️ 恢复录音 - Ctrl+Alt+Shift+U (Un-pause)
"$SCRIPTS_DIR/resume_recording.sh"
    Control+Alt+Shift + u
EOF

# 启动快捷键服务
xbindkeys > /dev/null 2>&1 &

# =================== 第8步:配置开机自启动 ===================
echo "🚀 第8步:配置开机自启动..."
mkdir -p "$USER_HOME/.config/autostart"

cat > "$USER_HOME/.config/autostart/voice-input-shortcuts.desktop" << EOF
[Desktop Entry]
Type=Application
Exec=xbindkeys
Hidden=false
NoDisplay=false
X-GNOME-Autostart-enabled=true
Name=Voice Input Shortcuts
Comment=Global shortcuts for Chinese voice input
Icon=audio-input-microphone
Categories=Utility;
EOF

# =================== 第9步:创建状态查看工具 ===================
echo "🔍 第9步:创建管理工具..."

cat > "$USER_HOME/voice_input_manager.sh" << 'EOF'
#!/bin/bash
# 语音输入状态管理工具

STATE_FILE="$HOME/.config/nerd-dictation/recording_state"
LOG_FILE="$HOME/.config/nerd-dictation/voice_input.log"

show_status() {
    echo "=========================================="
    echo "        🎤 语音输入系统状态"
    echo "=========================================="
    
    # 显示当前状态
    if [ -f "$STATE_FILE" ]; then
        current_state=$(cat "$STATE_FILE")
        case $current_state in
            "recording") echo "📍 当前状态: 🔴 正在录音" ;;
            "paused") echo "📍 当前状态: ⏸️ 已暂停" ;;
            "idle") echo "📍 当前状态: ⚪ 空闲" ;;
            *) echo "📍 当前状态: ❓ 未知 ($current_state)" ;;
        esac
    else
        echo "📍 当前状态: ⚪ 空闲"
    fi
    
    # 检查进程状态
    if pgrep -f "nerd-dictation begin" > /dev/null; then
        echo "🔧 录音进程: ✅ 运行中"
    else
        echo "🔧 录音进程: ❌ 未运行"
    fi
    
    if pgrep -x "xbindkeys" > /dev/null; then
        echo "⌨️ 快捷键服务: ✅ 运行中"
    else
        echo "⌨️ 快捷键服务: ❌ 未运行"
    fi
    
    # 检查模型
    if [ -d "$HOME/.config/nerd-dictation/model" ]; then
        echo "🧠 中文模型: ✅ 已安装"
    else
        echo "🧠 中文模型: ❌ 未找到"
    fi
    
    echo ""
    echo "🎯 快捷键说明:"
    echo "   Ctrl+Alt+H           - 🟢 开始录音"
    echo "   Ctrl+Alt+U           - 🔴 结束录音"
    echo "   Ctrl+Alt+Shift+C     - ❌ 取消录音"
    echo "   Ctrl+Alt+Shift+H     - ⏸️ 暂停录音"
    echo "   Ctrl+Alt+Shift+U     - ▶️ 恢复录音"
    echo ""
}

show_logs() {
    echo "📋 最近的操作日志:"
    if [ -f "$LOG_FILE" ]; then
        tail -10 "$LOG_FILE"
    else
        echo "暂无日志记录"
    fi
}

reset_state() {
    echo "idle" > "$STATE_FILE"
    pkill -f "nerd-dictation" 2>/dev/null || true
    echo "✅ 状态已重置为空闲"
}

case "$1" in
    "status"|"")
        show_status
        ;;
    "logs")
        show_logs
        ;;
    "reset")
        reset_state
        ;;
    "test")
        echo "🧪 打开测试编辑器..."
        gedit "/tmp/语音输入测试.txt" &
        echo "现在可以在编辑器中测试语音输入功能了!"
        ;;
    *)
        echo "用法: $0 [status|logs|reset|test]"
        echo "  status - 显示系统状态(默认)"
        echo "  logs   - 显示操作日志"
        echo "  reset  - 重置状态"
        echo "  test   - 打开测试编辑器"
        ;;
esac
EOF

chmod +x "$USER_HOME/voice_input_manager.sh"

# =================== 第10步:最终检查和测试 ===================
echo "✅ 第10步:最终检查..."

# 创建初始状态文件
echo "idle" > "$STATE_FILE"

# 测试脚本权限
for script in start_recording.sh pause_recording.sh resume_recording.sh end_recording.sh cancel_recording.sh; do
    if [ -x "$SCRIPTS_DIR/$script" ]; then
        echo "✅ $script 权限正确"
    else
        echo "❌ $script 权限错误"
        chmod +x "$SCRIPTS_DIR/$script"
    fi
done

echo ""
echo "🎉 ======================================"
echo "     安装完成!中文语音输入系统就绪"
echo "========================================"
echo ""
echo "📚 使用说明:"
echo "   Ctrl+Alt+H           - 🟢 开始录音"
echo "   Ctrl+Alt+U           - 🔴 结束录音并输出文字"  
echo "   Ctrl+Alt+Shift+C     - ❌ 取消录音"
echo "   Ctrl+Alt+Shift+H     - ⏸️ 暂停录音"
echo "   Ctrl+Alt+Shift+U     - ▶️ 恢复录音"
echo ""
echo "🔧 管理命令:"
echo "   bash ~/voice_input_manager.sh        - 查看状态"
echo "   bash ~/voice_input_manager.sh test   - 打开测试编辑器"
echo "   bash ~/voice_input_manager.sh logs   - 查看操作日志"
echo "   bash ~/voice_input_manager.sh reset  - 重置状态"
echo ""
echo "✨ 特色功能:"
echo "   • 使用最强大的中文识别模型 (vosk-model-cn-0.22)"
echo "   • 支持暂停/恢复功能,长录音更方便"
echo "   • 完全离线工作,保护隐私"
echo "   • 智能窗口焦点恢复"
echo "   • 详细的状态管理和日志记录"
echo ""
echo "🚀 现在就可以开始使用了!"
echo "   在任何文本编辑器中按 Ctrl+Alt+H 开始录音"

执行保存后的文件install_voice_input.sh

bash install_voice_input.sh

🎯 快速使用指南

基本操作流程

  1. 开始录音: Ctrl+Alt+H → 看到通知"开始录音"
  2. 说中文: 清晰地说出要输入的中文内容
  3. 暂停录音: Ctrl+Alt+Shift+H → 暂时停止录制(可恢复)
  4. 恢复录音: Ctrl+Alt+Shift+U → 继续录制
  5. 结束录音: Ctrl+Alt+U → 文字自动输入到光标位置 Ctrl+Alt+H image.png Ctrl+Alt+Shift+H image.png Ctrl+Alt+U image.png

状态管理

# 查看系统状态
bash ~/voice_input_manager.sh

# 查看操作日志  
bash ~/voice_input_manager.sh logs

# 重置系统状态
bash ~/voice_input_manager.sh reset

# 打开测试编辑器
bash ~/voice_input_manager.sh test

重启电脑后如果语音输入不转文字,在终端执行以下代码即可

# 清理所有相关进程
pkill -f "nerd-dictation"

# 重启快捷键服务  
pkill xbindkeys
xbindkeys &

# 重置状态文件
echo "idle" > ~/.config/nerd-dictation/recording_state

🧠 模型说明

使用的中文模型

  • 模型名称: vosk-model-cn-0.22
  • 模型大小: ~1.5GB
  • 识别精度: 最高级别
  • 内存需求: 2-4GB
  • 特点: 离线高精度中文语音识别

模型优势

  • ✅ 完全离线工作,保护隐私
  • ✅ 支持标准普通话
  • ✅ 识别准确率高
  • ✅ 支持连续语音识别
  • ✅ 低延迟响应

🔧 高级配置

自定义快捷键

编辑 ~/.xbindkeysrc 文件可自定义快捷键:

# 例如:修改开始录音为 F9
"$HOME/bin/voice-input/start_recording.sh"
    F9

日志配置

日志文件位置:~/.config/nerd-dictation/voice_input.log

故障排除

问题解决方案
快捷键不响应pkill xbindkeys && xbindkeys
录音无响应bash ~/voice_input_manager.sh reset
模型加载失败检查 ~/.config/nerd-dictation/model
权限错误chmod +x ~/bin/voice-input/*.sh

📈 系统要求

  • 操作系统: Ubuntu 18.04+ / Debian 10+
  • 内存: 建议 4GB+ (模型需要 2-4GB)
  • 存储: 3GB 可用空间
  • 音频: 支持的麦克风设备
  • 网络: 仅安装时需要(运行时完全离线)

🎉 完成

现在你拥有了功能最完整的中文语音输入系统!支持开始、暂停、恢复、结束、取消五大功能,使用最强大的中文识别模型,完全离线工作。