本地视频转字幕方案

安装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

posted @ 2025-03-13 10:48  trykle  阅读(87)  评论(0)    收藏  举报