Files
dobetternorge-tools/transcribe-tech.php
T
daveadmin b84827ecea Add Transcribe docs (about/guide/tech) + refresh Redact docs
- New: transcribe-about.php, transcribe-guide.php, transcribe-tech.php
  with full en/no/uk/pl translations (3-engine cascade, diarization, vocab)
- New: translations/transcribe-about|guide|tech.php (4-lang strings)
- New: scripts/translate-pages.php (Azure gpt-4o CLI translation helper)
- Add korr-doc-links nav to transcribe.php
- Refresh redact-about|guide|tech.php — point to assets/images/redact/
- Fix all "never written to disk" wording in redact translations
- Add Min Sak/corpus save workflow to redact guide and tech privacy section
- redact.php upload hint: correct in-memory wording

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-26 10:28:06 +02:00

263 lines
14 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
declare(strict_types=1);
require_once __DIR__ . '/includes/bootstrap.php';
$uiLang = dbnToolsCurrentLanguage();
$isAuthed = dbnToolsIsAuthenticated();
$langPath = '/transcribe-tech.php';
$toolsLogin = 'https://dobetternorge.no/tools-login.php?return=' . urlencode('/transcribe.php');
$_pt = require __DIR__ . '/translations/transcribe-tech.php';
$t = $_pt[$uiLang] ?? $_pt['en'];
?>
<!doctype html>
<html lang="<?= htmlspecialchars($uiLang) ?>">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>How Transcribe Works — Three-engine cascade, Whisper GPU, pyannote diarization · Do Better Norge Tools</title>
<meta name="description" content="Technical deep-dive: Azure Batch Speech → Google Cloud Speech-to-Text v2 → Whisper large-v3 GPU cascade, pyannote.audio speaker diarization, vocabulary injection, and GPT-4o cleanup pipeline.">
<meta name="robots" content="index, follow">
<link rel="canonical" href="https://tools.dobetternorge.no/transcribe-tech.php">
<meta property="og:title" content="How Transcribe Works — Technical Reference">
<meta property="og:description" content="Three-engine cascade: Azure Speech, Google Cloud Chirp, Whisper GPU. Speaker diarization with pyannote.audio. Optional GPT-4o cleanup. Privacy-first data handling.">
<meta name="theme-color" content="#00205B">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Crimson+Pro:wght@400;600;700&family=IBM+Plex+Sans:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap">
<link rel="stylesheet" href="assets/css/tools.css">
<link rel="stylesheet" href="assets/css/dbn-tools-redesign.css">
</head>
<body class="kdoc-page">
<header class="lt-nav">
<a href="https://dobetternorge.no" class="lt-nav__brand">
<picture>
<source srcset="assets/images/logo-header.webp" type="image/webp">
<img class="lt-nav__logo" src="assets/images/logo-header.png" alt="Do Better Norge" width="140" height="36" loading="eager">
</picture>
<span class="lt-nav__badge">Legal Tools</span>
</a>
<div class="lt-nav__right">
<nav class="shell-lang-switcher" aria-label="Language">
<?php foreach (dbnToolsSupportedLanguages() as $langCode): ?>
<a href="<?= htmlspecialchars($langPath . '?lang=' . $langCode) ?>" class="<?= $langCode === $uiLang ? 'is-active' : '' ?>"><?= htmlspecialchars(dbnToolsLanguageLabel($langCode)) ?></a>
<?php endforeach; ?>
</nav>
<?php if ($isAuthed): ?>
<a href="/transcribe.php" class="lt-nav__cta lt-nav__cta--enter"><?= htmlspecialchars($t['nav_open']) ?></a>
<?php else: ?>
<a href="<?= htmlspecialchars($toolsLogin) ?>" class="lt-nav__cta"><?= htmlspecialchars($t['nav_signin']) ?></a>
<?php endif; ?>
</div>
</header>
<nav class="kdoc-doc-nav" aria-label="Transcribe documentation">
<div class="kdoc-doc-nav__inner">
<a href="/transcribe-about.php"><?= htmlspecialchars($t['nav_about']) ?></a>
<a href="/transcribe-guide.php"><?= htmlspecialchars($t['nav_guide']) ?></a>
<a href="/transcribe-tech.php" class="is-active"><?= htmlspecialchars($t['nav_howit']) ?></a>
<?php if ($isAuthed): ?><a href="/transcribe.php"><?= htmlspecialchars($t['nav_opentool']) ?></a><?php endif; ?>
</div>
</nav>
<!-- Hero -->
<section class="kdoc-hero" style="background: linear-gradient(rgba(0,15,50,0.88),rgba(0,15,50,0.93)), url('assets/images/transcribe/hero-tech.png') center/cover no-repeat;">
<div class="kdoc-hero__inner">
<p class="kdoc-hero__kicker"><?= htmlspecialchars($t['hero_kicker']) ?></p>
<h1 class="kdoc-hero__title"><?= htmlspecialchars($t['hero_title']) ?></h1>
<p class="kdoc-hero__sub"><?= htmlspecialchars($t['hero_sub']) ?></p>
<div class="kdoc-hero__stats">
<div class="kdoc-hero__stat">
<strong>3</strong>
<span><?= htmlspecialchars($t['stat_engines']) ?></span>
</div>
<div class="kdoc-hero__stat">
<strong>24×</strong>
<span><?= htmlspecialchars($t['stat_latency']) ?></span>
</div>
<div class="kdoc-hero__stat">
<strong>&lt;5%</strong>
<span><?= htmlspecialchars($t['stat_wer']) ?></span>
</div>
<div class="kdoc-hero__stat">
<strong>20</strong>
<span><?= htmlspecialchars($t['stat_speakers']) ?></span>
</div>
</div>
</div>
</section>
<div class="kdoc-section">
<div class="kdoc-toc">
<p class="kdoc-toc__title"><?= htmlspecialchars($t['toc_title']) ?></p>
<ol>
<li><a href="#arch"><?= htmlspecialchars($t['toc_1']) ?></a></li>
<li><a href="#azure"><?= htmlspecialchars($t['toc_2']) ?></a></li>
<li><a href="#google"><?= htmlspecialchars($t['toc_3']) ?></a></li>
<li><a href="#whisper"><?= htmlspecialchars($t['toc_4']) ?></a></li>
<li><a href="#diarization"><?= htmlspecialchars($t['toc_5']) ?></a></li>
<li><a href="#vocab"><?= htmlspecialchars($t['toc_6']) ?></a></li>
<li><a href="#cleanup"><?= htmlspecialchars($t['toc_7']) ?></a></li>
<li><a href="#languages"><?= htmlspecialchars($t['toc_8']) ?></a></li>
<li><a href="#privacy"><?= htmlspecialchars($t['toc_9']) ?></a></li>
</ol>
</div>
<!-- Architecture -->
<div class="kdoc-guide-step" id="arch">
<h2 class="kdoc-guide-step__title"><?= htmlspecialchars($t['arch_title']) ?></h2>
<p><?= htmlspecialchars($t['arch_intro']) ?></p>
<div class="kdoc-pipeline">
<p class="kdoc-pipeline__label"><?= htmlspecialchars($t['arch_cascade_label']) ?></p>
<div class="kdoc-pipeline__stages">
<div class="kdoc-pipeline__stage kdoc-pipeline__stage--primary">
<span class="kdoc-pipeline__num">1</span>
<strong><?= htmlspecialchars($t['arch_e1']) ?></strong>
<small><?= htmlspecialchars($t['arch_e1_sub']) ?></small>
</div>
<span class="kdoc-pipeline__arrow" aria-hidden="true">&darr;</span>
<div class="kdoc-pipeline__stage">
<span class="kdoc-pipeline__num">2</span>
<strong><?= htmlspecialchars($t['arch_e2']) ?></strong>
<small><?= htmlspecialchars($t['arch_e2_sub']) ?></small>
</div>
<span class="kdoc-pipeline__arrow" aria-hidden="true">&darr;</span>
<div class="kdoc-pipeline__stage">
<span class="kdoc-pipeline__num">3</span>
<strong><?= htmlspecialchars($t['arch_e3']) ?></strong>
<small><?= htmlspecialchars($t['arch_e3_sub']) ?></small>
</div>
<span class="kdoc-pipeline__arrow kdoc-pipeline__arrow--right" aria-hidden="true">&rarr;</span>
<div class="kdoc-pipeline__stage kdoc-pipeline__stage--optional">
<strong><?= htmlspecialchars($t['arch_post1']) ?></strong>
<small><?= htmlspecialchars($t['arch_post1_sub']) ?></small>
</div>
<span class="kdoc-pipeline__arrow" aria-hidden="true">&darr;</span>
<div class="kdoc-pipeline__stage kdoc-pipeline__stage--optional">
<strong><?= htmlspecialchars($t['arch_post2']) ?></strong>
<small><?= htmlspecialchars($t['arch_post2_sub']) ?></small>
</div>
</div>
</div>
</div>
<!-- Engine 1: Azure -->
<div class="kdoc-guide-step" id="azure">
<h2 class="kdoc-guide-step__title"><?= htmlspecialchars($t['e1_title']) ?></h2>
<p><?= htmlspecialchars($t['e1_intro']) ?></p>
<ul class="kdoc-list">
<li><?= $t['e1_model'] ?></li>
<li><?= htmlspecialchars($t['e1_latency']) ?></li>
<li><?= htmlspecialchars($t['e1_format']) ?></li>
<li><?= htmlspecialchars($t['e1_auth']) ?></li>
</ul>
</div>
<!-- Engine 2: Google -->
<div class="kdoc-guide-step" id="google">
<h2 class="kdoc-guide-step__title"><?= htmlspecialchars($t['e2_title']) ?></h2>
<p><?= htmlspecialchars($t['e2_intro']) ?></p>
<ul class="kdoc-list">
<li><?= $t['e2_model'] ?></li>
<li><?= htmlspecialchars($t['e2_latency']) ?></li>
<li><?= htmlspecialchars($t['e2_format']) ?></li>
</ul>
</div>
<!-- Engine 3: Whisper -->
<div class="kdoc-guide-step" id="whisper">
<h2 class="kdoc-guide-step__title"><?= htmlspecialchars($t['e3_title']) ?></h2>
<p><?= htmlspecialchars($t['e3_intro']) ?></p>
<ul class="kdoc-list">
<li><?= $t['e3_model'] ?></li>
<li><?= $t['e3_vocab'] ?></li>
<li><?= $t['e3_vad'] ?></li>
<li><?= htmlspecialchars($t['e3_latency']) ?></li>
</ul>
<p class="kdoc-guide-note">&#127968; <?= htmlspecialchars($t['e3_note']) ?></p>
</div>
<!-- Speaker diarization -->
<div class="kdoc-guide-step" id="diarization">
<h2 class="kdoc-guide-step__title"><?= htmlspecialchars($t['diar_title']) ?></h2>
<p><?= $t['diar_intro'] ?></p>
<p><strong><?= $t['diar_pipeline'] ?></strong></p>
<p><?= htmlspecialchars($t['diar_flow']) ?></p>
<ol class="kdoc-list">
<li><?= htmlspecialchars($t['diar_f1']) ?></li>
<li><?= htmlspecialchars($t['diar_f2']) ?></li>
<li><?= htmlspecialchars($t['diar_f3']) ?></li>
<li><?= htmlspecialchars($t['diar_f4']) ?></li>
</ol>
<p><?= $t['diar_count'] ?></p>
<p class="kdoc-guide-note"><?= htmlspecialchars($t['diar_limit']) ?></p>
</div>
<!-- Vocabulary -->
<div class="kdoc-guide-step" id="vocab">
<h2 class="kdoc-guide-step__title"><?= htmlspecialchars($t['vocab_title']) ?></h2>
<p><?= $t['vocab_intro'] ?></p>
<p><?= htmlspecialchars($t['vocab_limit']) ?></p>
<p><?= htmlspecialchars($t['vocab_builtin']) ?></p>
<p class="kdoc-guide-note">&#9888;&#65039; <?= htmlspecialchars($t['vocab_note']) ?></p>
</div>
<!-- Cleanup -->
<div class="kdoc-guide-step" id="cleanup">
<h2 class="kdoc-guide-step__title"><?= htmlspecialchars($t['cleanup_title']) ?></h2>
<p><?= htmlspecialchars($t['cleanup_intro']) ?></p>
<p><?= htmlspecialchars($t['cleanup_prompt']) ?></p>
<ul class="kdoc-list">
<li><?= $t['cleanup_mini'] ?></li>
<li><?= $t['cleanup_full'] ?></li>
</ul>
<p class="kdoc-guide-note">&#128274; <?= htmlspecialchars($t['cleanup_privacy']) ?></p>
</div>
<!-- Language support -->
<div class="kdoc-guide-step" id="languages">
<h2 class="kdoc-guide-step__title"><?= htmlspecialchars($t['lang_title']) ?></h2>
<p><?= htmlspecialchars($t['lang_intro']) ?></p>
<table class="kdoc-table">
<thead><tr>
<th><?= htmlspecialchars($t['lang_table_lang']) ?></th>
<th><?= htmlspecialchars($t['lang_table_engine']) ?></th>
<th><?= htmlspecialchars($t['lang_table_notes']) ?></th>
</tr></thead>
<tbody>
<tr><td><?= htmlspecialchars($t['lang_nb']) ?></td><td><code><?= htmlspecialchars($t['lang_nb_engine']) ?></code></td><td><?= htmlspecialchars($t['lang_nb_notes']) ?></td></tr>
<tr><td><?= htmlspecialchars($t['lang_nn']) ?></td><td><code><?= htmlspecialchars($t['lang_nn_engine']) ?></code></td><td><?= htmlspecialchars($t['lang_nn_notes']) ?></td></tr>
<tr><td><?= htmlspecialchars($t['lang_en']) ?></td><td><code><?= htmlspecialchars($t['lang_en_engine']) ?></code></td><td><?= htmlspecialchars($t['lang_en_notes']) ?></td></tr>
<tr><td><?= htmlspecialchars($t['lang_pl']) ?></td><td><code><?= htmlspecialchars($t['lang_pl_engine']) ?></code></td><td><?= htmlspecialchars($t['lang_pl_notes']) ?></td></tr>
<tr><td><?= htmlspecialchars($t['lang_uk']) ?></td><td><code><?= htmlspecialchars($t['lang_uk_engine']) ?></code></td><td><?= htmlspecialchars($t['lang_uk_notes']) ?></td></tr>
<tr><td><?= htmlspecialchars($t['lang_sv']) ?></td><td><code><?= htmlspecialchars($t['lang_sv_engine']) ?></code></td><td><?= htmlspecialchars($t['lang_sv_notes']) ?></td></tr>
<tr><td><?= htmlspecialchars($t['lang_da']) ?></td><td><code><?= htmlspecialchars($t['lang_da_engine']) ?></code></td><td><?= htmlspecialchars($t['lang_da_notes']) ?></td></tr>
<tr><td><?= htmlspecialchars($t['lang_de']) ?></td><td><code><?= htmlspecialchars($t['lang_de_engine']) ?></code></td><td><?= htmlspecialchars($t['lang_de_notes']) ?></td></tr>
<tr><td><?= htmlspecialchars($t['lang_fr']) ?></td><td><code><?= htmlspecialchars($t['lang_fr_engine']) ?></code></td><td><?= htmlspecialchars($t['lang_fr_notes']) ?></td></tr>
</tbody>
</table>
</div>
<!-- Privacy -->
<div class="kdoc-guide-step" id="privacy">
<h2 class="kdoc-guide-step__title"><?= htmlspecialchars($t['priv_title']) ?></h2>
<ul class="kdoc-list">
<li>&#128274; <?= htmlspecialchars($t['priv_1']) ?></li>
<li>&#9729;&#65039; <?= htmlspecialchars($t['priv_2']) ?></li>
<li>&#127968; <?= htmlspecialchars($t['priv_3']) ?></li>
<li>&#129302; <?= htmlspecialchars($t['priv_4']) ?></li>
<li>&#9989; <?= htmlspecialchars($t['priv_5']) ?></li>
</ul>
</div>
</div><!-- /.kdoc-section -->
<?php require_once __DIR__ . '/includes/footer.php'; ?>
<script src="assets/js/tools.js" defer></script>
</body>
</html>