{"id":50566540,"url":"https://github.com/nlink-jp/gem-transcribe","last_synced_at":"2026-06-04T15:02:02.828Z","repository":{"id":358049859,"uuid":"1239712355","full_name":"nlink-jp/gem-transcribe","owner":"nlink-jp","description":"Audio transcription CLI built on Vertex AI Gemini — speaker name inference, multi-language output, structured JSON","archived":false,"fork":false,"pushed_at":"2026-05-15T11:59:18.000Z","size":123,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-15T13:36:57.832Z","etag":null,"topics":["audio-transcription","cli","gemini","multilingual","python","speaker-diarization","srt","subtitles","vertex-ai","webvtt"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nlink-jp.png","metadata":{"files":{"readme":"README.ja.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2026-05-15T11:12:28.000Z","updated_at":"2026-05-15T12:53:33.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/nlink-jp/gem-transcribe","commit_stats":null,"previous_names":["nlink-jp/gem-transcribe"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/nlink-jp/gem-transcribe","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nlink-jp%2Fgem-transcribe","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nlink-jp%2Fgem-transcribe/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nlink-jp%2Fgem-transcribe/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nlink-jp%2Fgem-transcribe/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nlink-jp","download_url":"https://codeload.github.com/nlink-jp/gem-transcribe/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nlink-jp%2Fgem-transcribe/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33910137,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-04T02:00:06.755Z","response_time":64,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["audio-transcription","cli","gemini","multilingual","python","speaker-diarization","srt","subtitles","vertex-ai","webvtt"],"created_at":"2026-06-04T15:02:02.706Z","updated_at":"2026-06-04T15:02:02.812Z","avatar_url":"https://github.com/nlink-jp.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# gem-transcribe\n\nVertex AI Gemini を活用した音声文字起こし CLI。話者推論、マルチランゲージ出力、構造化 JSON に対応します。\n\n`gem-transcribe` は「文字起こし基盤」に特化した単機能ツールです。議事録の構造化、要約、アクションアイテム抽出は下流の\n[meeting-note](https://github.com/nlink-jp/meeting-note) などに任せます。\n\n## 主な機能\n\n- **話者推論** — デフォルトで音声内の自己紹介・呼びかけ・第三者言及から話者の名前を抽出します。名前が特定できない話者は `Speaker A`, `Speaker B`, ... のラベルにフォールバック。`--speaker-hint=\"山田,佐藤\"` を渡すと候補名を限定できます\n- **マルチランゲージ出力** — `--lang=en,ja` のように指定すると、原文と翻訳を 1 回の API 呼び出しで同時生成\n- **長尺音声対応** — ローカルファイルは GCS ステージングバケットに自動アップロードされ、処理後に削除されます。事前アップロード済みの `gs://` URI もそのまま受け付けます\n- **複数の出力フォーマット** — デフォルトは stdout への JSON。`--format text|md|srt|vtt` で他形式に切り替え可能。SRT/VTT を `--output-file=meeting.srt --lang=en,ja` のように多言語指定すると `meeting.en.srt` と `meeting.ja.srt` が自動生成されます。`--output-dir` は `.json` と `.txt` の両方を一括出力\n- **stderr への進捗表示** — アップロード開始・転記開始・所要時間など、節目ごとに1行ずつ stderr に出力。長時間の API 呼び出し中に「フリーズしているのか動いているのか」分からなくなるのを防ぎます。`--quiet` で抑制、`--verbose` で INFO レベルの詳細ログ\n\n## インストール\n\n```bash\nuv tool install git+https://github.com/nlink-jp/gem-transcribe.git\n# または、クローンから\nuv sync --all-extras\n```\n\nPython 3.11+ が必要です。\n\n## セットアップ\n\n1. **GCS バケットの作成**（ステージング用）:\n\n   ```bash\n   gsutil mb -l us-central1 gs://your-bucket\n   ```\n\n2. **ADC（Application Default Credentials）の設定**:\n\n   ```bash\n   gcloud auth application-default login\n   ```\n\n3. **設定ファイルの作成** — `~/.config/gem-transcribe/config.toml`\n   （テンプレートは `config.example.toml` 参照）:\n\n   ```toml\n   [gcp]\n   project = \"your-gcp-project\"\n   location = \"us-central1\"\n\n   [model]\n   name = \"gemini-2.5-flash\"\n\n   [storage]\n   staging_bucket = \"gs://your-bucket/gem-transcribe/\"\n   ```\n\n   IAM プリンシパルには `roles/aiplatform.user` と、ステージングバケットへの `roles/storage.objectAdmin` が必要です。\n\n## 使い方\n\n```bash\n# JSON を stdout に出力（デフォルト）\ngem-transcribe meeting.mp3\n\n# 多言語出力\ngem-transcribe interview.m4a --lang=en,ja\n\n# 話者名の割り当て\ngem-transcribe meeting.mp3 --speaker-hint=\"山田,佐藤,田中\"\n\n# JSON とプレーンテキストの両方をディレクトリに出力\ngem-transcribe meeting.mp3 --output-dir=./transcripts/\n\n# Markdown タイムライン\ngem-transcribe meeting.mp3 --format=md --output-file=meeting.md\n\n# SRT 字幕\ngem-transcribe meeting.mp3 --format=srt --output-file=meeting.srt\n\n# 多言語 SRT — meeting.en.srt と meeting.ja.srt が生成される\ngem-transcribe meeting.mp3 --lang=en,ja --format=srt --output-file=meeting.srt\n\n# WebVTT 字幕（\u003cv Speaker\u003e voice タグ付き）\ngem-transcribe meeting.mp3 --format=vtt --output-file=meeting.vtt\n\n# 事前アップロード済みの GCS 音声\ngem-transcribe gs://your-bucket/recordings/2026-05-15.mp3\n```\n\n## 既知の制約\n\n### タイムスタンプ精度\n\nセグメントの `start` / `end` は Gemini が音声トークンから推定した値で、サンプル単位の正確なデコードに基づくものではありません。**おおまかな目印として扱い、同期精度が必要な用途には使用しないでください。**\n\n- **長尺音声でドリフトが累積する。** 20分以上の連続音声を1回で転記すると、後半になるほどズレが大きくなる傾向があります。数分程度の音声であれば誤差は通常1〜2秒以内。\n- **タイムスタンプが実際の音声長を超えることがある。** 実機検証で、25分の録音を `gemini-2.5-pro` で転記したところ、セグメントのタイムスタンプが30分超に達しました。`gemini-2.5-flash` でも `gemini-2.5-pro` でもこの現象は観測されており、モデル変更で確実には解決しません。\n- **`end` が duration(相対秒数)として出力される既知の癖** が Gemini 2.5 にあります。orchestrator はこれを検出して `end = start + end` に書き換え、`--verbose` で警告ログを出します。\n\nサンプル単位の精度が必要な場合(動画への字幕焼き込みなど)、これらのタイムスタンプを直接使用しないでください。下流パイプライン側での回避策(本ツールの責務外):\n\n- `ffprobe` 等でローカルに実 duration を計測し、セグメントタイムスタンプをそれに合わせてクリップ/スケーリングする\n- 音声を短いチャンクに分割してから転記し、各チャンクのタイムスタンプを再オフセットする(ドリフトをチャンク長以内に抑制)\n- WhisperX 等のフォーストアライメントを別パスで実行し、出力テキストを元音声に再アラインする\n\n### 壊れたセグメント(部分結果)\n\n特に長尺録音で、モデルが構造的に壊れたセグメントを稀に出力します。レスポンス\nスキーマで生成を制約して稀にしていますが、安全網として各セグメントを個別に\n検証します:\n\n- **既定(サルベージ):** 無効なセグメントはドロップし、件数(と概算位置)を\n  警告で報告し、**部分的な文字起こし**を返します。JSON 出力の\n  `metadata.dropped_segments` に件数を記録します。数秒を失う方が、数分の\n  文字起こしを丸ごと捨てるよりましです。\n- **`--strict`:** ドロップが1件でもあれば実行全体を失敗させます(従来の\n  全か無かの挙動)。完全な文字起こしを必要とするパイプライン向け。\n- 空の文字起こし(有効セグメント0件)は常にエラーです。\n\n既定は `config.toml` の `[transcribe] strict = true|false` で設定し、実行ごとに\n`--strict` / `--no-strict` で上書きできます(CLI が config より優先)。\n\n## 設定の優先順位\n\n高 → 低:\n\n1. CLI フラグ\n2. 環境変数（`GEM_TRANSCRIBE_*`）\n3. `.env` ファイル\n4. `~/.config/gem-transcribe/config.toml`\n5. 組み込みデフォルト値\n\n## ビルドとテスト\n\n```bash\nmake test     # uv run pytest tests/ -v\nmake lint     # ruff check + format check\nmake build    # uv build --out-dir dist/\n```\n\n## ドキュメント\n\n- [docs/ja/gem-transcribe-rfp.ja.md](docs/ja/gem-transcribe-rfp.ja.md) — 設計 RFP\n- [docs/en/gem-transcribe-rfp.md](docs/en/gem-transcribe-rfp.md) — design RFP\n\n## ライセンス\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnlink-jp%2Fgem-transcribe","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnlink-jp%2Fgem-transcribe","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnlink-jp%2Fgem-transcribe/lists"}