tts-voice-creator-clone-and.../Manual.md
mARTin-B78 736aeaaeac feat: add magazine projects with layout-aware article extraction
Magazines break the audiobook pipeline's assumptions: several unrelated
articles share a page, columns run in parallel, adverts and sidebars
interrupt body copy, and a feature routinely jumps twenty pages to its
tail. Narrating page-by-page walks out of an article mid-sentence and
into an advert, so the canonical object is the article, not the page.

core/magazine.py reconstructs articles from a flat PDF: PyMuPDF extracts
blocks with bboxes and font metrics, tesseract supplies a TSV fallback so
scanned pages join the same column grouping, blocks are classified and
ordered column-major, and articles are anchored by the parsed table of
contents with "continued on page N" tails linked back.

routes/magazine.py adds 13 endpoints. Ingestion is a restart-safe
background job. Nothing is narrated until a human approves the
boundaries; podcast generation refuses unapproved articles.

Podcast mode renders an approved article as a 2-3 host discussion using
the configured LLM and voices the user picks, alongside narration rather
than instead of it.

Verified end-to-end over HTTP on a synthetic 8-page issue: the feature
came back as pages [3, 8] with its jump tail absorbed and the advert page
excluded, and an image-only rendering recovered all 47 blocks via OCR.
44 new tests; full suite 90 passing.

The Studio UI is not built — this is reachable only via the API.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-05 12:46:54 +02:00

101 lines
4.2 KiB
Markdown

# User manual
Living manual. Every feature updates this file in the same commit as the code.
> Sections for the mature features (voice library, Read Aloud, audiobook
> casting, Rehearser) are still to be written — this file was created alongside
> the magazine feature and currently documents that area only.
---
## Magazines
### Purpose
Listen to a magazine or newspaper one **article** at a time, from its true
beginning to its true end, without adverts, sidebars or a neighbouring article
spliced into the middle. Each article can be narrated by a single voice, or
turned into a podcast discussion between two or three voices you pick.
### Prerequisites
- The magazine as a PDF (native text or scanned — both work).
- At least one voice in the library for narration.
- For podcast mode: an LLM configured in Settings (`llm_url`, `llm_model`), and
two or three voices chosen as hosts.
### Step by step
1. **Add the magazine.** Studio → *Add Magazine / Paper*. Give it a title and
issue, then upload the PDF.
2. **Ingest.** Ingestion runs in the background — you can close the browser. It
renders every page, extracts text (falling back to OCR on scanned pages),
classifies each region of the layout, finds the contents page, and proposes
articles with page ranges.
3. **Review the articles.** This step is not optional and cannot be skipped.
Each proposed article shows its title, author, page range, estimated
listening time and a confidence score. Confirm the boundaries, exclude a
sidebar you do not want read, correct the title, then **Approve**.
4. **Listen.** An approved article can be narrated with the default voice, or
sent to podcast mode.
**Expected result:** the article plays from its headline to its final paragraph.
Page furniture (running heads, page numbers), adverts and pull quotes are never
read aloud.
### Confidence, and what it means
| Shown | Meaning |
|---|---|
| ~90% | The contents page listed this article — title and start page are known. |
| ~55% | Detected from a headline alone; check the boundaries carefully. |
| Low | No body copy found. Usually an advert or a section divider — reject it. |
An article is never narrated until you approve it, whatever its confidence.
### Podcast mode
Choose two or three voices as hosts. The configured LLM writes a discussion of
that article for listeners who have not read it, and each host's turns are
synthesised with their voice.
The prompt forbids inventing facts, figures or quotes that are not in the
article; if the article reaches no conclusion the hosts say so. It is still a
generated discussion, not the author's words — treat it as a summary, and read
the original for anything that matters.
Podcast generation is refused for an article you have not approved, because
unreviewed boundaries may include a neighbouring article or an advert.
### Errors
| What you see | What happened | What to do |
|---|---|---|
| "Upload the PDF first" | The project has no `source.pdf`. | Upload it, then ingest. |
| Ingestion failed | The PDF is encrypted or corrupt. | Check it opens in a viewer. |
| "Approve the article before generating a podcast" | Review gate. | Approve it first. |
| "No LLM model configured" | `llm_model` is empty. | Set it in Settings. |
| "LLM did not return usable JSON" | The model ignored the format. | Retry, or pick a stronger model. |
| "Article has too little text" | Under 200 characters — usually a stub. | Check the boundaries in review. |
### Privacy
Ingestion, OCR and storage are entirely local to the container. Podcast mode is
the exception: **the article's text is sent to whatever LLM `llm_url` points
at.** If that is a hosted API rather than a model on your own network, the
article leaves your machine. Narration uses your local TTS stack and sends
nothing outward.
### Accessibility and mobile
To be completed with the P1 interface. Planned: keyboard-navigable contents
tree and review screen, sentence highlighting that respects
`prefers-reduced-motion`, large touch targets for playback, and a driving mode
that advances images without requiring interaction.
### Offline
Ingested magazines are stored server-side, so any device on the network sees the
same library and reading progress. Playback needs the server; there is no
offline cache yet.