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

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

Built distribution (wheel)

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

Total release size: 155.3 kB

Release files / martino_summarize-0.3.0.tar.gz

Download URL martino_summarize-0.3.0.tar.gz
Size 84.2 kB
Tags Source
SHA-256 checksum
How to use checksums
16b13483a329fea9c15c1504c3559405313c1481f1fdee22a0adeda8ea64b7ff
BLAKE2b-256 checksum
How to use checksums
5f65509a7ce1536b5da97af95e2743fba597387e791bc394ac319c4247ca6e29
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.0-py3-none-any.whl

Download URL martino_summarize-0.3.0-py3-none-any.whl
Size 71.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
dff84190c062b3dba40ac2c7c58b15885dee9e8c54ecff5359ba4f52ab6a125c
BLAKE2b-256 checksum
How to use checksums
a43984c1861cb620ac6d33d2c025e37cea6693613af55650979a3572647d1635
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

0.3.1

2 release files

This release

0.3.0 This release

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