本地视频转字幕方案
安装Whisper
pip install openai-whisper
安装ffmpeg
winget install "FFmpeg (Essentials Build)"
提取音频
ffmpeg -i input.mp4 -vn -ar 16000 -ac 1 output.wav
生成字幕
whisper output.wav --language zh --model medium --output_format srt
指定位置后接--output_dir "D:\字幕文件" 或 --output "D:\字幕文件\自定义文件名"
常用语言代码:
中文:zh 或 chinese
英语:en 或 english
日语:ja 或 japanese
韩语:ko 或 korean
https://github.com/openai/whisper/blob/main/whisper/tokenizer.py
使用GPU
Whisper 在 NVIDIA GPU(CUDA) 上运行速度显著更快。确保已安装 GPU 版本的 PyTorch 和 CUDA 驱动:
pip install torch torchaudio --index-url https://download.pytorch.org/whl/cu118
如果安装太慢,手动下载https://download.pytorch.org/whl/cu118/torch-2.6.0%2Bcu118-cp311-cp311-win_amd64.whl
手动安装pip install torch-2.6.0+cu118-cp311-cp311-win_amd64.whl
验证是否可用python -c "import torch; print(f'CUDA 可用: {torch.cuda.is_available()}')"
批处理
以上操作测试通过后,就可以用代码批量处理了
static async Task Main(string[] args)
{
var dir = @"C:\temp";
var files = Directory.GetFiles(dir, "*.mp4");
foreach (var file in files)
{
var name = Path.GetFileNameWithoutExtension(file);
var srtFile = dir + "\\" + name + ".srt";
//var wavFile = Path.GetTempPath() + name + ".wav";
var wavDir = dir + "\\wav\\";
Directory.CreateDirectory(wavDir);
var wavFile = wavDir + name + ".wav";
if (File.Exists(srtFile))
{
Console.WriteLine($"存在字幕文件,跳过:{srtFile}");
}
else
{
if (File.Exists(wavFile))
{
Console.WriteLine($"存在wav文件,不转换:{wavFile}");
}
else
{
//转换wav
var cmd = $"ffmpeg -i \"{file}\" -vn -ar 16000 -ac 1 \"{wavFile}\"";
Console.WriteLine(cmd);
await RunCmd(cmd);
}
}
if (File.Exists(wavFile) && !File.Exists(srtFile))
{
var cmd = $"whisper \"{wavFile}\" --language zh --model medium --output_format srt --output_dir \"{dir}\"";
Console.WriteLine(cmd);
await RunCmd(cmd);
}
}
Console.WriteLine("---END---");
Console.Read();
}
public static async Task RunCmd(string cmd, int waitExitMs = 0)
{
var processStartInfo = new ProcessStartInfo
{
FileName = "cmd.exe",
Arguments = $"/C {cmd}",
RedirectStandardOutput = true,
RedirectStandardError = true,
UseShellExecute = false,
CreateNoWindow = true
};
using var process = new Process { StartInfo = processStartInfo };
var outputBuilder = new StringBuilder();
var errorBuilder = new StringBuilder();
process.OutputDataReceived += (sender, e) =>
{
if (e.Data != null)
{
outputBuilder.AppendLine(e.Data);
Console.WriteLine(e.Data);
}
};
process.ErrorDataReceived += (sender, e) =>
{
if (e.Data != null)
{
errorBuilder.AppendLine(e.Data);
Console.WriteLine(e.Data);
}
};
process.Start();
// 开始异步读取输出
process.BeginOutputReadLine();
process.BeginErrorReadLine();
// 异步等待进程退出
await process.WaitForExitAsync();
// 获取完整输出
string output = outputBuilder.ToString();
string error = errorBuilder.ToString();
Console.WriteLine("Output:\n" + output);
if (!string.IsNullOrEmpty(error))
{
Console.WriteLine("Error:\n" + error);
}
}
字幕超长
使用 https://github.com/SubtitleEdit/subtitleedit 分割一下

更优的方案
使用 faster-whisper
https://github.com/CheshireCC/faster-whisper-GUI
手动下载模型
https://huggingface.co/models?sort=trending&search=faster-whisper
浙公网安备 33010602011771号