streamgrabber is a Python CLI stream downloader for movies and TV shows. Paste an IMDb, StreamIMDb, embed, or web video URL and it can auto-detect HLS/M3U8/DASH streams, subtitles, seasons, episodes, and mux the download to MKV with ffmpeg.
It is designed for Stream Detector-style workflows where the browser URL may stay fixed while the player internally changes episodes, sources, signed stream URLs, or subtitle tracks.
If Streamgrabber saves you time, consider giving the repo a star ⭐
pipx install streamgrabber
pipxis the recommended way to install CLI tools — it isolates dependencies automatically. Install pipx withbrew install pipx(macOS) orpip install pipx.
Alternatively with pip:
pip install streamgrabberAfter installation, verify it works:
streamgrabber --helpstreamgrabber 'https://www.imdb.com/title/tt0096895'
streamgrabber 'https://streamimdb.ru/embed/tv/tt3032476' --season 1 --all-episodes --quality 720 --subtitle-lang tr
streamgrabber 'https://streamimdb.ru/embed/tv/tt3032476' --episodes- IMDb / StreamIMDb video downloader for movies and TV series.
- HLS/M3U8 stream downloader with browser header preservation.
- Season and episode downloader for fixed-URL players.
- Subtitle downloader, matcher, syncer, converter, and MKV muxer.
- CLI workflow powered by Playwright, streamlink, yt-dlp, ffmpeg, and ffsubsync.
- Captures
.m3u8,.mpd,.vtt,.srtrequests from dynamic web/player pages. - Preserves important request headers such as
User-AgentandReferer. - Uses
streamlinkby default for HLS downloads. - Supports
yt-dlpas an alternate downloader. - Uses
ffmpegto mux output to.mkv. - Automatically selects best quality if you do not pass
--quality. - Automatically generates the output filename if you do not pass
--output. - For supported TV players, can list/download a specific episode or an entire season.
- Handles fixed-URL players where episode changes happen through an internal API rather than the browser URL.
- Accepts direct StreamIMDB embeds, IMDb title URLs, or bare IMDb IDs such as
tt0096895. - Can search, download, convert, and mux matching subtitles such as Turkish (
--subtitle-lang tr).
Streamgrabber automates the entire video extraction and processing pipeline by acting as a headless browser to sniff out hidden stream URLs and subtitles.
graph TD
A["Input URL\n(IMDb ID / Embed)"] --> B["Playwright Chromium\n(Network Interceptor)"]
B --> C{"Captures Data"}
C -- "HLS / M3U8" --> D["Video Downloader\n(streamlink / yt-dlp)"]
C -- "VTT / SRT" --> E["Subtitle Processor"]
C -- "Episode APIs" --> F["Series Tracker\n(Navigates seasons)"]
F -.->|"Next Episode"| B
D --> G["ffsubsync\n(Audio Sync)"]
E --> G
D --> H["ffmpeg\n(MKV Muxer)"]
G --> H
H --> I["Final Output\n(.mkv)"]
classDef input fill:#3498db,stroke:#2980b9,stroke-width:2px,color:#fff
classDef browser fill:#9b59b6,stroke:#8e44ad,stroke-width:2px,color:#fff
classDef extract fill:#e67e22,stroke:#d35400,stroke-width:2px,color:#fff
classDef tool fill:#2ecc71,stroke:#27ae60,stroke-width:2px,color:#fff
classDef output fill:#1abc9c,stroke:#16a085,stroke-width:2px,color:#fff
class A input
class B browser
class C,F extract
class D,E,G,H tool
class I output
- Python 3.11+
- Playwright Chromium
streamlinkyt-dlpoptional but recommendedffmpeg/ffprobeffsubsyncfor automatic subtitle synchronization
Check the local setup:
streamgrabber doctorExpected checks:
ffmpeg OK
ffprobe OK
streamlink OK
yt-dlp OK
ffsubsync OK
playwright chromium OK
If Playwright Chromium is missing:
cd streamgrabber
source .venv/bin/activate
python -m playwright install chromiumUse the primary command:
streamgrabberInstallations from this repository expose streamgrabber. If your shell still runs an older Node prototype, remove or overwrite that old executable from your PATH.
You can pass a direct embed URL:
streamgrabber 'https://streamimdb.ru/embed/movie/tt0096895'
streamgrabber 'https://streamimdb.ru/embed/tv/tt3032476'You can also pass an IMDb title URL:
streamgrabber 'https://www.imdb.com/title/tt0096895'Or just the IMDb ID:
streamgrabber tt0096895For IMDb inputs, the tool resolves to the matching StreamIMDB embed automatically. For example:
https://www.imdb.com/title/tt0096895
-> https://streamimdb.ru/embed/movie/tt0096895
List streams for Batman 1989 from IMDb:
streamgrabber 'https://www.imdb.com/title/tt0096895' --listDownload it with defaults:
streamgrabber 'https://www.imdb.com/title/tt0096895'Defaults still apply:
- quality:
best - output filename: automatic
Example automatic output:
Batman 1989.mkv
streamgrabber 'https://streamimdb.ru/embed/tv/tt3032476' --listThis prints the captured HLS URL, available quality variants, detected subtitles, source name, and planned output path.
streamgrabber 'https://streamimdb.ru/embed/tv/tt3032476'Defaults:
- quality:
best - output: automatically generated from the detected source/title
- container:
.mkv
Example automatic output name:
Better Call Saul 2015 1-1.mkv
For TV episode API mode, automatic names use clean season/episode format:
Better Call Saul 2015 S01E02.mkv
This is equivalent to omitting --quality:
streamgrabber 'https://streamimdb.ru/embed/tv/tt3032476' --quality beststreamgrabber 'https://streamimdb.ru/embed/tv/tt3032476' --quality 720or:
streamgrabber 'https://streamimdb.ru/embed/tv/tt3032476' --quality 360streamgrabber 'https://streamimdb.ru/embed/tv/tt3032476' --quality 720 --output 'Better Call Saul S01E01.mkv'Short options also work:
streamgrabber 'https://streamimdb.ru/embed/tv/tt3032476' -q 720 -o 'Better Call Saul S01E01.mkv'Useful before downloading a full episode:
streamgrabber 'https://streamimdb.ru/embed/tv/tt3032476' --quality 360 --duration 00:00:10 --output sample.mkvstreamgrabber 'https://streamimdb.ru/embed/tv/tt3032476' --print-commandor:
streamgrabber 'https://streamimdb.ru/embed/tv/tt3032476' --commandsSome players keep the browser URL fixed while the user changes episode inside the player. For example:
https://streamimdb.ru/embed/tv/tt3032476
The URL remains the same, but the player internally calls an API with season and episode parameters. streamgrabber supports this.
streamgrabber 'https://streamimdb.ru/embed/tv/tt3032476' --episodesExample result:
{
"title": "Better Call Saul 2015",
"episodes": {
"1": ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"],
"2": ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"],
"6": ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13"]
}
}streamgrabber 'https://streamimdb.ru/embed/tv/tt3032476' --season 1 --all-episodes --listExample:
{
"title": "Better Call Saul 2015",
"season": 1,
"episodes": [1,2,3,4,5,6,7,8,9,10]
}streamgrabber 'https://streamimdb.ru/embed/tv/tt3032476' --season 1 --episode 2Default output:
Better Call Saul 2015 S01E02.mkv
streamgrabber 'https://streamimdb.ru/embed/tv/tt3032476' --season 1 --episode 2 --quality 720streamgrabber 'https://streamimdb.ru/embed/tv/tt3032476' --season 1 --all-episodesEach episode download is retried on transient CDN/timeout failures. On retry, the tool asks the player API for a fresh signed stream URL before calling streamlink again.
Useful retry controls:
streamgrabber 'https://streamimdb.ru/embed/tv/tt3032476' --season 1 --all-episodes --download-retries 5
streamgrabber 'https://streamimdb.ru/embed/tv/tt3032476' --season 1 --all-episodes --stop-on-errorBy default, --all-episodes continues to the next episode after retries are exhausted and reports failed episode numbers at the end. Re-run the same command later to retry missing/failed files.
This downloads every episode in S01 sequentially, generating filenames like:
Better Call Saul 2015 S01E01.mkv
Better Call Saul 2015 S01E02.mkv
Better Call Saul 2015 S01E03.mkv
...
Better Call Saul 2015 S01E10.mkv
streamgrabber 'https://streamimdb.ru/embed/tv/tt3032476' --season 1 --all-episodes --quality 720streamgrabber 'https://streamimdb.ru/embed/tv/tt3032476' --season 1 --all-episodes --quality 720 --subtitle-lang trFor each episode, the tool checks player-provided default subtitles first. If none match the requested language, it searches OpenSubtitles, prefers subtitle releases that match the actual video release/source (for example BluRay x264 over a high-download WEBRip subtitle), automatically syncs the subtitle to the downloaded video audio with ffsubsync, converts SRT to WebVTT when needed, and muxes it into the MKV.
mkdir -p downloads/better-call-saul-s01
streamgrabber 'https://streamimdb.ru/embed/tv/tt3032476' --season 1 --all-episodes --quality best --output downloads/better-call-saul-s01When --output is a directory path in season mode, every episode is saved there with an automatic filename.
Use --subtitle-lang / --sub-lang to download and mux a matching subtitle.
Turkish movie example:
streamgrabber 'https://www.imdb.com/title/tt0096895' --subtitle-lang trTurkish TV episode example:
streamgrabber 'https://streamimdb.ru/embed/tv/tt3032476' --season 1 --episode 2 --subtitle-lang trSubtitle sync is enabled by default. Useful controls:
streamgrabber 'https://streamimdb.ru/embed/tv/tt3032476' --season 1 --episode 2 --subtitle-lang tr --no-sync-subtitles
streamgrabber 'https://streamimdb.ru/embed/tv/tt3032476' --season 1 --episode 2 --subtitle-lang tr --subtitle-offset -1.5--no-sync-subtitlesdisablesffsubsyncand muxes the selected subtitle as-is.--subtitle-offset SECONDSapplies an extra fixed offset; negative values make subtitles earlier, positive values make them later.--subtitle-sync-max-duration SECONDSlimits ffsubsync analysis for short tests/debugging.
Accepted Turkish values:
tr
tur
turkish
türkçe
How subtitle matching works:
- Extracts the IMDb ID from the input.
- Fetches the StreamIMDB/VaPlayer metadata for the selected movie or episode.
- Reads the actual upstream video release filename from
data.file_name. - Checks
default_subsfrom the player API first and uses the requested language if available. - If there is no matching default subtitle, searches the OpenSubtitles REST endpoint.
- For TV episodes, searches with
seasonandepisode. - Scores candidates against the video release name, prioritizing sync-critical signals:
- source/release type:
BluRay,WEBRip,WEB-DL,HDTV - season/episode:
S01E02 - codec:
x264,x265 - resolution:
1080p,720p - title/year/release-group matches
- source/release type:
- Uses download count only as a small tiebreaker/fallback, not as the main selector.
- Downloads the selected subtitle (
.gzfrom OpenSubtitles when needed). - Decodes the subtitle with the advertised encoding, e.g.
UTF-8orCP1254for Turkish. - Converts SRT to WebVTT.
- Runs
ffsubsyncagainst the downloaded video/audio to correct fixed offsets and framerate drift. - Applies any extra
--subtitle-offsetrequested by the user. - Muxes the synced subtitle into the final
.mkvas a subtitle stream.
Verify subtitle muxing with:
ffprobe -v error -select_streams s -show_entries stream=index,codec_name,codec_type -of json 'output.mkv'Expected subtitle stream:
{
"codec_name": "webvtt",
"codec_type": "subtitle"
}Default downloader:
streamlink
Use yt-dlp instead:
streamgrabber 'https://streamimdb.ru/embed/tv/tt3032476' --downloader yt-dlp --output video.mkvFor most captured HLS streams, streamlink is the recommended default.
The tool starts with a headless Playwright browser.
If headless mode does not capture a stream, it automatically retries with an automated visible browser window.
Disable the fallback:
streamgrabber 'URL' --no-fallbackForce visible browser mode:
streamgrabber 'URL' --headed --listIf you do not pass --output, streamgrabber tries to generate a useful .mkv filename automatically.
Normal capture mode:
- Finds the iframe/frame that emitted the HLS/DASH request.
- Reads visible source/player text from that frame.
- Filters noise like
Player,S01,E01,S01E01, timestamps, ad labels, and control labels. - Uses the best source name it finds.
- Falls back to useful title text if needed.
TV episode API mode:
- Uses the show title from the API.
- Adds
SxxExxautomatically.
Example:
Better Call Saul 2015 S01E02.mkv
The URL below was verified during development:
https://streamimdb.ru/embed/tv/tt3032476
Verified behavior:
- HLS master playlist captured
- Variants found: 360p and 720p
- Best quality is selected by default
- S01 episode list detected
- S01E02 short sample downloaded and muxed
- Turkish subtitle search/download/mux verified with
--subtitle-lang tr - Subtitle release matching verified: BluRay video prefers BluRay subtitle over high-download WEBRip/NF subtitle
- Automatic subtitle sync path verified with
ffsubsync ffprobeconfirmed video/audio/subtitle streams
Sample ffprobe result from a short S01E02 test:
Video: 640x360
Audio: AAC
Subtitle: WebVTT
Duration: ~5s
Container: MKV
Run tests:
cd streamgrabber
source .venv/bin/activate
pytest -qExpected at the time of writing:
39 passed
- Signed
.m3u8URLs can expire, so the tool fetches fresh episode stream URLs immediately before downloading. - DRM-protected streams are not supported.
- Use this tool only for content you are authorized to access and download.