streamgrabber 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- streamgrabber-0.1.0/.gitignore +6 -0
- streamgrabber-0.1.0/LICENSE +21 -0
- streamgrabber-0.1.0/PKG-INFO +548 -0
- streamgrabber-0.1.0/README.md +516 -0
- streamgrabber-0.1.0/pyproject.toml +61 -0
- streamgrabber-0.1.0/src/streamgrabber/__init__.py +1 -0
- streamgrabber-0.1.0/src/streamgrabber/cli.py +471 -0
- streamgrabber-0.1.0/src/streamgrabber/detector.py +163 -0
- streamgrabber-0.1.0/src/streamgrabber/doctor.py +70 -0
- streamgrabber-0.1.0/src/streamgrabber/downloader.py +85 -0
- streamgrabber-0.1.0/src/streamgrabber/manifest.py +55 -0
- streamgrabber-0.1.0/src/streamgrabber/models.py +44 -0
- streamgrabber-0.1.0/src/streamgrabber/muxer.py +27 -0
- streamgrabber-0.1.0/src/streamgrabber/naming.py +22 -0
- streamgrabber-0.1.0/src/streamgrabber/resolver.py +68 -0
- streamgrabber-0.1.0/src/streamgrabber/source_name.py +49 -0
- streamgrabber-0.1.0/src/streamgrabber/subsync.py +129 -0
- streamgrabber-0.1.0/src/streamgrabber/subtitles.py +364 -0
- streamgrabber-0.1.0/src/streamgrabber/vaplayer.py +84 -0
- streamgrabber-0.1.0/tests/test_core.py +125 -0
- streamgrabber-0.1.0/tests/test_doctor.py +17 -0
- streamgrabber-0.1.0/tests/test_naming.py +17 -0
- streamgrabber-0.1.0/tests/test_resolver.py +57 -0
- streamgrabber-0.1.0/tests/test_source_name.py +17 -0
- streamgrabber-0.1.0/tests/test_subsync.py +52 -0
- streamgrabber-0.1.0/tests/test_subtitles.py +89 -0
- streamgrabber-0.1.0/tests/test_vaplayer.py +32 -0
- streamgrabber-0.1.0/tools/inspect_episodes.py +43 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Enki013
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,548 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: streamgrabber
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Capture HLS/DASH streams from web pages and download them with preserved headers
|
|
5
|
+
Project-URL: Homepage, https://github.com/Enki013/streamgrabber
|
|
6
|
+
Project-URL: Source, https://github.com/Enki013/streamgrabber
|
|
7
|
+
Project-URL: Bug Tracker, https://github.com/Enki013/streamgrabber/issues
|
|
8
|
+
Author-email: Enki013 <enessalman1300@gmail.com>
|
|
9
|
+
License: MIT
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Keywords: dash,downloader,hls,imdb,m3u8,playwright,stream,streamlink,yt-dlp
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Environment :: Console
|
|
14
|
+
Classifier: Intended Audience :: End Users/Desktop
|
|
15
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
16
|
+
Classifier: Operating System :: OS Independent
|
|
17
|
+
Classifier: Programming Language :: Python :: 3
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
21
|
+
Classifier: Topic :: Internet :: WWW/HTTP
|
|
22
|
+
Classifier: Topic :: Multimedia :: Video
|
|
23
|
+
Classifier: Topic :: Utilities
|
|
24
|
+
Requires-Python: >=3.11
|
|
25
|
+
Requires-Dist: ffsubsync>=0.5.0
|
|
26
|
+
Requires-Dist: m3u8>=6.0.0
|
|
27
|
+
Requires-Dist: platformdirs>=4.3.6
|
|
28
|
+
Requires-Dist: playwright>=1.49.0
|
|
29
|
+
Requires-Dist: rich>=13.9.4
|
|
30
|
+
Requires-Dist: typer>=0.15.1
|
|
31
|
+
Description-Content-Type: text/markdown
|
|
32
|
+
|
|
33
|
+
# Streamgrabber — IMDb/StreamIMDb HLS/M3U8 Video Downloader
|
|
34
|
+
|
|
35
|
+
`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`.
|
|
36
|
+
|
|
37
|
+
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.
|
|
38
|
+
|
|
39
|
+
If Streamgrabber saves you time, consider giving the repo a star ⭐
|
|
40
|
+
|
|
41
|
+
## Quick examples
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
streamgrabber 'https://www.imdb.com/title/tt0096895'
|
|
45
|
+
streamgrabber 'https://streamimdb.ru/embed/tv/tt3032476' --season 1 --all-episodes --quality 720 --subtitle-lang tr
|
|
46
|
+
streamgrabber 'https://streamimdb.ru/embed/tv/tt3032476' --episodes
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## What Streamgrabber does
|
|
50
|
+
|
|
51
|
+
- IMDb / StreamIMDb video downloader for movies and TV series.
|
|
52
|
+
- HLS/M3U8 stream downloader with browser header preservation.
|
|
53
|
+
- Season and episode downloader for fixed-URL players.
|
|
54
|
+
- Subtitle downloader, matcher, syncer, converter, and MKV muxer.
|
|
55
|
+
- CLI workflow powered by Playwright, streamlink, yt-dlp, ffmpeg, and ffsubsync.
|
|
56
|
+
|
|
57
|
+
## Features
|
|
58
|
+
|
|
59
|
+
- Captures `.m3u8`, `.mpd`, `.vtt`, `.srt` requests from dynamic web/player pages.
|
|
60
|
+
- Preserves important request headers such as `User-Agent` and `Referer`.
|
|
61
|
+
- Uses `streamlink` by default for HLS downloads.
|
|
62
|
+
- Supports `yt-dlp` as an alternate downloader.
|
|
63
|
+
- Uses `ffmpeg` to mux output to `.mkv`.
|
|
64
|
+
- Automatically selects **best quality** if you do not pass `--quality`.
|
|
65
|
+
- Automatically generates the output filename if you do not pass `--output`.
|
|
66
|
+
- For supported TV players, can list/download a specific episode or an entire season.
|
|
67
|
+
- Handles fixed-URL players where episode changes happen through an internal API rather than the browser URL.
|
|
68
|
+
- Accepts direct StreamIMDB embeds, IMDb title URLs, or bare IMDb IDs such as `tt0096895`.
|
|
69
|
+
- Can search, download, convert, and mux matching subtitles such as Turkish (`--subtitle-lang tr`).
|
|
70
|
+
|
|
71
|
+
## Requirements
|
|
72
|
+
|
|
73
|
+
- Python 3.11+
|
|
74
|
+
- Playwright Chromium
|
|
75
|
+
- `streamlink`
|
|
76
|
+
- `yt-dlp` optional but recommended
|
|
77
|
+
- `ffmpeg` / `ffprobe`
|
|
78
|
+
- `ffsubsync` for automatic subtitle synchronization
|
|
79
|
+
|
|
80
|
+
Check the local setup:
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
streamgrabber doctor
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Expected checks:
|
|
87
|
+
|
|
88
|
+
```text
|
|
89
|
+
ffmpeg OK
|
|
90
|
+
ffprobe OK
|
|
91
|
+
streamlink OK
|
|
92
|
+
yt-dlp OK
|
|
93
|
+
ffsubsync OK
|
|
94
|
+
playwright chromium OK
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
If Playwright Chromium is missing:
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
cd streamgrabber
|
|
101
|
+
source .venv/bin/activate
|
|
102
|
+
python -m playwright install chromium
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
## Command name
|
|
106
|
+
|
|
107
|
+
Use the primary command:
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
streamgrabber
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
Installations from this repository expose `streamgrabber`. If your shell still runs an older Node prototype, remove or overwrite that old executable from your `PATH`.
|
|
114
|
+
|
|
115
|
+
## Basic usage
|
|
116
|
+
|
|
117
|
+
### Supported input forms
|
|
118
|
+
|
|
119
|
+
You can pass a direct embed URL:
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
streamgrabber 'https://streamimdb.ru/embed/movie/tt0096895'
|
|
123
|
+
streamgrabber 'https://streamimdb.ru/embed/tv/tt3032476'
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
You can also pass an IMDb title URL:
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
streamgrabber 'https://www.imdb.com/title/tt0096895'
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
Or just the IMDb ID:
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
streamgrabber tt0096895
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
For IMDb inputs, the tool resolves to the matching StreamIMDB embed automatically. For example:
|
|
139
|
+
|
|
140
|
+
```text
|
|
141
|
+
https://www.imdb.com/title/tt0096895
|
|
142
|
+
-> https://streamimdb.ru/embed/movie/tt0096895
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
### IMDb movie example
|
|
146
|
+
|
|
147
|
+
List streams for Batman 1989 from IMDb:
|
|
148
|
+
|
|
149
|
+
```bash
|
|
150
|
+
streamgrabber 'https://www.imdb.com/title/tt0096895' --list
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
Download it with defaults:
|
|
154
|
+
|
|
155
|
+
```bash
|
|
156
|
+
streamgrabber 'https://www.imdb.com/title/tt0096895'
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
Defaults still apply:
|
|
160
|
+
|
|
161
|
+
- quality: `best`
|
|
162
|
+
- output filename: automatic
|
|
163
|
+
|
|
164
|
+
Example automatic output:
|
|
165
|
+
|
|
166
|
+
```text
|
|
167
|
+
Batman 1989.mkv
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
### List detected streams
|
|
171
|
+
|
|
172
|
+
```bash
|
|
173
|
+
streamgrabber 'https://streamimdb.ru/embed/tv/tt3032476' --list
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
This prints the captured HLS URL, available quality variants, detected subtitles, source name, and planned output path.
|
|
177
|
+
|
|
178
|
+
### Download without specifying quality or filename
|
|
179
|
+
|
|
180
|
+
```bash
|
|
181
|
+
streamgrabber 'https://streamimdb.ru/embed/tv/tt3032476'
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
Defaults:
|
|
185
|
+
|
|
186
|
+
- quality: `best`
|
|
187
|
+
- output: automatically generated from the detected source/title
|
|
188
|
+
- container: `.mkv`
|
|
189
|
+
|
|
190
|
+
Example automatic output name:
|
|
191
|
+
|
|
192
|
+
```text
|
|
193
|
+
Better Call Saul 2015 1-1.mkv
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
For TV episode API mode, automatic names use clean season/episode format:
|
|
197
|
+
|
|
198
|
+
```text
|
|
199
|
+
Better Call Saul 2015 S01E02.mkv
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
### Download best quality explicitly
|
|
203
|
+
|
|
204
|
+
This is equivalent to omitting `--quality`:
|
|
205
|
+
|
|
206
|
+
```bash
|
|
207
|
+
streamgrabber 'https://streamimdb.ru/embed/tv/tt3032476' --quality best
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
### Download a specific quality
|
|
211
|
+
|
|
212
|
+
```bash
|
|
213
|
+
streamgrabber 'https://streamimdb.ru/embed/tv/tt3032476' --quality 720
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
or:
|
|
217
|
+
|
|
218
|
+
```bash
|
|
219
|
+
streamgrabber 'https://streamimdb.ru/embed/tv/tt3032476' --quality 360
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
### Manually choose output filename
|
|
223
|
+
|
|
224
|
+
```bash
|
|
225
|
+
streamgrabber 'https://streamimdb.ru/embed/tv/tt3032476' --quality 720 --output 'Better Call Saul S01E01.mkv'
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
Short options also work:
|
|
229
|
+
|
|
230
|
+
```bash
|
|
231
|
+
streamgrabber 'https://streamimdb.ru/embed/tv/tt3032476' -q 720 -o 'Better Call Saul S01E01.mkv'
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
### Short test download
|
|
235
|
+
|
|
236
|
+
Useful before downloading a full episode:
|
|
237
|
+
|
|
238
|
+
```bash
|
|
239
|
+
streamgrabber 'https://streamimdb.ru/embed/tv/tt3032476' --quality 360 --duration 00:00:10 --output sample.mkv
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
### Print commands without downloading
|
|
243
|
+
|
|
244
|
+
```bash
|
|
245
|
+
streamgrabber 'https://streamimdb.ru/embed/tv/tt3032476' --print-command
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
or:
|
|
249
|
+
|
|
250
|
+
```bash
|
|
251
|
+
streamgrabber 'https://streamimdb.ru/embed/tv/tt3032476' --commands
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
## TV season / episode mode
|
|
255
|
+
|
|
256
|
+
Some players keep the browser URL fixed while the user changes episode inside the player. For example:
|
|
257
|
+
|
|
258
|
+
```text
|
|
259
|
+
https://streamimdb.ru/embed/tv/tt3032476
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
The URL remains the same, but the player internally calls an API with `season` and `episode` parameters. `streamgrabber` supports this.
|
|
263
|
+
|
|
264
|
+
### List all available seasons and episodes
|
|
265
|
+
|
|
266
|
+
```bash
|
|
267
|
+
streamgrabber 'https://streamimdb.ru/embed/tv/tt3032476' --episodes
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
Example result:
|
|
271
|
+
|
|
272
|
+
```json
|
|
273
|
+
{
|
|
274
|
+
"title": "Better Call Saul 2015",
|
|
275
|
+
"episodes": {
|
|
276
|
+
"1": ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"],
|
|
277
|
+
"2": ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"],
|
|
278
|
+
"6": ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13"]
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
### List one season
|
|
284
|
+
|
|
285
|
+
```bash
|
|
286
|
+
streamgrabber 'https://streamimdb.ru/embed/tv/tt3032476' --season 1 --all-episodes --list
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
Example:
|
|
290
|
+
|
|
291
|
+
```json
|
|
292
|
+
{
|
|
293
|
+
"title": "Better Call Saul 2015",
|
|
294
|
+
"season": 1,
|
|
295
|
+
"episodes": [1,2,3,4,5,6,7,8,9,10]
|
|
296
|
+
}
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
### Download one episode
|
|
300
|
+
|
|
301
|
+
```bash
|
|
302
|
+
streamgrabber 'https://streamimdb.ru/embed/tv/tt3032476' --season 1 --episode 2
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
Default output:
|
|
306
|
+
|
|
307
|
+
```text
|
|
308
|
+
Better Call Saul 2015 S01E02.mkv
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
### Download one episode with quality
|
|
312
|
+
|
|
313
|
+
```bash
|
|
314
|
+
streamgrabber 'https://streamimdb.ru/embed/tv/tt3032476' --season 1 --episode 2 --quality 720
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
### Download an entire season
|
|
318
|
+
|
|
319
|
+
```bash
|
|
320
|
+
streamgrabber 'https://streamimdb.ru/embed/tv/tt3032476' --season 1 --all-episodes
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
Each 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.
|
|
324
|
+
|
|
325
|
+
Useful retry controls:
|
|
326
|
+
|
|
327
|
+
```bash
|
|
328
|
+
streamgrabber 'https://streamimdb.ru/embed/tv/tt3032476' --season 1 --all-episodes --download-retries 5
|
|
329
|
+
streamgrabber 'https://streamimdb.ru/embed/tv/tt3032476' --season 1 --all-episodes --stop-on-error
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
By 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.
|
|
333
|
+
|
|
334
|
+
This downloads every episode in S01 sequentially, generating filenames like:
|
|
335
|
+
|
|
336
|
+
```text
|
|
337
|
+
Better Call Saul 2015 S01E01.mkv
|
|
338
|
+
Better Call Saul 2015 S01E02.mkv
|
|
339
|
+
Better Call Saul 2015 S01E03.mkv
|
|
340
|
+
...
|
|
341
|
+
Better Call Saul 2015 S01E10.mkv
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
### Download an entire season at 720p
|
|
345
|
+
|
|
346
|
+
```bash
|
|
347
|
+
streamgrabber 'https://streamimdb.ru/embed/tv/tt3032476' --season 1 --all-episodes --quality 720
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
### Download an entire season with Turkish subtitles
|
|
351
|
+
|
|
352
|
+
```bash
|
|
353
|
+
streamgrabber 'https://streamimdb.ru/embed/tv/tt3032476' --season 1 --all-episodes --quality 720 --subtitle-lang tr
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
For 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.
|
|
357
|
+
|
|
358
|
+
### Download an entire season into a directory
|
|
359
|
+
|
|
360
|
+
```bash
|
|
361
|
+
mkdir -p downloads/better-call-saul-s01
|
|
362
|
+
|
|
363
|
+
streamgrabber 'https://streamimdb.ru/embed/tv/tt3032476' --season 1 --all-episodes --quality best --output downloads/better-call-saul-s01
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
When `--output` is a directory path in season mode, every episode is saved there with an automatic filename.
|
|
367
|
+
|
|
368
|
+
## Subtitles
|
|
369
|
+
|
|
370
|
+
Use `--subtitle-lang` / `--sub-lang` to download and mux a matching subtitle.
|
|
371
|
+
|
|
372
|
+
Turkish movie example:
|
|
373
|
+
|
|
374
|
+
```bash
|
|
375
|
+
streamgrabber 'https://www.imdb.com/title/tt0096895' --subtitle-lang tr
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
Turkish TV episode example:
|
|
379
|
+
|
|
380
|
+
```bash
|
|
381
|
+
streamgrabber 'https://streamimdb.ru/embed/tv/tt3032476' --season 1 --episode 2 --subtitle-lang tr
|
|
382
|
+
```
|
|
383
|
+
|
|
384
|
+
Subtitle sync is enabled by default. Useful controls:
|
|
385
|
+
|
|
386
|
+
```bash
|
|
387
|
+
streamgrabber 'https://streamimdb.ru/embed/tv/tt3032476' --season 1 --episode 2 --subtitle-lang tr --no-sync-subtitles
|
|
388
|
+
streamgrabber 'https://streamimdb.ru/embed/tv/tt3032476' --season 1 --episode 2 --subtitle-lang tr --subtitle-offset -1.5
|
|
389
|
+
```
|
|
390
|
+
|
|
391
|
+
- `--no-sync-subtitles` disables `ffsubsync` and muxes the selected subtitle as-is.
|
|
392
|
+
- `--subtitle-offset SECONDS` applies an extra fixed offset; negative values make subtitles earlier, positive values make them later.
|
|
393
|
+
- `--subtitle-sync-max-duration SECONDS` limits ffsubsync analysis for short tests/debugging.
|
|
394
|
+
|
|
395
|
+
Accepted Turkish values:
|
|
396
|
+
|
|
397
|
+
```text
|
|
398
|
+
tr
|
|
399
|
+
tur
|
|
400
|
+
turkish
|
|
401
|
+
türkçe
|
|
402
|
+
```
|
|
403
|
+
|
|
404
|
+
How subtitle matching works:
|
|
405
|
+
|
|
406
|
+
1. Extracts the IMDb ID from the input.
|
|
407
|
+
2. Fetches the StreamIMDB/VaPlayer metadata for the selected movie or episode.
|
|
408
|
+
3. Reads the actual upstream video release filename from `data.file_name`.
|
|
409
|
+
4. Checks `default_subs` from the player API first and uses the requested language if available.
|
|
410
|
+
5. If there is no matching default subtitle, searches the OpenSubtitles REST endpoint.
|
|
411
|
+
6. For TV episodes, searches with `season` and `episode`.
|
|
412
|
+
7. Scores candidates against the video release name, prioritizing sync-critical signals:
|
|
413
|
+
- source/release type: `BluRay`, `WEBRip`, `WEB-DL`, `HDTV`
|
|
414
|
+
- season/episode: `S01E02`
|
|
415
|
+
- codec: `x264`, `x265`
|
|
416
|
+
- resolution: `1080p`, `720p`
|
|
417
|
+
- title/year/release-group matches
|
|
418
|
+
8. Uses download count only as a small tiebreaker/fallback, not as the main selector.
|
|
419
|
+
9. Downloads the selected subtitle (`.gz` from OpenSubtitles when needed).
|
|
420
|
+
10. Decodes the subtitle with the advertised encoding, e.g. `UTF-8` or `CP1254` for Turkish.
|
|
421
|
+
11. Converts SRT to WebVTT.
|
|
422
|
+
12. Runs `ffsubsync` against the downloaded video/audio to correct fixed offsets and framerate drift.
|
|
423
|
+
13. Applies any extra `--subtitle-offset` requested by the user.
|
|
424
|
+
14. Muxes the synced subtitle into the final `.mkv` as a subtitle stream.
|
|
425
|
+
|
|
426
|
+
Verify subtitle muxing with:
|
|
427
|
+
|
|
428
|
+
```bash
|
|
429
|
+
ffprobe -v error -select_streams s -show_entries stream=index,codec_name,codec_type -of json 'output.mkv'
|
|
430
|
+
```
|
|
431
|
+
|
|
432
|
+
Expected subtitle stream:
|
|
433
|
+
|
|
434
|
+
```json
|
|
435
|
+
{
|
|
436
|
+
"codec_name": "webvtt",
|
|
437
|
+
"codec_type": "subtitle"
|
|
438
|
+
}
|
|
439
|
+
```
|
|
440
|
+
|
|
441
|
+
## Downloader options
|
|
442
|
+
|
|
443
|
+
Default downloader:
|
|
444
|
+
|
|
445
|
+
```text
|
|
446
|
+
streamlink
|
|
447
|
+
```
|
|
448
|
+
|
|
449
|
+
Use `yt-dlp` instead:
|
|
450
|
+
|
|
451
|
+
```bash
|
|
452
|
+
streamgrabber 'https://streamimdb.ru/embed/tv/tt3032476' --downloader yt-dlp --output video.mkv
|
|
453
|
+
```
|
|
454
|
+
|
|
455
|
+
For most captured HLS streams, `streamlink` is the recommended default.
|
|
456
|
+
|
|
457
|
+
## Browser behavior
|
|
458
|
+
|
|
459
|
+
The tool starts with a headless Playwright browser.
|
|
460
|
+
|
|
461
|
+
If headless mode does not capture a stream, it automatically retries with an automated visible browser window.
|
|
462
|
+
|
|
463
|
+
Disable the fallback:
|
|
464
|
+
|
|
465
|
+
```bash
|
|
466
|
+
streamgrabber 'URL' --no-fallback
|
|
467
|
+
```
|
|
468
|
+
|
|
469
|
+
Force visible browser mode:
|
|
470
|
+
|
|
471
|
+
```bash
|
|
472
|
+
streamgrabber 'URL' --headed --list
|
|
473
|
+
```
|
|
474
|
+
|
|
475
|
+
## Output naming
|
|
476
|
+
|
|
477
|
+
If you do not pass `--output`, `streamgrabber` tries to generate a useful `.mkv` filename automatically.
|
|
478
|
+
|
|
479
|
+
Normal capture mode:
|
|
480
|
+
|
|
481
|
+
1. Finds the iframe/frame that emitted the HLS/DASH request.
|
|
482
|
+
2. Reads visible source/player text from that frame.
|
|
483
|
+
3. Filters noise like `Player`, `S01`, `E01`, `S01E01`, timestamps, ad labels, and control labels.
|
|
484
|
+
4. Uses the best source name it finds.
|
|
485
|
+
5. Falls back to useful title text if needed.
|
|
486
|
+
|
|
487
|
+
TV episode API mode:
|
|
488
|
+
|
|
489
|
+
- Uses the show title from the API.
|
|
490
|
+
- Adds `SxxExx` automatically.
|
|
491
|
+
|
|
492
|
+
Example:
|
|
493
|
+
|
|
494
|
+
```text
|
|
495
|
+
Better Call Saul 2015 S01E02.mkv
|
|
496
|
+
```
|
|
497
|
+
|
|
498
|
+
## Verified sample
|
|
499
|
+
|
|
500
|
+
The URL below was verified during development:
|
|
501
|
+
|
|
502
|
+
```text
|
|
503
|
+
https://streamimdb.ru/embed/tv/tt3032476
|
|
504
|
+
```
|
|
505
|
+
|
|
506
|
+
Verified behavior:
|
|
507
|
+
|
|
508
|
+
- HLS master playlist captured
|
|
509
|
+
- Variants found: 360p and 720p
|
|
510
|
+
- Best quality is selected by default
|
|
511
|
+
- S01 episode list detected
|
|
512
|
+
- S01E02 short sample downloaded and muxed
|
|
513
|
+
- Turkish subtitle search/download/mux verified with `--subtitle-lang tr`
|
|
514
|
+
- Subtitle release matching verified: BluRay video prefers BluRay subtitle over high-download WEBRip/NF subtitle
|
|
515
|
+
- Automatic subtitle sync path verified with `ffsubsync`
|
|
516
|
+
- `ffprobe` confirmed video/audio/subtitle streams
|
|
517
|
+
|
|
518
|
+
Sample `ffprobe` result from a short S01E02 test:
|
|
519
|
+
|
|
520
|
+
```text
|
|
521
|
+
Video: 640x360
|
|
522
|
+
Audio: AAC
|
|
523
|
+
Subtitle: WebVTT
|
|
524
|
+
Duration: ~5s
|
|
525
|
+
Container: MKV
|
|
526
|
+
```
|
|
527
|
+
|
|
528
|
+
## Development
|
|
529
|
+
|
|
530
|
+
Run tests:
|
|
531
|
+
|
|
532
|
+
```bash
|
|
533
|
+
cd streamgrabber
|
|
534
|
+
source .venv/bin/activate
|
|
535
|
+
pytest -q
|
|
536
|
+
```
|
|
537
|
+
|
|
538
|
+
Expected at the time of writing:
|
|
539
|
+
|
|
540
|
+
```text
|
|
541
|
+
39 passed
|
|
542
|
+
```
|
|
543
|
+
|
|
544
|
+
## Notes
|
|
545
|
+
|
|
546
|
+
- Signed `.m3u8` URLs can expire, so the tool fetches fresh episode stream URLs immediately before downloading.
|
|
547
|
+
- DRM-protected streams are not supported.
|
|
548
|
+
- Use this tool only for content you are authorized to access and download.
|