PHPackages                             martin3r/platforms-whisper - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. martin3r/platforms-whisper

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

martin3r/platforms-whisper
==========================

Whisper Module for Platform - Browser audio recording with AssemblyAI transcription + speaker diarization + LLM summary

066—5.3%PHP

Since Jun 28Pushed 1mo agoCompare

[ Source](https://github.com/martin3r-me/platforms-whisper)[ Packagist](https://packagist.org/packages/martin3r/platforms-whisper)[ RSS](/packages/martin3r-platforms-whisper/feed)WikiDiscussions main Synced today

READMEChangelogDependenciesVersions (1)Used By (0)

Platform Whisper Module
=======================

[](#platform-whisper-module)

Audio-Aufnahme → **AssemblyAI** Transkription mit Speaker Diarization (oder Dual-Channel Multichannel) → Transkript + Segmente + Sprecher landen persistent.

**Scope:** Whisper liefert Transkripte und Sprecher-Segmente. Höhere Layer (Zusammenfassungen, Action Items, Q&amp;A, semantischer Titel) leben im **Inbox-Modul** als Enrichment-Pipeline. Whisper feuert nach `status=completed` einen Observer, der das Recording in den Inbox-Triage-Layer übergibt.

Features
--------

[](#features)

- Browser-Recorder via MediaRecorder API (Opus, mono)
- Dual-Channel-Upload (`POST /api/whisper/recordings/dual`, Bearer-Auth): zwei WAV-Spuren (`mic` + `loopback`) werden serverseitig zu Stereo gemerged und an AssemblyAI im Multichannel-Mode geschickt
- **Speaker Diarization** bei Mono / **Multichannel** bei Dual-Spur (Kanal-Identifier statt VAD-Ratespiel)
- **Queue-basiert**: Upload kehrt sofort zurück, Job verarbeitet im Hintergrund
- **Audio-Persistence**: Original-File wandert via `ContextFileService` auf S3, Recording behält File-Reference (`kind: audio_original`)
- **Inbox-Bridge**: Fertige Recordings werden automatisch als `InboxItem` mit Channel `recording` in die Inbox ingested
- **Organization-Linking**: `HasOrganizationContexts` (morph\_alias `whisper_recording`)

Voraussetzungen (Host-App)
--------------------------

[](#voraussetzungen-host-app)

### 1. Composer

[](#1-composer)

```
"require": {
    "martin3r/platforms-whisper": "dev-main"
},
"repositories": [
    {
        "type": "vcs",
        "url": "git@github.com:martin3r-me/platforms-whisper.git"
    }
]
```

```
composer update martin3r/platforms-whisper
php artisan migrate
```

### 2. API Keys

[](#2-api-keys)

```
# Transkription + Diarization
ASSEMBLYAI_API_KEY=...
```

### 3. Queue Worker

[](#3-queue-worker)

```
php artisan queue:work --timeout=1800 --tries=1
```

Das Polling gegen AssemblyAI läuft während `handle()`. `--timeout=1800` deckt auch stundenlange Meetings ab.

### 4. PHP Limits

[](#4-php-limits)

In `php.ini` (oder `.user.ini`):

```
upload_max_filesize = 500M
post_max_size = 500M
max_execution_time = 300
memory_limit = 256M
```

Datenmodell
-----------

[](#datenmodell)

Tabelle `whisper_recordings` (Kern-Felder):

FeldTypBemerkungid / uuidPKUuidV7team\_id / created\_by\_user\_idFKTeam-Scopetitlestring"Aufnahme vom dd.mm.yyyy HH:ii" (semantischer Titel kommt aus Inbox-Enrichment)transcriptlongTextFließtext-Transkriptsegmentsjson`[{speaker, start, end, text}, …]`speakers\_countintAnzahl erkannter Sprecherspeaker\_mapjsonOptional: A/B/C → AnzeigenamelanguagestringISO-Code, AssemblyAI-detectedduration\_secondsintmodelstringz. B. `assemblyai:universal-3-pro`provider\_idstringAssemblyAI transcript idstatusenumpending / processing / completed / failederror\_messagetextbei failedWorkflow
--------

[](#workflow)

1. Upload-Quelle:
    - Browser-Recorder auf `/whisper` → `POST /whisper/upload` (Session-Auth, mono Opus/WebM)
    - Dual-Channel Client → `POST /api/whisper/recordings/dual` (Bearer-Auth, zwei WAVs `mic` + `loopback`, serverseitig zu Stereo gemerged)
2. Controller speichert Audio in `storage/app/whisper-tmp/`, legt Recording mit `status=pending` an, dispatched `TranscribeRecordingJob`
3. Job (Worker):
    - Status → `processing`
    - `AssemblyAiTranscriptionService::transcribe()`: Upload → Submit → Polling bis `completed` (Mono: `speaker_labels`; Dual: `multichannel`)
    - Recording bekommt `transcript`, `segments`, `speakers_count`, `language`, `duration_seconds`, `provider_id`
    - Original-Audio wird via `ContextFileService` persistiert (File-Reference `kind: audio_original`)
    - Status → `completed` → Tmp-Datei wird gelöscht
4. `WhisperRecordingInboxObserver` feuert auf den completed-Übergang und dispatched `IngestRecordingToInboxJob` → Recording wandert als `InboxItem` in den Inbox-Triage-Layer
5. Show-Page pollt alle 3 s während `pending`/`processing`, zeigt Sprecher-Blöcke + Fließtext + Inline-Audio-Player

Fehler-Handling
---------------

[](#fehler-handling)

- Kein `ASSEMBLYAI_API_KEY` → Job wirft Exception → Status `failed`
- AssemblyAI-Fehler (Upload/Submit/Poll) → Status `failed`, `error_message` mit API-Response
- Polling-Timeout (`WHISPER_AAI_MAX_WAIT`) → Status `failed`
- Bei `failed`: Tmp-Datei wird trotzdem aufgeräumt

LLM-Tools
---------

[](#llm-tools)

- `whisper.overview.GET` — Modul-Übersicht
- `whisper.recordings.GET` — Liste aller Aufnahmen
- `whisper.recording.GET` — Einzel-Aufnahme (inkl. Segmente)
- `whisper.recordings.PUT` — Metadaten updaten
- `whisper.recordings.DELETE` — Aufnahme löschen
- `whisper.recordings.search.GET` — Volltextsuche
- `whisper.recording.transcript.GET` — Reines Transkript + Segments (LLM-freundlich)

Config Overrides
----------------

[](#config-overrides)

```
WHISPER_AAI_REQUEST_TIMEOUT=120     # HTTP-Timeout pro AssemblyAI-Call
WHISPER_AAI_POLL_INTERVAL=3         # Polling-Intervall in Sekunden
WHISPER_AAI_MAX_WAIT=1500           # Maximale Polling-Dauer
WHISPER_AAI_SPEAKER_LABELS=true     # Diarization an/aus
WHISPER_AAI_SPEAKERS_EXPECTED=0     # 0 = automatisch, sonst erwartete Anzahl
```

Out-of-Scope
------------

[](#out-of-scope)

- Editierbares Transkript
- Echtzeit-Streaming
- Speaker-Identifikation (Zuordnung zu Personen/Namen) — liefert nur `A`, `B`, `C` … plus optionalen `speaker_map`-Override
- Zusammenfassung / Action Items / Q&amp;A — lebt im Inbox-Modul als Enrichment-Pipeline

###  Health Score

22

—

LowBetter than 21% of packages

Maintenance61

Regular maintenance activity

Popularity8

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity11

Early-stage or recently created project

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

### Community

Maintainers

![](https://www.gravatar.com/avatar/624263472b888cbddf2459047c1ab71dafd2a5875da576e3675b9c3584dad922?d=identicon)[martin3r](/maintainers/martin3r)

---

Top Contributors

[![martin3r-me](https://avatars.githubusercontent.com/u/187852765?v=4)](https://github.com/martin3r-me "martin3r-me (31 commits)")

### Embed Badge

![Health badge](/badges/martin3r-platforms-whisper/health.svg)

```
[![Health](https://phpackages.com/badges/martin3r-platforms-whisper/health.svg)](https://phpackages.com/packages/martin3r-platforms-whisper)
```

###  Alternatives

[digital-creative/icon-action-toolbar

Allows you to update a single column of a resource all at once.

2628.9k](/packages/digital-creative-icon-action-toolbar)[friendsoftypo3/widgets

Dashboard Widgets Collection

1129.4k](/packages/friendsoftypo3-widgets)[artificertech/laravel-relationship-events

Missing relationship events for Laravel

1218.8k](/packages/artificertech-laravel-relationship-events)[apanly/browser-detector

根据UA判断浏览器类型和版本，操作系统，设备型号

312.7k](/packages/apanly-browser-detector)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
