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.
@@ -0,0 +1,6 @@
1
+ .venv/
2
+ .pytest_cache/
3
+ *.mkv
4
+ .DS_Store
5
+ __pycache__/
6
+ *.pyc
@@ -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.