mirror of
https://github.com/ThePlasmak/faster-whisper.git
synced 2026-09-19 07:38:23 +08:00
fix: suppress onnxruntime WSL2 device-discovery warning on every run
Pre-import onnxruntime at startup with stderr redirected to /dev/null, so the harmless [W:onnxruntime:Default, device_discovery.cc:211] warning about missing /sys/class/drm/card0/device/vendor is silenced before any real output begins. Subsequent lazy imports (Silero VAD) hit the cache. docs(skill): add missing ASS/LRC/HTML trigger phrases and batch chapters caveat - Add 'ASS subtitles', 'aegisub format', 'LRC subtitles', 'timed lyrics', 'HTML transcript', 'confidence-colored transcript' to trigger phrases - Note that --chapters-file takes a single path and overwrites in batch mode
This commit is contained in:
@@ -42,6 +42,9 @@ Use this skill when you need to:
|
||||
"find where X is mentioned", "search transcript for", "when did they say", "at what timestamp",
|
||||
"add chapters", "detect chapters", "find breaks in the audio", "table of contents for this recording",
|
||||
"TTML subtitles", "DFXP subtitles", "broadcast format subtitles", "Netflix format",
|
||||
"ASS subtitles", "aegisub format", "advanced substation alpha", "mpv subtitles",
|
||||
"LRC subtitles", "timed lyrics", "karaoke subtitles", "music player lyrics",
|
||||
"HTML transcript", "confidence-colored transcript", "color-coded transcript",
|
||||
"separate audio per speaker", "export speaker audio", "split by speaker",
|
||||
"transcript as CSV", "spreadsheet output", "transcribe podcast", "podcast RSS feed",
|
||||
"different languages in batch", "per-file language",
|
||||
@@ -102,6 +105,7 @@ Use this skill when you need to:
|
||||
- `--chapter-format youtube` (default) outputs YouTube-ready timestamps; use `json` for programmatic use
|
||||
- **Always use `--chapters-file PATH`** when combining chapters with a transcript output — avoids mixing chapter markers into the transcript text
|
||||
- If the user only wants chapters (not the transcript), pipe stdout to a file with `-o /dev/null` and use `--chapters-file`
|
||||
- **Batch mode limitation:** `--chapters-file` takes a single path — in batch mode, each file's chapters overwrite the previous. For batch chapter detection, omit `--chapters-file` (chapters print to stdout under `=== CHAPTERS (N) ===`) or use a separate run per file
|
||||
|
||||
**Speaker audio export:**
|
||||
- Only add `--export-speakers DIR` when the user explicitly asks to save each speaker's audio separately
|
||||
@@ -116,10 +120,11 @@ Use this skill when you need to:
|
||||
**RSS / Podcast:**
|
||||
- Only add `--rss URL` when the user provides a podcast RSS feed URL
|
||||
- Default fetches 5 newest episodes; `--rss-latest 0` for all; `--skip-existing` to resume safely
|
||||
- **Always use `-o <dir>`** with `--rss` — without it, all episode transcripts print to stdout concatenated, which is hard to use; each episode gets its own file when `-o <dir>` is set
|
||||
|
||||
**Output format for agent relay:**
|
||||
- **Search results** (`--search`) → print directly to user; output is human-readable
|
||||
- **Chapter output** → if no `--chapters-file`, chapters appear in stdout under `=== CHAPTERS (N) ===` header after the transcript
|
||||
- **Chapter output** → if no `--chapters-file`, chapters appear in stdout under `=== CHAPTERS (N) ===` header after the transcript; with `--format json`, chapters are also embedded in the JSON under `"chapters"` key
|
||||
- **Subtitle formats** (SRT, VTT, ASS, LRC, TTML) → always write to `-o` file; tell the user the output path, never paste raw subtitle content
|
||||
- **Data formats** (CSV, HTML, TTML, JSON) → always write to `-o` file; tell the user the output path, don't paste raw XML/CSV/HTML
|
||||
- **ASS format** → for Aegisub, VLC, mpv; write to file and tell user they can open it in Aegisub or play it in VLC/mpv
|
||||
|
||||
+29
-8
@@ -1827,6 +1827,22 @@ def format_result(result, fmt, max_words_per_line=None, max_chars_per_line=None)
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
def main():
|
||||
# Pre-import onnxruntime silently to suppress the harmless WSL2 device-discovery warning.
|
||||
# onnxruntime writes directly to stderr fd when first imported (device_discovery.cc:211).
|
||||
# By importing it here with fd 2 redirected, we populate sys.modules so that later
|
||||
# lazy imports (faster_whisper's SileroVADModel) hit the cache instead of re-triggering.
|
||||
try:
|
||||
_old_stderr_fd = os.dup(2)
|
||||
try:
|
||||
with open(os.devnull, "wb") as _devnull:
|
||||
os.dup2(_devnull.fileno(), 2)
|
||||
import onnxruntime as _ort # noqa: F401
|
||||
finally:
|
||||
os.dup2(_old_stderr_fd, 2)
|
||||
os.close(_old_stderr_fd)
|
||||
except Exception:
|
||||
pass # If anything goes wrong, just continue — stderr stays intact
|
||||
|
||||
# Early exit handlers — must run BEFORE argparse so they work without AUDIO positional arg
|
||||
_SCRIPT_DIR = Path(__file__).parent
|
||||
|
||||
@@ -2451,7 +2467,7 @@ def main():
|
||||
if compute_type == "auto":
|
||||
compute_type = "float16" if device == "cuda" else "int8"
|
||||
|
||||
if cuda_ok and compute_type == "float16" and args.compute_type == "auto":
|
||||
if cuda_ok and compute_type == "float16" and args.compute_type == "auto" and not args.quiet:
|
||||
import re as _re
|
||||
gpu_name = gpu_name or ""
|
||||
if _re.search(r"RTX 30[0-9]{2}", gpu_name, _re.IGNORECASE):
|
||||
@@ -2703,6 +2719,15 @@ def main():
|
||||
lang = r.get("language", "xx")
|
||||
model_name = args.model
|
||||
|
||||
# ---- Pre-compute chapters (must happen before output formatting for JSON embedding) ----
|
||||
# Stored in _computed_chapters so the display block below can reuse it without a second call.
|
||||
_computed_chapters = None
|
||||
if getattr(args, "detect_chapters", False) and r.get("segments"):
|
||||
_computed_chapters = detect_chapters(r["segments"], min_gap=args.chapter_gap)
|
||||
_formats_list = getattr(args, "_formats", [args.format])
|
||||
if "json" in _formats_list:
|
||||
r["chapters"] = _computed_chapters # embed in JSON output
|
||||
|
||||
# ---- Transcript search mode ----
|
||||
if getattr(args, "search", None):
|
||||
matches = search_transcript(
|
||||
@@ -2769,9 +2794,9 @@ def main():
|
||||
print(f"\n=== {r['file']} ===")
|
||||
print(output)
|
||||
|
||||
# ---- Chapter detection ----
|
||||
if getattr(args, "detect_chapters", False) and r.get("segments"):
|
||||
chapters = detect_chapters(r["segments"], min_gap=args.chapter_gap)
|
||||
# ---- Chapter detection output ----
|
||||
if _computed_chapters is not None:
|
||||
chapters = _computed_chapters # reuse pre-computed result
|
||||
chapters_output = format_chapters_output(chapters, fmt=args.chapter_format)
|
||||
if not args.quiet:
|
||||
if not chapters or len(chapters) == 1:
|
||||
@@ -2797,10 +2822,6 @@ def main():
|
||||
# Print to stdout after transcript — clear header so agents can parse it separately
|
||||
print(f"\n=== CHAPTERS ({len(chapters)}) ===\n{chapters_output}")
|
||||
|
||||
# For JSON output, embed chapters in the result too
|
||||
if args.format == "json":
|
||||
r["chapters"] = chapters
|
||||
|
||||
# Write stats sidecar
|
||||
_write_stats(r, args)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user