Skip to main content

Video Summarizer

Video summarizer demo

Turn any video — a lecture, TikTok, or Drive recording — into distilled markdown: Q&A, fact-checks, tutorials, Mermaid diagrams, essays, and more.

  • 11+ sources: Local-first summarization for YouTube, Instagram, TikTok, X, Reddit, Facebook, Drive, Dropbox, local files
  • Bring your own API keys: Works with any OpenAI-compatible LLM, Perplexity models, LiteLLM
  • CLI · Streamlit · HTTP API · Docker · Raycast · Agent skill
  • Transcript cache + optional JEV prefiltering + optional Cobalt sidecar for yt-dlp fallbacks + optional vision mode
  • Documentation: https://summarize.martino.im
  • Background: more on this project

Quick Start

Requires Python 3.7+, ffmpeg on PATH, and an OpenAI-compatible API key in .env. Recommended: install with pipx for an isolated environment.

Groq (GROQ_API_KEY) offers a free tier; OPENAI_API_KEY works with --provider openai.

pipx install martino-summarize
summarizer --init-config
echo "GROQ_API_KEY=your_key_here" > .env
summarizer --source "https://www.youtube.com/watch?v=arj7oStGLkU"

Output: summaries/watch_YYYYMMDD_HHMMSS.md.

Configuration lives in summarizer.yaml and .env.

Prefer Docker?

git clone https://github.com/martinopiaggi/summarize.git && cd summarize
cp summarizer.docker.yaml summarizer.yaml
echo "GROQ_API_KEY=your_key_here" > .env
docker compose up -d    # → http://localhost:8501

Or pull the pre-built image: docker pull ghcr.io/martinopiaggi/summarize:latest.

Optional JEV prefilter

Full guide: JEV Prefiltering.

Check Use JEV prefiltering to reveal two optional fields:

  • I want to include only… — e.g. a particular concept about this video to filter. Selects that subject even when it is not the main topic. Blank means general relevance to the video.
  • I want to exclude… — e.g. Sponsorship and self-promotion. Removes matching passages. Blank means no additional exclusions. Exclusions win when a passage matches both fields.

JEV selects original passages before the existing LLM request. It does not rewrite the transcript, change the summary prompt/model, or modify the cached transcript. The selected passages stay in source order. With JEV off, the existing pipeline is unchanged.

defaults:
  use-jev-prefiltering: true
  jev-provider: openrouter
  jev-include: "a particular concept about this video to filter"
  jev-exclude: "Sponsorship and self-promotion"
  jev-keep-ratio: 0.35

Uses the existing OpenRouter (default) or TypeSafe provider's API key, with a JEV model instead of its chat model. /systemone is the structured scoring endpoint, not a system prompt. No separate provider entry is needed.

CLI: --use-jev-prefiltering --jev-include "X" --jev-exclude "Sponsorship". YAML accepts jev-include / jev-exclude; HTTP single/batch/upload requests accept jev_include / jev_exclude. Empty strings clear configured rules.

Compression and limits:

  • Bounded batched scoring requests per eligible chunk (more than one for large chunks), with existing concurrency limits and no retries. The summary chunk size is unchanged. Independent inclusion/exclusion scores prevent a high inclusion score from overriding an exclusion.
  • The default budget is about 35% of each original chunk, including when using exclusion only. It is a ceiling, not a quota: irrelevant text never fills unused space. Whole units are retained; one best matching unit can exceed the budget. Set jev-keep-ratio: 1.0 in YAML to retain all qualifying units instead of ranking down to 35%.
  • All-rejected chunks are omitted; if none remain, return a no-match message without calling the LLM.
  • Every non-empty text chunk is scored when enabled, including single-unit chunks. On timeout, malformed response, HTTP error or an unsplittable request, explicit rules stop before any summary request rather than sending unfiltered text. With both fields blank, scoring failure warns and falls back to the original chunk.
  • Visual mode and grammar correction bypass JEV entirely, with a warning that selection rules do not apply.
  • JEV works with any configured summary chunk-size: it divides oversized scoring work into bounded requests (28 KB state / 60 KB total JSON each), then ranks all scored units across the original chunk. Short captions may be merged locally to fit; no source text is deleted. Explicit-rule requests are planned before sending any scoring or summary requests. A single unsplittable unit or scoring error stops explicit-rule runs rather than leaking unfiltered text.
  • Semantic classification is not guaranteed. Long chunks use roughly 800–1,200-character units; an exclusion in a mixed unit drops the whole unit, potentially losing useful neighboring text. Compare with an unfiltered summary for important material.

Progress reports retained characters, requests, exclusions, fallbacks and elapsed time. Automated tests use mocked scores; live classification quality, cost and latency are not benchmarked.

Contributing

git clone https://github.com/martinopiaggi/summarize.git && cd summarize
pip install -e ".[all]" pytest && pytest tests/

See CONTRIBUTING.md. License: MIT.

Release files for martino-summarize 0.3.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for martino-summarize 0.3.1
File Size Uploaded
martino_summarize-0.3.1.tar.gz 84.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for martino-summarize 0.3.1
File Interpreter ABI Platform
martino_summarize-0.3.1-py3-none-any.whl Python 3 none any Details

Total release size: 155.3 kB

Release files / martino_summarize-0.3.1.tar.gz

Download URL martino_summarize-0.3.1.tar.gz
Size 84.2 kB
Tags Source
SHA-256 checksum
How to use checksums
dd79c792993c6fce4eae0d7fa494c262c2806c8eea10b2b8e8bf73ca92d728ba
BLAKE2b-256 checksum
How to use checksums
3f25a3dc2dbf0695a3a8e56ca83238399776ed20cf91ad814c645e26fde44b48
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 22, 2026.

Transparency log

Release files / martino_summarize-0.3.1-py3-none-any.whl

Download URL martino_summarize-0.3.1-py3-none-any.whl
Size 71.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
5de03c0bfc0c8751cf1e5b9c305deeed3ec76eb3b3bde504e47e5837053aae68
BLAKE2b-256 checksum
How to use checksums
9e8f9b6d320eda2388fc90519801f0d58e8ddc2ab8499ea355121bda29407459
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 22, 2026.

Transparency log

Release history Release notifications | RSS feed

0.3.2

2 release files

This release

0.3.1 This release

2 release files

0.3.0

2 release files

0.2.2

2 release files

0.2.1

2 release files

0.2.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page