ggerganov commited on
Commit
4860566
·
1 Parent(s): 11f86cb

ref #17 : add options to output result to file

Browse files

Support for:

- plain text
- VTT
- SRT

Files changed (2) hide show
  1. main.cpp +91 -7
  2. whisper.cpp +1 -1
main.cpp CHANGED
@@ -5,6 +5,7 @@
5
  #define DR_WAV_IMPLEMENTATION
6
  #include "dr_wav.h"
7
 
 
8
  #include <cstdio>
9
  #include <string>
10
  #include <thread>
@@ -32,6 +33,9 @@ struct whisper_params {
32
 
33
  bool verbose = false;
34
  bool translate = false;
 
 
 
35
  bool print_special_tokens = false;
36
  bool no_timestamps = false;
37
 
@@ -69,6 +73,12 @@ bool whisper_params_parse(int argc, char ** argv, whisper_params & params) {
69
  whisper_print_usage(argc, argv, params);
70
  exit(0);
71
  }
 
 
 
 
 
 
72
  } else if (arg == "-ps" || arg == "--print_special") {
73
  params.print_special_tokens = true;
74
  } else if (arg == "-nt" || arg == "--no_timestamps") {
@@ -101,6 +111,8 @@ void whisper_print_usage(int argc, char ** argv, const whisper_params & params)
101
  fprintf(stderr, " -o N, --offset N offset in milliseconds (default: %d)\n", params.offset_ms);
102
  fprintf(stderr, " -v, --verbose verbose output\n");
103
  fprintf(stderr, " --translate translate from source language to english\n");
 
 
104
  fprintf(stderr, " -ps, --print_special print special tokens\n");
105
  fprintf(stderr, " -nt, --no_timestamps do not print timestamps\n");
106
  fprintf(stderr, " -l LANG, --language LANG spoken language (default: %s)\n", params.language.c_str());
@@ -123,7 +135,7 @@ int main(int argc, char ** argv) {
123
  if (params.fname_inp.empty()) {
124
  fprintf(stderr, "error: no input files specified\n");
125
  whisper_print_usage(argc, argv, params);
126
- return 1;
127
  }
128
 
129
  // whisper init
@@ -140,22 +152,22 @@ int main(int argc, char ** argv) {
140
  if (!drwav_init_file(&wav, fname_inp.c_str(), NULL)) {
141
  fprintf(stderr, "%s: failed to open WAV file '%s' - check your input\n", argv[0], fname_inp.c_str());
142
  whisper_print_usage(argc, argv, {});
143
- return 2;
144
  }
145
 
146
  if (wav.channels != 1 && wav.channels != 2) {
147
  fprintf(stderr, "%s: WAV file '%s' must be mono or stereo\n", argv[0], fname_inp.c_str());
148
- return 3;
149
  }
150
 
151
  if (wav.sampleRate != WHISPER_SAMPLE_RATE) {
152
  fprintf(stderr, "%s: WAV file '%s' must be 16 kHz\n", argv[0], fname_inp.c_str());
153
- return 4;
154
  }
155
 
156
  if (wav.bitsPerSample != 16) {
157
  fprintf(stderr, "%s: WAV file '%s' must be 16-bit\n", argv[0], fname_inp.c_str());
158
- return 5;
159
  }
160
 
161
  int n = wav.totalPCMFrameCount;
@@ -193,9 +205,11 @@ int main(int argc, char ** argv) {
193
  params.language.c_str(),
194
  params.translate ? "translate" : "transcribe",
195
  params.no_timestamps ? 0 : 1);
 
196
  printf("\n");
197
  }
198
 
 
199
  // run the inference
200
  {
201
  whisper_full_params wparams = whisper_full_default_params(WHISPER_DECODE_GREEDY);
@@ -211,10 +225,10 @@ int main(int argc, char ** argv) {
211
 
212
  if (whisper_full(ctx, wparams, pcmf32.data(), pcmf32.size()) != 0) {
213
  fprintf(stderr, "%s: failed to process audio\n", argv[0]);
214
- return 6;
215
  }
216
 
217
- // print result;
218
  if (!wparams.print_realtime) {
219
  printf("\n");
220
 
@@ -233,6 +247,76 @@ int main(int argc, char ** argv) {
233
  }
234
  }
235
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
236
  }
237
  }
238
 
 
5
  #define DR_WAV_IMPLEMENTATION
6
  #include "dr_wav.h"
7
 
8
+ #include <fstream>
9
  #include <cstdio>
10
  #include <string>
11
  #include <thread>
 
33
 
34
  bool verbose = false;
35
  bool translate = false;
36
+ bool output_txt = false;
37
+ bool output_vtt = false;
38
+ bool output_srt = false;
39
  bool print_special_tokens = false;
40
  bool no_timestamps = false;
41
 
 
73
  whisper_print_usage(argc, argv, params);
74
  exit(0);
75
  }
76
+ } else if (arg == "-otxt" || arg == "--output-txt") {
77
+ params.output_txt = true;
78
+ } else if (arg == "-ovtt" || arg == "--output-vtt") {
79
+ params.output_vtt = true;
80
+ } else if (arg == "-osrt" || arg == "--output-srt") {
81
+ params.output_srt = true;
82
  } else if (arg == "-ps" || arg == "--print_special") {
83
  params.print_special_tokens = true;
84
  } else if (arg == "-nt" || arg == "--no_timestamps") {
 
111
  fprintf(stderr, " -o N, --offset N offset in milliseconds (default: %d)\n", params.offset_ms);
112
  fprintf(stderr, " -v, --verbose verbose output\n");
113
  fprintf(stderr, " --translate translate from source language to english\n");
114
+ fprintf(stderr, " -otxt, --output-txt output result in a text file\n");
115
+ fprintf(stderr, " -ovtt, --output-vtt output result in a vtt file\n");
116
  fprintf(stderr, " -ps, --print_special print special tokens\n");
117
  fprintf(stderr, " -nt, --no_timestamps do not print timestamps\n");
118
  fprintf(stderr, " -l LANG, --language LANG spoken language (default: %s)\n", params.language.c_str());
 
135
  if (params.fname_inp.empty()) {
136
  fprintf(stderr, "error: no input files specified\n");
137
  whisper_print_usage(argc, argv, params);
138
+ return 2;
139
  }
140
 
141
  // whisper init
 
152
  if (!drwav_init_file(&wav, fname_inp.c_str(), NULL)) {
153
  fprintf(stderr, "%s: failed to open WAV file '%s' - check your input\n", argv[0], fname_inp.c_str());
154
  whisper_print_usage(argc, argv, {});
155
+ return 3;
156
  }
157
 
158
  if (wav.channels != 1 && wav.channels != 2) {
159
  fprintf(stderr, "%s: WAV file '%s' must be mono or stereo\n", argv[0], fname_inp.c_str());
160
+ return 4;
161
  }
162
 
163
  if (wav.sampleRate != WHISPER_SAMPLE_RATE) {
164
  fprintf(stderr, "%s: WAV file '%s' must be 16 kHz\n", argv[0], fname_inp.c_str());
165
+ return 5;
166
  }
167
 
168
  if (wav.bitsPerSample != 16) {
169
  fprintf(stderr, "%s: WAV file '%s' must be 16-bit\n", argv[0], fname_inp.c_str());
170
+ return 6;
171
  }
172
 
173
  int n = wav.totalPCMFrameCount;
 
205
  params.language.c_str(),
206
  params.translate ? "translate" : "transcribe",
207
  params.no_timestamps ? 0 : 1);
208
+
209
  printf("\n");
210
  }
211
 
212
+
213
  // run the inference
214
  {
215
  whisper_full_params wparams = whisper_full_default_params(WHISPER_DECODE_GREEDY);
 
225
 
226
  if (whisper_full(ctx, wparams, pcmf32.data(), pcmf32.size()) != 0) {
227
  fprintf(stderr, "%s: failed to process audio\n", argv[0]);
228
+ return 7;
229
  }
230
 
231
+ // print result
232
  if (!wparams.print_realtime) {
233
  printf("\n");
234
 
 
247
  }
248
  }
249
  }
250
+
251
+ printf("\n");
252
+
253
+ // output to text file
254
+ if (params.output_txt) {
255
+
256
+ const auto fname_txt = fname_inp + ".txt";
257
+ std::ofstream fout_txt(fname_txt);
258
+ if (!fout_txt.is_open()) {
259
+ fprintf(stderr, "%s: failed to open '%s' for writing\n", __func__, fname_txt.c_str());
260
+ return 8;
261
+ }
262
+
263
+ printf("%s: saving output to '%s.txt'\n", __func__, fname_inp.c_str());
264
+
265
+ const int n_segments = whisper_full_n_segments(ctx);
266
+ for (int i = 0; i < n_segments; ++i) {
267
+ const char * text = whisper_full_get_segment_text(ctx, i);
268
+ fout_txt << text;
269
+ }
270
+ }
271
+
272
+ // output to VTT file
273
+ if (params.output_vtt) {
274
+
275
+ const auto fname_vtt = fname_inp + ".vtt";
276
+ std::ofstream fout_vtt(fname_vtt);
277
+ if (!fout_vtt.is_open()) {
278
+ fprintf(stderr, "%s: failed to open '%s' for writing\n", __func__, fname_vtt.c_str());
279
+ return 9;
280
+ }
281
+
282
+ printf("%s: saving output to '%s.vtt'\n", __func__, fname_inp.c_str());
283
+
284
+ fout_vtt << "WEBVTT\n\n";
285
+
286
+ const int n_segments = whisper_full_n_segments(ctx);
287
+ for (int i = 0; i < n_segments; ++i) {
288
+ const char * text = whisper_full_get_segment_text(ctx, i);
289
+ const int64_t t0 = whisper_full_get_segment_t0(ctx, i);
290
+ const int64_t t1 = whisper_full_get_segment_t1(ctx, i);
291
+
292
+ fout_vtt << to_timestamp(t0) << " --> " << to_timestamp(t1) << "\n";
293
+ fout_vtt << text << "\n\n";
294
+ }
295
+ }
296
+
297
+ // output to SRT file
298
+ if (params.output_srt) {
299
+
300
+ const auto fname_srt = fname_inp + ".srt";
301
+ std::ofstream fout_srt(fname_srt);
302
+ if (!fout_srt.is_open()) {
303
+ fprintf(stderr, "%s: failed to open '%s' for writing\n", __func__, fname_srt.c_str());
304
+ return 10;
305
+ }
306
+
307
+ printf("%s: saving output to '%s.srt'\n", __func__, fname_inp.c_str());
308
+
309
+ const int n_segments = whisper_full_n_segments(ctx);
310
+ for (int i = 0; i < n_segments; ++i) {
311
+ const char * text = whisper_full_get_segment_text(ctx, i);
312
+ const int64_t t0 = whisper_full_get_segment_t0(ctx, i);
313
+ const int64_t t1 = whisper_full_get_segment_t1(ctx, i);
314
+
315
+ fout_srt << i + 1 << "\n";
316
+ fout_srt << to_timestamp(t0) << " --> " << to_timestamp(t1) << "\n";
317
+ fout_srt << text << "\n\n";
318
+ }
319
+ }
320
  }
321
  }
322
 
whisper.cpp CHANGED
@@ -2242,7 +2242,7 @@ whisper_token whisper_token_transcribe() {
2242
  void whisper_print_timings(struct whisper_context * ctx) {
2243
  const int64_t t_end_us = ggml_time_us();
2244
 
2245
- printf("\n\n");
2246
  printf("%s: load time = %8.2f ms\n", __func__, ctx->t_load_us/1000.0f);
2247
  printf("%s: mel time = %8.2f ms\n", __func__, ctx->t_mel_us/1000.0f);
2248
  printf("%s: sample time = %8.2f ms\n", __func__, ctx->t_sample_us/1000.0f);
 
2242
  void whisper_print_timings(struct whisper_context * ctx) {
2243
  const int64_t t_end_us = ggml_time_us();
2244
 
2245
+ printf("\n");
2246
  printf("%s: load time = %8.2f ms\n", __func__, ctx->t_load_us/1000.0f);
2247
  printf("%s: mel time = %8.2f ms\n", __func__, ctx->t_mel_us/1000.0f);
2248
  printf("%s: sample time = %8.2f ms\n", __func__, ctx->t_sample_us/1000.0f);