()
| 218 | |
| 219 | |
| 220 | def main() -> None: |
| 221 | args = parse_args() |
| 222 | extensions = normalize_extensions(args.extensions) |
| 223 | files = iter_audio_files(args.input, extensions, args.recursive) |
| 224 | if not files: |
| 225 | print(f"No audio files found under {args.input} for extensions {extensions}", file=sys.stderr) |
| 226 | sys.exit(2) |
| 227 | |
| 228 | vad_model = None if args.vad_model.lower() == "none" else args.vad_model |
| 229 | model_kwargs: Dict[str, Any] = {"model": args.model, "vad_model": vad_model, "device": args.device} |
| 230 | if args.spk_model: |
| 231 | model_kwargs["spk_model"] = args.spk_model |
| 232 | |
| 233 | print(f"Loading FunASR model: {args.model} on {args.device}") |
| 234 | load_start = time.perf_counter() |
| 235 | model = AutoModel(**model_kwargs) |
| 236 | model_load_seconds = time.perf_counter() - load_start |
| 237 | print(f"Model loaded in {model_load_seconds:.3f}s") |
| 238 | |
| 239 | rows: List[Dict[str, Any]] = [] |
| 240 | for index, audio_path in enumerate(files, start=1): |
| 241 | display = str(audio_path if args.input.is_file() else audio_path.relative_to(args.input)) |
| 242 | print(f"[{index}/{len(files)}] {display}") |
| 243 | duration = audio_duration_seconds(audio_path) |
| 244 | start = time.perf_counter() |
| 245 | row: Dict[str, Any] = { |
| 246 | "input": display, |
| 247 | "path": str(audio_path), |
| 248 | "duration_seconds": duration, |
| 249 | "model": args.model, |
| 250 | "device": args.device, |
| 251 | "language": args.language, |
| 252 | } |
| 253 | try: |
| 254 | result = model.generate(input=str(audio_path), language=args.language, batch_size=args.batch_size) |
| 255 | elapsed = time.perf_counter() - start |
| 256 | row["elapsed_seconds"] = elapsed |
| 257 | row["realtime_factor"] = (duration / elapsed) if duration and elapsed else None |
| 258 | row["text"] = extract_text(result) |
| 259 | print(f" ok: {elapsed:.3f}s" + (f", {row['realtime_factor']:.3f}x" if row["realtime_factor"] else "")) |
| 260 | except Exception as exc: # keep benchmarking other files |
| 261 | elapsed = time.perf_counter() - start |
| 262 | row["elapsed_seconds"] = elapsed |
| 263 | row["realtime_factor"] = None |
| 264 | row["error"] = repr(exc) |
| 265 | print(f" error: {exc}", file=sys.stderr) |
| 266 | rows.append(row) |
| 267 | |
| 268 | args.output_dir.mkdir(parents=True, exist_ok=True) |
| 269 | results_path = args.output_dir / "results.jsonl" |
| 270 | summary_path = args.output_dir / "summary.md" |
| 271 | write_jsonl(results_path, rows) |
| 272 | summary_path.write_text(markdown_summary(rows, args, model_load_seconds), encoding="utf-8") |
| 273 | print(f"\nWrote {results_path}") |
| 274 | print(f"Wrote {summary_path}") |
| 275 | |
| 276 | |
| 277 | if __name__ == "__main__": |
no test coverage detected
searching dependent graphs…