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.2

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.2
File Size Uploaded
martino_summarize-0.3.2.tar.gz 84.2 kB Details

Built distribution (wheel)

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

Total release size: 155.3 kB

Release files / martino_summarize-0.3.2.tar.gz

Download URL martino_summarize-0.3.2.tar.gz
Size 84.2 kB
Tags Source
SHA-256 checksum
How to use checksums
e3ed81593bca09444f2a0c52b37819146a1e338a32bfcf14be405c86ed620800
BLAKE2b-256 checksum
How to use checksums
5e81459544d9d70a17c19059fce785f05ea37e64ce74d4027f02dab90c037985
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 25, 2026.

Transparency log

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

Download URL martino_summarize-0.3.2-py3-none-any.whl
Size 71.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
64ca3380e16b5f95afe74910021634e80b1492fbdeed1d1d40ea4fdbbbb07a7f
BLAKE2b-256 checksum
How to use checksums
afff11e112cab4daf9523460b2ca0e2885bf0c2086afc9f3e2fd977e77abe914
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 25, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.3.2 This release

2 release files

0.3.1

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