StreamingCommunity 3.2.1__tar.gz → 3.2.7__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.
Potentially problematic release.
This version of StreamingCommunity might be problematic. Click here for more details.
- {streamingcommunity-3.2.1/StreamingCommunity.egg-info → streamingcommunity-3.2.7}/PKG-INFO +7 -9
- {streamingcommunity-3.2.1 → streamingcommunity-3.2.7}/README.md +5 -6
- {streamingcommunity-3.2.1 → streamingcommunity-3.2.7}/StreamingCommunity/Api/Player/Helper/Vixcloud/util.py +4 -0
- {streamingcommunity-3.2.1 → streamingcommunity-3.2.7}/StreamingCommunity/Api/Player/hdplayer.py +2 -2
- {streamingcommunity-3.2.1 → streamingcommunity-3.2.7}/StreamingCommunity/Api/Player/mixdrop.py +1 -1
- {streamingcommunity-3.2.1 → streamingcommunity-3.2.7}/StreamingCommunity/Api/Player/vixcloud.py +4 -5
- {streamingcommunity-3.2.1 → streamingcommunity-3.2.7}/StreamingCommunity/Api/Site/altadefinizione/film.py +2 -2
- {streamingcommunity-3.2.1 → streamingcommunity-3.2.7}/StreamingCommunity/Api/Site/altadefinizione/series.py +1 -1
- {streamingcommunity-3.2.1 → streamingcommunity-3.2.7}/StreamingCommunity/Api/Site/animeunity/serie.py +1 -1
- {streamingcommunity-3.2.1 → streamingcommunity-3.2.7}/StreamingCommunity/Api/Site/animeworld/film.py +1 -1
- {streamingcommunity-3.2.1 → streamingcommunity-3.2.7}/StreamingCommunity/Api/Site/animeworld/serie.py +1 -2
- {streamingcommunity-3.2.1 → streamingcommunity-3.2.7}/StreamingCommunity/Api/Site/cb01new/film.py +1 -1
- streamingcommunity-3.2.7/StreamingCommunity/Api/Site/crunchyroll/__init__.py +103 -0
- streamingcommunity-3.2.7/StreamingCommunity/Api/Site/crunchyroll/film.py +82 -0
- streamingcommunity-3.2.7/StreamingCommunity/Api/Site/crunchyroll/series.py +186 -0
- streamingcommunity-3.2.7/StreamingCommunity/Api/Site/crunchyroll/site.py +113 -0
- streamingcommunity-3.2.7/StreamingCommunity/Api/Site/crunchyroll/util/ScrapeSerie.py +238 -0
- streamingcommunity-3.2.7/StreamingCommunity/Api/Site/crunchyroll/util/get_license.py +227 -0
- {streamingcommunity-3.2.1 → streamingcommunity-3.2.7}/StreamingCommunity/Api/Site/guardaserie/series.py +1 -2
- {streamingcommunity-3.2.1 → streamingcommunity-3.2.7}/StreamingCommunity/Api/Site/guardaserie/site.py +1 -2
- {streamingcommunity-3.2.1 → streamingcommunity-3.2.7}/StreamingCommunity/Api/Site/guardaserie/util/ScrapeSerie.py +9 -8
- streamingcommunity-3.2.7/StreamingCommunity/Api/Site/mediasetinfinity/__init__.py +96 -0
- streamingcommunity-3.2.7/StreamingCommunity/Api/Site/mediasetinfinity/film.py +85 -0
- streamingcommunity-3.2.7/StreamingCommunity/Api/Site/mediasetinfinity/series.py +185 -0
- streamingcommunity-3.2.7/StreamingCommunity/Api/Site/mediasetinfinity/site.py +112 -0
- streamingcommunity-3.2.7/StreamingCommunity/Api/Site/mediasetinfinity/util/ScrapeSerie.py +259 -0
- streamingcommunity-3.2.7/StreamingCommunity/Api/Site/mediasetinfinity/util/fix_mpd.py +64 -0
- streamingcommunity-3.2.7/StreamingCommunity/Api/Site/mediasetinfinity/util/get_license.py +214 -0
- {streamingcommunity-3.2.1 → streamingcommunity-3.2.7}/StreamingCommunity/Api/Site/raiplay/film.py +2 -2
- {streamingcommunity-3.2.1 → streamingcommunity-3.2.7}/StreamingCommunity/Api/Site/raiplay/series.py +2 -1
- {streamingcommunity-3.2.1 → streamingcommunity-3.2.7}/StreamingCommunity/Api/Site/streamingcommunity/__init__.py +6 -17
- {streamingcommunity-3.2.1 → streamingcommunity-3.2.7}/StreamingCommunity/Api/Site/streamingcommunity/film.py +3 -3
- {streamingcommunity-3.2.1 → streamingcommunity-3.2.7}/StreamingCommunity/Api/Site/streamingcommunity/series.py +11 -11
- {streamingcommunity-3.2.1 → streamingcommunity-3.2.7}/StreamingCommunity/Api/Site/streamingcommunity/site.py +2 -4
- {streamingcommunity-3.2.1 → streamingcommunity-3.2.7}/StreamingCommunity/Api/Site/streamingcommunity/util/ScrapeSerie.py +3 -6
- {streamingcommunity-3.2.1 → streamingcommunity-3.2.7}/StreamingCommunity/Api/Site/streamingwatch/__init__.py +6 -14
- {streamingcommunity-3.2.1 → streamingcommunity-3.2.7}/StreamingCommunity/Api/Site/streamingwatch/film.py +3 -3
- {streamingcommunity-3.2.1 → streamingcommunity-3.2.7}/StreamingCommunity/Api/Site/streamingwatch/series.py +9 -9
- {streamingcommunity-3.2.1 → streamingcommunity-3.2.7}/StreamingCommunity/Api/Site/streamingwatch/site.py +5 -7
- {streamingcommunity-3.2.1 → streamingcommunity-3.2.7}/StreamingCommunity/Api/Site/streamingwatch/util/ScrapeSerie.py +2 -2
- streamingcommunity-3.2.7/StreamingCommunity/Lib/Downloader/DASH/cdm_helpher.py +131 -0
- streamingcommunity-3.2.7/StreamingCommunity/Lib/Downloader/DASH/decrypt.py +79 -0
- streamingcommunity-3.2.7/StreamingCommunity/Lib/Downloader/DASH/downloader.py +218 -0
- streamingcommunity-3.2.7/StreamingCommunity/Lib/Downloader/DASH/parser.py +249 -0
- streamingcommunity-3.2.7/StreamingCommunity/Lib/Downloader/DASH/segments.py +332 -0
- {streamingcommunity-3.2.1 → streamingcommunity-3.2.7}/StreamingCommunity/Lib/Downloader/HLS/downloader.py +10 -30
- streamingcommunity-3.2.7/StreamingCommunity/Lib/Downloader/HLS/segments.py +350 -0
- {streamingcommunity-3.2.1 → streamingcommunity-3.2.7}/StreamingCommunity/Lib/Downloader/MP4/downloader.py +0 -5
- {streamingcommunity-3.2.1 → streamingcommunity-3.2.7}/StreamingCommunity/Lib/FFmpeg/capture.py +3 -3
- {streamingcommunity-3.2.1 → streamingcommunity-3.2.7}/StreamingCommunity/Lib/FFmpeg/command.py +1 -1
- {streamingcommunity-3.2.1 → streamingcommunity-3.2.7}/StreamingCommunity/TelegramHelp/config.json +3 -7
- {streamingcommunity-3.2.1 → streamingcommunity-3.2.7}/StreamingCommunity/Upload/version.py +1 -1
- streamingcommunity-3.2.7/StreamingCommunity/Util/bento4_installer.py +191 -0
- {streamingcommunity-3.2.1 → streamingcommunity-3.2.7}/StreamingCommunity/Util/config_json.py +1 -1
- {streamingcommunity-3.2.1 → streamingcommunity-3.2.7}/StreamingCommunity/Util/headers.py +0 -3
- {streamingcommunity-3.2.1 → streamingcommunity-3.2.7}/StreamingCommunity/Util/os.py +36 -46
- {streamingcommunity-3.2.1 → streamingcommunity-3.2.7}/StreamingCommunity/__init__.py +2 -1
- {streamingcommunity-3.2.1 → streamingcommunity-3.2.7}/StreamingCommunity/run.py +11 -10
- {streamingcommunity-3.2.1 → streamingcommunity-3.2.7/StreamingCommunity.egg-info}/PKG-INFO +7 -9
- {streamingcommunity-3.2.1 → streamingcommunity-3.2.7}/StreamingCommunity.egg-info/SOURCES.txt +19 -4
- {streamingcommunity-3.2.1 → streamingcommunity-3.2.7}/StreamingCommunity.egg-info/requires.txt +1 -2
- {streamingcommunity-3.2.1 → streamingcommunity-3.2.7}/requirements.txt +1 -2
- streamingcommunity-3.2.1/StreamingCommunity/Api/Site/1337xx/__init__.py +0 -72
- streamingcommunity-3.2.1/StreamingCommunity/Api/Site/1337xx/site.py +0 -82
- streamingcommunity-3.2.1/StreamingCommunity/Api/Site/1337xx/title.py +0 -61
- streamingcommunity-3.2.1/StreamingCommunity/Lib/Downloader/HLS/segments.py +0 -467
- streamingcommunity-3.2.1/StreamingCommunity/Lib/Proxies/proxy.py +0 -72
- {streamingcommunity-3.2.1 → streamingcommunity-3.2.7}/LICENSE +0 -0
- {streamingcommunity-3.2.1 → streamingcommunity-3.2.7}/MANIFEST.in +0 -0
- {streamingcommunity-3.2.1 → streamingcommunity-3.2.7}/StreamingCommunity/Api/Player/Helper/Vixcloud/js_parser.py +0 -0
- {streamingcommunity-3.2.1 → streamingcommunity-3.2.7}/StreamingCommunity/Api/Player/ddl.py +0 -0
- {streamingcommunity-3.2.1 → streamingcommunity-3.2.7}/StreamingCommunity/Api/Player/maxstream.py +0 -0
- {streamingcommunity-3.2.1 → streamingcommunity-3.2.7}/StreamingCommunity/Api/Player/mediapolisvod.py +0 -0
- {streamingcommunity-3.2.1 → streamingcommunity-3.2.7}/StreamingCommunity/Api/Player/supervideo.py +0 -0
- {streamingcommunity-3.2.1 → streamingcommunity-3.2.7}/StreamingCommunity/Api/Player/sweetpixel.py +0 -0
- {streamingcommunity-3.2.1 → streamingcommunity-3.2.7}/StreamingCommunity/Api/Site/altadefinizione/__init__.py +0 -0
- {streamingcommunity-3.2.1 → streamingcommunity-3.2.7}/StreamingCommunity/Api/Site/altadefinizione/site.py +0 -0
- {streamingcommunity-3.2.1 → streamingcommunity-3.2.7}/StreamingCommunity/Api/Site/altadefinizione/util/ScrapeSerie.py +0 -0
- {streamingcommunity-3.2.1 → streamingcommunity-3.2.7}/StreamingCommunity/Api/Site/animeunity/__init__.py +0 -0
- {streamingcommunity-3.2.1 → streamingcommunity-3.2.7}/StreamingCommunity/Api/Site/animeunity/film.py +0 -0
- {streamingcommunity-3.2.1 → streamingcommunity-3.2.7}/StreamingCommunity/Api/Site/animeunity/site.py +0 -0
- {streamingcommunity-3.2.1 → streamingcommunity-3.2.7}/StreamingCommunity/Api/Site/animeunity/util/ScrapeSerie.py +0 -0
- {streamingcommunity-3.2.1 → streamingcommunity-3.2.7}/StreamingCommunity/Api/Site/animeworld/__init__.py +0 -0
- {streamingcommunity-3.2.1 → streamingcommunity-3.2.7}/StreamingCommunity/Api/Site/animeworld/site.py +0 -0
- {streamingcommunity-3.2.1 → streamingcommunity-3.2.7}/StreamingCommunity/Api/Site/animeworld/util/ScrapeSerie.py +0 -0
- {streamingcommunity-3.2.1 → streamingcommunity-3.2.7}/StreamingCommunity/Api/Site/cb01new/__init__.py +0 -0
- {streamingcommunity-3.2.1 → streamingcommunity-3.2.7}/StreamingCommunity/Api/Site/cb01new/site.py +0 -0
- {streamingcommunity-3.2.1 → streamingcommunity-3.2.7}/StreamingCommunity/Api/Site/guardaserie/__init__.py +0 -0
- {streamingcommunity-3.2.1 → streamingcommunity-3.2.7}/StreamingCommunity/Api/Site/raiplay/__init__.py +0 -0
- {streamingcommunity-3.2.1 → streamingcommunity-3.2.7}/StreamingCommunity/Api/Site/raiplay/site.py +0 -0
- {streamingcommunity-3.2.1 → streamingcommunity-3.2.7}/StreamingCommunity/Api/Site/raiplay/util/ScrapeSerie.py +0 -0
- {streamingcommunity-3.2.1 → streamingcommunity-3.2.7}/StreamingCommunity/Api/Template/Class/SearchType.py +0 -0
- {streamingcommunity-3.2.1 → streamingcommunity-3.2.7}/StreamingCommunity/Api/Template/Util/__init__.py +0 -0
- {streamingcommunity-3.2.1 → streamingcommunity-3.2.7}/StreamingCommunity/Api/Template/Util/manage_ep.py +0 -0
- {streamingcommunity-3.2.1 → streamingcommunity-3.2.7}/StreamingCommunity/Api/Template/__init__.py +0 -0
- {streamingcommunity-3.2.1 → streamingcommunity-3.2.7}/StreamingCommunity/Api/Template/config_loader.py +0 -0
- {streamingcommunity-3.2.1 → streamingcommunity-3.2.7}/StreamingCommunity/Api/Template/site.py +0 -0
- {streamingcommunity-3.2.1 → streamingcommunity-3.2.7}/StreamingCommunity/Lib/Downloader/TOR/downloader.py +0 -0
- {streamingcommunity-3.2.1 → streamingcommunity-3.2.7}/StreamingCommunity/Lib/Downloader/__init__.py +0 -0
- {streamingcommunity-3.2.1 → streamingcommunity-3.2.7}/StreamingCommunity/Lib/FFmpeg/__init__.py +0 -0
- {streamingcommunity-3.2.1 → streamingcommunity-3.2.7}/StreamingCommunity/Lib/FFmpeg/util.py +0 -0
- {streamingcommunity-3.2.1 → streamingcommunity-3.2.7}/StreamingCommunity/Lib/M3U8/__init__.py +0 -0
- {streamingcommunity-3.2.1 → streamingcommunity-3.2.7}/StreamingCommunity/Lib/M3U8/decryptor.py +0 -0
- {streamingcommunity-3.2.1 → streamingcommunity-3.2.7}/StreamingCommunity/Lib/M3U8/estimator.py +0 -0
- {streamingcommunity-3.2.1 → streamingcommunity-3.2.7}/StreamingCommunity/Lib/M3U8/parser.py +0 -0
- {streamingcommunity-3.2.1 → streamingcommunity-3.2.7}/StreamingCommunity/Lib/M3U8/url_fixer.py +0 -0
- {streamingcommunity-3.2.1 → streamingcommunity-3.2.7}/StreamingCommunity/Lib/TMBD/__init__.py +0 -0
- {streamingcommunity-3.2.1 → streamingcommunity-3.2.7}/StreamingCommunity/Lib/TMBD/obj_tmbd.py +0 -0
- {streamingcommunity-3.2.1 → streamingcommunity-3.2.7}/StreamingCommunity/Lib/TMBD/tmdb.py +0 -0
- {streamingcommunity-3.2.1 → streamingcommunity-3.2.7}/StreamingCommunity/TelegramHelp/__init__.py +0 -0
- {streamingcommunity-3.2.1 → streamingcommunity-3.2.7}/StreamingCommunity/TelegramHelp/telegram_bot.py +0 -0
- {streamingcommunity-3.2.1 → streamingcommunity-3.2.7}/StreamingCommunity/Upload/update.py +0 -0
- {streamingcommunity-3.2.1 → streamingcommunity-3.2.7}/StreamingCommunity/Util/color.py +0 -0
- {streamingcommunity-3.2.1 → streamingcommunity-3.2.7}/StreamingCommunity/Util/ffmpeg_installer.py +0 -0
- {streamingcommunity-3.2.1 → streamingcommunity-3.2.7}/StreamingCommunity/Util/logger.py +0 -0
- {streamingcommunity-3.2.1 → streamingcommunity-3.2.7}/StreamingCommunity/Util/message.py +0 -0
- {streamingcommunity-3.2.1 → streamingcommunity-3.2.7}/StreamingCommunity/Util/table.py +0 -0
- {streamingcommunity-3.2.1 → streamingcommunity-3.2.7}/StreamingCommunity/global_search.py +0 -0
- {streamingcommunity-3.2.1 → streamingcommunity-3.2.7}/StreamingCommunity.egg-info/dependency_links.txt +0 -0
- {streamingcommunity-3.2.1 → streamingcommunity-3.2.7}/StreamingCommunity.egg-info/entry_points.txt +0 -0
- {streamingcommunity-3.2.1 → streamingcommunity-3.2.7}/StreamingCommunity.egg-info/top_level.txt +0 -0
- {streamingcommunity-3.2.1 → streamingcommunity-3.2.7}/setup.cfg +0 -0
- {streamingcommunity-3.2.1 → streamingcommunity-3.2.7}/setup.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: StreamingCommunity
|
|
3
|
-
Version: 3.2.
|
|
3
|
+
Version: 3.2.7
|
|
4
4
|
Home-page: https://github.com/Lovi-0/StreamingCommunity
|
|
5
5
|
Author: Lovi-0
|
|
6
6
|
Project-URL: Bug Reports, https://github.com/Lovi-0/StreamingCommunity/issues
|
|
@@ -18,14 +18,13 @@ Requires-Dist: certifi
|
|
|
18
18
|
Requires-Dist: psutil
|
|
19
19
|
Requires-Dist: unidecode
|
|
20
20
|
Requires-Dist: curl_cffi
|
|
21
|
-
Requires-Dist: dnspython
|
|
22
21
|
Requires-Dist: jsbeautifier
|
|
23
22
|
Requires-Dist: pathvalidate
|
|
24
23
|
Requires-Dist: pycryptodomex
|
|
25
24
|
Requires-Dist: ua-generator
|
|
26
25
|
Requires-Dist: qbittorrent-api
|
|
27
26
|
Requires-Dist: pyTelegramBotAPI
|
|
28
|
-
Requires-Dist:
|
|
27
|
+
Requires-Dist: pywidevine
|
|
29
28
|
Dynamic: author
|
|
30
29
|
Dynamic: description
|
|
31
30
|
Dynamic: description-content-type
|
|
@@ -149,7 +148,7 @@ python run_streaming.py
|
|
|
149
148
|
Download HTTP Live Streaming (HLS) content from m3u8 URLs.
|
|
150
149
|
|
|
151
150
|
```python
|
|
152
|
-
from StreamingCommunity
|
|
151
|
+
from StreamingCommunity import HLS_Downloader
|
|
153
152
|
|
|
154
153
|
# Initialize with m3u8 URL and optional output path
|
|
155
154
|
downloader = HLS_Downloader(
|
|
@@ -170,7 +169,7 @@ See [HLS example](./Test/Download/HLS.py) for complete usage.
|
|
|
170
169
|
Direct MP4 file downloader with support for custom headers and referrer.
|
|
171
170
|
|
|
172
171
|
```python
|
|
173
|
-
from StreamingCommunity
|
|
172
|
+
from StreamingCommunity import MP4_downloader
|
|
174
173
|
|
|
175
174
|
# Basic usage
|
|
176
175
|
downloader = MP4_downloader(
|
|
@@ -202,7 +201,7 @@ See [MP4 example](./Test/Download/MP4.py) for complete usage.
|
|
|
202
201
|
Download content via torrent magnet links.
|
|
203
202
|
|
|
204
203
|
```python
|
|
205
|
-
from StreamingCommunity
|
|
204
|
+
from StreamingCommunity import TOR_downloader
|
|
206
205
|
|
|
207
206
|
# Initialize torrent client
|
|
208
207
|
client = TOR_downloader()
|
|
@@ -526,8 +525,6 @@ To enable qBittorrent integration, follow the setup guide [here](https://github.
|
|
|
526
525
|
"default_video_workser": 12,
|
|
527
526
|
"default_audio_workser": 12,
|
|
528
527
|
"segment_timeout": 8,
|
|
529
|
-
"download_audio": true,
|
|
530
|
-
"merge_audio": true,
|
|
531
528
|
"specific_list_audio": [
|
|
532
529
|
"ita"
|
|
533
530
|
],
|
|
@@ -552,7 +549,6 @@ To enable qBittorrent integration, follow the setup guide [here](https://github.
|
|
|
552
549
|
|
|
553
550
|
#### Audio Settings
|
|
554
551
|
- `download_audio`: Whether to download audio tracks
|
|
555
|
-
- `merge_audio`: Whether to merge audio with video
|
|
556
552
|
- `specific_list_audio`: List of audio languages to download
|
|
557
553
|
* Can be changed with `--specific_list_audio ita,eng`
|
|
558
554
|
|
|
@@ -839,3 +835,5 @@ API non ufficiale per accedere ai contenuti del sito italiano StreamingCommunity
|
|
|
839
835
|
# Disclaimer
|
|
840
836
|
|
|
841
837
|
This software is provided "as is", without warranty of any kind, express or implied, including but not limited to the warranties of merchantability, fitness for a particular purpose, and noninfringement. In no event shall the authors or copyright holders be liable for any claim, damages, or other liability, whether in an action of contract, tort, or otherwise, arising from, out of, or in connection with the software or the use or other dealings in the software.
|
|
838
|
+
|
|
839
|
+
> **Note:** DASH downloads require a valid L3 CDM (Content Decryption Module) to proceed. This project does not provide, include, or facilitate obtaining any CDM. Users are responsible for ensuring compliance with all applicable laws and requirements regarding DRM and decryption modules.
|
|
@@ -111,7 +111,7 @@ python run_streaming.py
|
|
|
111
111
|
Download HTTP Live Streaming (HLS) content from m3u8 URLs.
|
|
112
112
|
|
|
113
113
|
```python
|
|
114
|
-
from StreamingCommunity
|
|
114
|
+
from StreamingCommunity import HLS_Downloader
|
|
115
115
|
|
|
116
116
|
# Initialize with m3u8 URL and optional output path
|
|
117
117
|
downloader = HLS_Downloader(
|
|
@@ -132,7 +132,7 @@ See [HLS example](./Test/Download/HLS.py) for complete usage.
|
|
|
132
132
|
Direct MP4 file downloader with support for custom headers and referrer.
|
|
133
133
|
|
|
134
134
|
```python
|
|
135
|
-
from StreamingCommunity
|
|
135
|
+
from StreamingCommunity import MP4_downloader
|
|
136
136
|
|
|
137
137
|
# Basic usage
|
|
138
138
|
downloader = MP4_downloader(
|
|
@@ -164,7 +164,7 @@ See [MP4 example](./Test/Download/MP4.py) for complete usage.
|
|
|
164
164
|
Download content via torrent magnet links.
|
|
165
165
|
|
|
166
166
|
```python
|
|
167
|
-
from StreamingCommunity
|
|
167
|
+
from StreamingCommunity import TOR_downloader
|
|
168
168
|
|
|
169
169
|
# Initialize torrent client
|
|
170
170
|
client = TOR_downloader()
|
|
@@ -488,8 +488,6 @@ To enable qBittorrent integration, follow the setup guide [here](https://github.
|
|
|
488
488
|
"default_video_workser": 12,
|
|
489
489
|
"default_audio_workser": 12,
|
|
490
490
|
"segment_timeout": 8,
|
|
491
|
-
"download_audio": true,
|
|
492
|
-
"merge_audio": true,
|
|
493
491
|
"specific_list_audio": [
|
|
494
492
|
"ita"
|
|
495
493
|
],
|
|
@@ -514,7 +512,6 @@ To enable qBittorrent integration, follow the setup guide [here](https://github.
|
|
|
514
512
|
|
|
515
513
|
#### Audio Settings
|
|
516
514
|
- `download_audio`: Whether to download audio tracks
|
|
517
|
-
- `merge_audio`: Whether to merge audio with video
|
|
518
515
|
- `specific_list_audio`: List of audio languages to download
|
|
519
516
|
* Can be changed with `--specific_list_audio ita,eng`
|
|
520
517
|
|
|
@@ -801,3 +798,5 @@ API non ufficiale per accedere ai contenuti del sito italiano StreamingCommunity
|
|
|
801
798
|
# Disclaimer
|
|
802
799
|
|
|
803
800
|
This software is provided "as is", without warranty of any kind, express or implied, including but not limited to the warranties of merchantability, fitness for a particular purpose, and noninfringement. In no event shall the authors or copyright holders be liable for any claim, damages, or other liability, whether in an action of contract, tort, or otherwise, arising from, out of, or in connection with the software or the use or other dealings in the software.
|
|
801
|
+
|
|
802
|
+
> **Note:** DASH downloads require a valid L3 CDM (Content Decryption Module) to proceed. This project does not provide, include, or facilitate obtaining any CDM. Users are responsible for ensuring compliance with all applicable laws and requirements regarding DRM and decryption modules.
|
|
@@ -90,9 +90,13 @@ class SeasonManager:
|
|
|
90
90
|
Parameters:
|
|
91
91
|
- number (int): The season number (1-based index)
|
|
92
92
|
"""
|
|
93
|
+
if len(self.seasons) == 1:
|
|
94
|
+
return self.seasons[0]
|
|
95
|
+
|
|
93
96
|
for season in self.seasons:
|
|
94
97
|
if season.number == number:
|
|
95
98
|
return season
|
|
99
|
+
|
|
96
100
|
return None
|
|
97
101
|
|
|
98
102
|
def __len__(self) -> int:
|
{streamingcommunity-3.2.1 → streamingcommunity-3.2.7}/StreamingCommunity/Api/Player/hdplayer.py
RENAMED
|
@@ -18,8 +18,8 @@ REQUEST_VERIFY = config_manager.get_bool('REQUESTS', 'verify')
|
|
|
18
18
|
|
|
19
19
|
|
|
20
20
|
class VideoSource:
|
|
21
|
-
def __init__(self
|
|
22
|
-
self.client = httpx.Client(headers={'user-agent': get_userAgent()}, timeout=MAX_TIMEOUT,
|
|
21
|
+
def __init__(self):
|
|
22
|
+
self.client = httpx.Client(headers={'user-agent': get_userAgent()}, timeout=MAX_TIMEOUT, verify=REQUEST_VERIFY)
|
|
23
23
|
|
|
24
24
|
def extractLinkHdPlayer(self, response):
|
|
25
25
|
"""Extract iframe source from the page."""
|
{streamingcommunity-3.2.1 → streamingcommunity-3.2.7}/StreamingCommunity/Api/Player/vixcloud.py
RENAMED
|
@@ -25,7 +25,7 @@ console = Console()
|
|
|
25
25
|
|
|
26
26
|
|
|
27
27
|
class VideoSource:
|
|
28
|
-
def __init__(self, url: str, is_series: bool, media_id: int = None
|
|
28
|
+
def __init__(self, url: str, is_series: bool, media_id: int = None):
|
|
29
29
|
"""
|
|
30
30
|
Initialize video source for streaming site.
|
|
31
31
|
|
|
@@ -36,7 +36,6 @@ class VideoSource:
|
|
|
36
36
|
"""
|
|
37
37
|
self.headers = {'user-agent': get_userAgent()}
|
|
38
38
|
self.url = url
|
|
39
|
-
self.proxy = proxy
|
|
40
39
|
self.is_series = is_series
|
|
41
40
|
self.media_id = media_id
|
|
42
41
|
self.iframe_src = None
|
|
@@ -58,7 +57,7 @@ class VideoSource:
|
|
|
58
57
|
}
|
|
59
58
|
|
|
60
59
|
try:
|
|
61
|
-
response = httpx.get(f"{self.url}/iframe/{self.media_id}", headers=self.headers, params=params, timeout=MAX_TIMEOUT,
|
|
60
|
+
response = httpx.get(f"{self.url}/iframe/{self.media_id}", headers=self.headers, params=params, timeout=MAX_TIMEOUT, verify=REQUEST_VERIFY)
|
|
62
61
|
response.raise_for_status()
|
|
63
62
|
|
|
64
63
|
# Parse response with BeautifulSoup to get iframe source
|
|
@@ -123,12 +122,12 @@ class VideoSource:
|
|
|
123
122
|
logging.error(f"Error getting content: {e}")
|
|
124
123
|
raise
|
|
125
124
|
|
|
126
|
-
def get_playlist(self) -> str
|
|
125
|
+
def get_playlist(self) -> str:
|
|
127
126
|
"""
|
|
128
127
|
Generate authenticated playlist URL.
|
|
129
128
|
|
|
130
129
|
Returns:
|
|
131
|
-
str
|
|
130
|
+
str: Fully constructed playlist URL with authentication parameters, or None if content unavailable
|
|
132
131
|
"""
|
|
133
132
|
if not self.window_parameter:
|
|
134
133
|
return None
|
|
@@ -12,10 +12,9 @@ from rich.console import Console
|
|
|
12
12
|
|
|
13
13
|
# Internal utilities
|
|
14
14
|
from StreamingCommunity.Util.os import os_manager
|
|
15
|
-
from StreamingCommunity.Util.message import start_message
|
|
16
15
|
from StreamingCommunity.Util.headers import get_headers
|
|
16
|
+
from StreamingCommunity.Util.message import start_message
|
|
17
17
|
from StreamingCommunity.Util.config_json import config_manager
|
|
18
|
-
from StreamingCommunity.Lib.Downloader import HLS_Downloader
|
|
19
18
|
from StreamingCommunity.TelegramHelp.telegram_bot import get_bot_instance, TelegramSession
|
|
20
19
|
|
|
21
20
|
|
|
@@ -25,6 +24,7 @@ from StreamingCommunity.Api.Template.Class.SearchType import MediaItem
|
|
|
25
24
|
|
|
26
25
|
|
|
27
26
|
# Player
|
|
27
|
+
from StreamingCommunity import HLS_Downloader
|
|
28
28
|
from StreamingCommunity.Api.Player.supervideo import VideoSource
|
|
29
29
|
|
|
30
30
|
|
|
@@ -11,7 +11,6 @@ from rich.prompt import Prompt
|
|
|
11
11
|
|
|
12
12
|
# Internal utilities
|
|
13
13
|
from StreamingCommunity.Util.message import start_message
|
|
14
|
-
from StreamingCommunity.Lib.Downloader import HLS_Downloader
|
|
15
14
|
from StreamingCommunity.TelegramHelp.telegram_bot import get_bot_instance, TelegramSession
|
|
16
15
|
|
|
17
16
|
|
|
@@ -29,6 +28,7 @@ from StreamingCommunity.Api.Template.Class.SearchType import MediaItem
|
|
|
29
28
|
|
|
30
29
|
|
|
31
30
|
# Player
|
|
31
|
+
from StreamingCommunity import HLS_Downloader
|
|
32
32
|
from StreamingCommunity.Api.Player.supervideo import VideoSource
|
|
33
33
|
|
|
34
34
|
|
|
@@ -12,7 +12,6 @@ from rich.prompt import Prompt
|
|
|
12
12
|
# Internal utilities
|
|
13
13
|
from StreamingCommunity.Util.os import os_manager
|
|
14
14
|
from StreamingCommunity.Util.message import start_message
|
|
15
|
-
from StreamingCommunity.Lib.Downloader import MP4_downloader
|
|
16
15
|
from StreamingCommunity.TelegramHelp.telegram_bot import TelegramSession, get_bot_instance
|
|
17
16
|
|
|
18
17
|
|
|
@@ -24,6 +23,7 @@ from StreamingCommunity.Api.Template.Class.SearchType import MediaItem
|
|
|
24
23
|
|
|
25
24
|
|
|
26
25
|
# Player
|
|
26
|
+
from StreamingCommunity import MP4_downloader
|
|
27
27
|
from StreamingCommunity.Api.Player.vixcloud import VideoSourceAnime
|
|
28
28
|
|
|
29
29
|
|
{streamingcommunity-3.2.1 → streamingcommunity-3.2.7}/StreamingCommunity/Api/Site/animeworld/film.py
RENAMED
|
@@ -9,7 +9,6 @@ from rich.console import Console
|
|
|
9
9
|
# Internal utilities
|
|
10
10
|
from StreamingCommunity.Util.os import os_manager
|
|
11
11
|
from StreamingCommunity.Util.message import start_message
|
|
12
|
-
from StreamingCommunity.Lib.Downloader import MP4_downloader
|
|
13
12
|
|
|
14
13
|
|
|
15
14
|
# Logic class
|
|
@@ -19,6 +18,7 @@ from StreamingCommunity.Api.Template.Class.SearchType import MediaItem
|
|
|
19
18
|
|
|
20
19
|
|
|
21
20
|
# Player
|
|
21
|
+
from StreamingCommunity import MP4_downloader
|
|
22
22
|
from StreamingCommunity.Api.Player.sweetpixel import VideoSource
|
|
23
23
|
|
|
24
24
|
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
# 11.03.24
|
|
2
2
|
|
|
3
3
|
import os
|
|
4
|
-
import logging
|
|
5
4
|
from typing import Tuple
|
|
6
5
|
|
|
7
6
|
|
|
@@ -13,7 +12,6 @@ from rich.prompt import Prompt
|
|
|
13
12
|
# Internal utilities
|
|
14
13
|
from StreamingCommunity.Util.os import os_manager
|
|
15
14
|
from StreamingCommunity.Util.message import start_message
|
|
16
|
-
from StreamingCommunity.Lib.Downloader import MP4_downloader
|
|
17
15
|
|
|
18
16
|
|
|
19
17
|
# Logic class
|
|
@@ -24,6 +22,7 @@ from StreamingCommunity.Api.Template.Class.SearchType import MediaItem
|
|
|
24
22
|
|
|
25
23
|
|
|
26
24
|
# Player
|
|
25
|
+
from StreamingCommunity import MP4_downloader
|
|
27
26
|
from StreamingCommunity.Api.Player.sweetpixel import VideoSource
|
|
28
27
|
|
|
29
28
|
|
{streamingcommunity-3.2.1 → streamingcommunity-3.2.7}/StreamingCommunity/Api/Site/cb01new/film.py
RENAMED
|
@@ -10,7 +10,6 @@ from rich.console import Console
|
|
|
10
10
|
# Internal utilities
|
|
11
11
|
from StreamingCommunity.Util.os import os_manager
|
|
12
12
|
from StreamingCommunity.Util.message import start_message
|
|
13
|
-
from StreamingCommunity.Lib.Downloader import HLS_Downloader
|
|
14
13
|
|
|
15
14
|
|
|
16
15
|
# Logic class
|
|
@@ -19,6 +18,7 @@ from StreamingCommunity.Api.Template.Class.SearchType import MediaItem
|
|
|
19
18
|
|
|
20
19
|
|
|
21
20
|
# Player
|
|
21
|
+
from StreamingCommunity import HLS_Downloader
|
|
22
22
|
from StreamingCommunity.Api.Player.maxstream import VideoSource
|
|
23
23
|
|
|
24
24
|
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
# 16.03.25
|
|
2
|
+
|
|
3
|
+
import sys
|
|
4
|
+
import subprocess
|
|
5
|
+
from urllib.parse import quote_plus
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
# External library
|
|
9
|
+
from rich.console import Console
|
|
10
|
+
from rich.prompt import Prompt
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
# Internal utilities
|
|
14
|
+
from StreamingCommunity.Api.Template import get_select_title
|
|
15
|
+
from StreamingCommunity.Api.Template.config_loader import site_constant
|
|
16
|
+
from StreamingCommunity.Api.Template.Class.SearchType import MediaItem
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
# Logic class
|
|
20
|
+
from .site import title_search, table_show_manager, media_search_manager
|
|
21
|
+
from .film import download_film
|
|
22
|
+
from .series import download_series
|
|
23
|
+
|
|
24
|
+
# Variable
|
|
25
|
+
indice = 8
|
|
26
|
+
_useFor = "Anime"
|
|
27
|
+
_priority = 0
|
|
28
|
+
_engineDownload = "hls"
|
|
29
|
+
_deprecate = False
|
|
30
|
+
|
|
31
|
+
msg = Prompt()
|
|
32
|
+
console = Console()
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def get_user_input(string_to_search: str = None):
|
|
36
|
+
"""
|
|
37
|
+
Asks the user to input a search term.
|
|
38
|
+
Handles both Telegram bot input and direct input.
|
|
39
|
+
"""
|
|
40
|
+
if string_to_search is None:
|
|
41
|
+
string_to_search = msg.ask(f"\n[purple]Insert a word to search in [green]{site_constant.SITE_NAME}").strip()
|
|
42
|
+
|
|
43
|
+
return string_to_search
|
|
44
|
+
|
|
45
|
+
def process_search_result(select_title, selections=None):
|
|
46
|
+
"""
|
|
47
|
+
Handles the search result and initiates the download for either a film or series.
|
|
48
|
+
|
|
49
|
+
Parameters:
|
|
50
|
+
select_title (MediaItem): The selected media item
|
|
51
|
+
selections (dict, optional): Dictionary containing selection inputs that bypass manual input
|
|
52
|
+
{'season': season_selection, 'episode': episode_selection}
|
|
53
|
+
"""
|
|
54
|
+
if select_title.type == 'tv':
|
|
55
|
+
season_selection = None
|
|
56
|
+
episode_selection = None
|
|
57
|
+
|
|
58
|
+
if selections:
|
|
59
|
+
season_selection = selections.get('season')
|
|
60
|
+
episode_selection = selections.get('episode')
|
|
61
|
+
|
|
62
|
+
download_series(select_title, season_selection, episode_selection)
|
|
63
|
+
|
|
64
|
+
else:
|
|
65
|
+
download_film(select_title)
|
|
66
|
+
|
|
67
|
+
# search("Game of Thrones", selections={"season": "1", "episode": "1-3"})
|
|
68
|
+
def search(string_to_search: str = None, get_onlyDatabase: bool = False, direct_item: dict = None, selections: dict = None):
|
|
69
|
+
"""
|
|
70
|
+
Main function of the application for search.
|
|
71
|
+
|
|
72
|
+
Parameters:
|
|
73
|
+
string_to_search (str, optional): String to search for
|
|
74
|
+
get_onylDatabase (bool, optional): If True, return only the database object
|
|
75
|
+
direct_item (dict, optional): Direct item to process (bypass search)
|
|
76
|
+
selections (dict, optional): Dictionary containing selection inputs that bypass manual input
|
|
77
|
+
{'season': season_selection, 'episode': episode_selection}
|
|
78
|
+
"""
|
|
79
|
+
if direct_item:
|
|
80
|
+
select_title = MediaItem(**direct_item)
|
|
81
|
+
process_search_result(select_title, selections)
|
|
82
|
+
return
|
|
83
|
+
|
|
84
|
+
# Get the user input for the search term
|
|
85
|
+
string_to_search = get_user_input(string_to_search)
|
|
86
|
+
|
|
87
|
+
# Perform the database search
|
|
88
|
+
len_database = title_search(quote_plus(string_to_search))
|
|
89
|
+
|
|
90
|
+
# If only the database is needed, return the manager
|
|
91
|
+
if get_onlyDatabase:
|
|
92
|
+
return media_search_manager
|
|
93
|
+
|
|
94
|
+
if len_database > 0:
|
|
95
|
+
select_title = get_select_title(table_show_manager, media_search_manager, len_database)
|
|
96
|
+
process_search_result(select_title, selections)
|
|
97
|
+
|
|
98
|
+
else:
|
|
99
|
+
console.print(f"\n[red]Nothing matching was found for[white]: [purple]{string_to_search}")
|
|
100
|
+
|
|
101
|
+
# If no results are found, ask again
|
|
102
|
+
string_to_search = get_user_input()
|
|
103
|
+
search(string_to_search, get_onlyDatabase, None, selections)
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# 16.03.25
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
from urllib.parse import urlparse, parse_qs
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
# External library
|
|
8
|
+
from rich.console import Console
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
# Internal utilities
|
|
12
|
+
from StreamingCommunity.Util.message import start_message
|
|
13
|
+
from StreamingCommunity.Util.config_json import config_manager
|
|
14
|
+
from StreamingCommunity.Util.os import os_manager, get_wvd_path
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
# Logic class
|
|
18
|
+
from StreamingCommunity.Api.Template.config_loader import site_constant
|
|
19
|
+
from StreamingCommunity.Api.Template.Class.SearchType import MediaItem
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
# Player
|
|
23
|
+
from StreamingCommunity import DASH_Downloader
|
|
24
|
+
from .util.get_license import get_playback_session, get_auth_token, generate_device_id
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
# Variable
|
|
28
|
+
console = Console()
|
|
29
|
+
max_timeout = config_manager.get_int("REQUESTS", "timeout")
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def download_film(select_title: MediaItem) -> str:
|
|
33
|
+
"""
|
|
34
|
+
Downloads a film using the provided film ID, title name, and domain.
|
|
35
|
+
|
|
36
|
+
Parameters:
|
|
37
|
+
- select_title (MediaItem): The selected media item.
|
|
38
|
+
|
|
39
|
+
Return:
|
|
40
|
+
- str: output path if successful, otherwise None
|
|
41
|
+
"""
|
|
42
|
+
start_message()
|
|
43
|
+
console.print(f"[bold yellow]Download:[/bold yellow] [red]{site_constant.SITE_NAME}[/red] → [cyan]{select_title.name}[/cyan] \n")
|
|
44
|
+
|
|
45
|
+
# Define filename and path for the downloaded video
|
|
46
|
+
mp4_name = os_manager.get_sanitize_file(select_title.name) + ".mp4"
|
|
47
|
+
mp4_path = os.path.join(site_constant.MOVIE_FOLDER, mp4_name.replace(".mp4", ""))
|
|
48
|
+
|
|
49
|
+
# Generate mpd and license URLs
|
|
50
|
+
url_id = select_title.get('url').split('/')[-1]
|
|
51
|
+
device_id = generate_device_id()
|
|
52
|
+
mpd_url, mpd_headers = get_playback_session(get_auth_token(device_id), device_id, url_id)
|
|
53
|
+
parsed_url = urlparse(mpd_url)
|
|
54
|
+
query_params = parse_qs(parsed_url.query)
|
|
55
|
+
|
|
56
|
+
# Download the episode
|
|
57
|
+
r_proc = DASH_Downloader(
|
|
58
|
+
cdm_device=get_wvd_path(),
|
|
59
|
+
license_url='https://www.crunchyroll.com/license/v1/license/widevine',
|
|
60
|
+
mpd_url=mpd_url,
|
|
61
|
+
output_path=os.path.join(mp4_path, mp4_name),
|
|
62
|
+
)
|
|
63
|
+
r_proc.parse_manifest(custom_headers=mpd_headers)
|
|
64
|
+
|
|
65
|
+
# Create headers for license request
|
|
66
|
+
license_headers = mpd_headers.copy()
|
|
67
|
+
license_headers.update({
|
|
68
|
+
"x-cr-content-id": url_id,
|
|
69
|
+
"x-cr-video-token": query_params['playbackGuid'][0],
|
|
70
|
+
})
|
|
71
|
+
|
|
72
|
+
if r_proc.download_and_decrypt(custom_headers=license_headers):
|
|
73
|
+
r_proc.finalize_output()
|
|
74
|
+
|
|
75
|
+
# Get final output path and status
|
|
76
|
+
status = r_proc.get_status()
|
|
77
|
+
|
|
78
|
+
if status['error'] is not None and status['path']:
|
|
79
|
+
try: os.remove(status['path'])
|
|
80
|
+
except Exception: pass
|
|
81
|
+
|
|
82
|
+
return status['path'], status['stopped']
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
# 16.03.25
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
from typing import Tuple
|
|
5
|
+
from urllib.parse import urlparse, parse_qs
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
# External library
|
|
9
|
+
from rich.console import Console
|
|
10
|
+
from rich.prompt import Prompt
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
# Internal utilities
|
|
14
|
+
from StreamingCommunity.Util.message import start_message
|
|
15
|
+
from StreamingCommunity.Util.os import os_manager, get_wvd_path
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
# Logic class
|
|
19
|
+
from .util.ScrapeSerie import GetSerieInfo, delete_stream_episode
|
|
20
|
+
from StreamingCommunity.Api.Template.Util import (
|
|
21
|
+
manage_selection,
|
|
22
|
+
map_episode_title,
|
|
23
|
+
validate_selection,
|
|
24
|
+
validate_episode_selection,
|
|
25
|
+
display_episodes_list
|
|
26
|
+
)
|
|
27
|
+
from StreamingCommunity.Api.Template.config_loader import site_constant
|
|
28
|
+
from StreamingCommunity.Api.Template.Class.SearchType import MediaItem
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
# Player
|
|
32
|
+
from StreamingCommunity import DASH_Downloader
|
|
33
|
+
from .util.get_license import get_playback_session, get_auth_token, generate_device_id
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
# Variable
|
|
37
|
+
msg = Prompt()
|
|
38
|
+
console = Console()
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def download_video(index_season_selected: int, index_episode_selected: int, scrape_serie: GetSerieInfo) -> Tuple[str,bool]:
|
|
42
|
+
"""
|
|
43
|
+
Downloads a specific episode from a specified season.
|
|
44
|
+
|
|
45
|
+
Parameters:
|
|
46
|
+
- index_season_selected (int): Season number
|
|
47
|
+
- index_episode_selected (int): Episode index
|
|
48
|
+
- scrape_serie (GetSerieInfo): Scraper object with series information
|
|
49
|
+
|
|
50
|
+
Returns:
|
|
51
|
+
- str: Path to downloaded file
|
|
52
|
+
- bool: Whether download was stopped
|
|
53
|
+
"""
|
|
54
|
+
start_message()
|
|
55
|
+
|
|
56
|
+
# Get episode information
|
|
57
|
+
obj_episode = scrape_serie.selectEpisode(index_season_selected, index_episode_selected-1)
|
|
58
|
+
console.print(f"[bold yellow]Download:[/bold yellow] [red]{site_constant.SITE_NAME}[/red] → [bold magenta]{obj_episode.get('name')}[/bold magenta] ([cyan]S{index_season_selected}E{index_episode_selected}[/cyan]) \n")
|
|
59
|
+
|
|
60
|
+
# Define filename and path for the downloaded video
|
|
61
|
+
mp4_name = f"{map_episode_title(scrape_serie.series_name, index_season_selected, index_episode_selected, obj_episode.get('name'))}.mp4"
|
|
62
|
+
mp4_path = os_manager.get_sanitize_path(os.path.join(site_constant.SERIES_FOLDER, scrape_serie.series_name, f"S{index_season_selected}"))
|
|
63
|
+
|
|
64
|
+
# Generate mpd and license URLs
|
|
65
|
+
url_id = obj_episode.get('url').split('/')[-1]
|
|
66
|
+
device_id = generate_device_id()
|
|
67
|
+
token_mpd = get_auth_token(device_id)
|
|
68
|
+
|
|
69
|
+
mpd_url, mpd_headers = get_playback_session(token_mpd, device_id, url_id)
|
|
70
|
+
parsed_url = urlparse(mpd_url)
|
|
71
|
+
query_params = parse_qs(parsed_url.query)
|
|
72
|
+
|
|
73
|
+
# Download the episode
|
|
74
|
+
r_proc = DASH_Downloader(
|
|
75
|
+
cdm_device=get_wvd_path(),
|
|
76
|
+
license_url='https://www.crunchyroll.com/license/v1/license/widevine',
|
|
77
|
+
mpd_url=mpd_url,
|
|
78
|
+
output_path=os.path.join(mp4_path, mp4_name),
|
|
79
|
+
)
|
|
80
|
+
r_proc.parse_manifest(custom_headers=mpd_headers)
|
|
81
|
+
|
|
82
|
+
# Create headers for license request
|
|
83
|
+
license_headers = mpd_headers.copy()
|
|
84
|
+
license_headers.update({
|
|
85
|
+
"x-cr-content-id": url_id,
|
|
86
|
+
"x-cr-video-token": query_params['playbackGuid'][0],
|
|
87
|
+
})
|
|
88
|
+
|
|
89
|
+
if r_proc.download_and_decrypt(custom_headers=license_headers):
|
|
90
|
+
r_proc.finalize_output()
|
|
91
|
+
|
|
92
|
+
# Get final output path and status
|
|
93
|
+
status = r_proc.get_status()
|
|
94
|
+
|
|
95
|
+
if status['error'] is not None and status['path']:
|
|
96
|
+
try: os.remove(status['path'])
|
|
97
|
+
except Exception: pass
|
|
98
|
+
|
|
99
|
+
# Delete episode stream
|
|
100
|
+
delete_stream_episode(url_id, query_params['playbackGuid'][0], mpd_headers)
|
|
101
|
+
|
|
102
|
+
return status['path'], status['stopped']
|
|
103
|
+
|
|
104
|
+
def download_episode(index_season_selected: int, scrape_serie: GetSerieInfo, download_all: bool = False, episode_selection: str = None) -> None:
|
|
105
|
+
"""
|
|
106
|
+
Handle downloading episodes for a specific season.
|
|
107
|
+
|
|
108
|
+
Parameters:
|
|
109
|
+
- index_season_selected (int): Season number
|
|
110
|
+
- scrape_serie (GetSerieInfo): Scraper object with series information
|
|
111
|
+
- download_all (bool): Whether to download all episodes
|
|
112
|
+
- episode_selection (str, optional): Pre-defined episode selection that bypasses manual input
|
|
113
|
+
"""
|
|
114
|
+
# Get episodes for the selected season
|
|
115
|
+
episodes = scrape_serie.getEpisodeSeasons(index_season_selected)
|
|
116
|
+
episodes_count = len(episodes)
|
|
117
|
+
|
|
118
|
+
if download_all:
|
|
119
|
+
for i_episode in range(1, episodes_count + 1):
|
|
120
|
+
path, stopped = download_video(index_season_selected, i_episode, scrape_serie)
|
|
121
|
+
|
|
122
|
+
if stopped:
|
|
123
|
+
break
|
|
124
|
+
|
|
125
|
+
console.print(f"\n[red]End downloaded [yellow]season: [red]{index_season_selected}.")
|
|
126
|
+
|
|
127
|
+
else:
|
|
128
|
+
if episode_selection is not None:
|
|
129
|
+
last_command = episode_selection
|
|
130
|
+
console.print(f"\n[cyan]Using provided episode selection: [yellow]{episode_selection}")
|
|
131
|
+
|
|
132
|
+
else:
|
|
133
|
+
last_command = display_episodes_list(episodes)
|
|
134
|
+
|
|
135
|
+
# Prompt user for episode selection
|
|
136
|
+
list_episode_select = manage_selection(last_command, episodes_count)
|
|
137
|
+
list_episode_select = validate_episode_selection(list_episode_select, episodes_count)
|
|
138
|
+
|
|
139
|
+
# Download selected episodes if not stopped
|
|
140
|
+
for i_episode in list_episode_select:
|
|
141
|
+
path, stopped = download_video(index_season_selected, i_episode, scrape_serie)
|
|
142
|
+
|
|
143
|
+
if stopped:
|
|
144
|
+
break
|
|
145
|
+
|
|
146
|
+
def download_series(select_season: MediaItem, season_selection: str = None, episode_selection: str = None) -> None:
|
|
147
|
+
"""
|
|
148
|
+
Handle downloading a complete series.
|
|
149
|
+
|
|
150
|
+
Parameters:
|
|
151
|
+
- select_season (MediaItem): Series metadata from search
|
|
152
|
+
- season_selection (str, optional): Pre-defined season selection that bypasses manual input
|
|
153
|
+
- episode_selection (str, optional): Pre-defined episode selection that bypasses manual input
|
|
154
|
+
"""
|
|
155
|
+
scrape_serie = GetSerieInfo(select_season.url.split("/")[-1])
|
|
156
|
+
|
|
157
|
+
# Get total number of seasons
|
|
158
|
+
seasons_count = scrape_serie.getNumberSeason()
|
|
159
|
+
|
|
160
|
+
# Prompt user for season selection and download episodes
|
|
161
|
+
console.print(f"\n[green]Seasons found: [red]{seasons_count}")
|
|
162
|
+
|
|
163
|
+
# If season_selection is provided, use it instead of asking for input
|
|
164
|
+
if season_selection is None:
|
|
165
|
+
index_season_selected = msg.ask(
|
|
166
|
+
"\n[cyan]Insert season number [yellow](e.g., 1), [red]* [cyan]to download all seasons, "
|
|
167
|
+
"[yellow](e.g., 1-2) [cyan]for a range of seasons, or [yellow](e.g., 3-*) [cyan]to download from a specific season to the end"
|
|
168
|
+
)
|
|
169
|
+
|
|
170
|
+
else:
|
|
171
|
+
index_season_selected = season_selection
|
|
172
|
+
console.print(f"\n[cyan]Using provided season selection: [yellow]{season_selection}")
|
|
173
|
+
|
|
174
|
+
# Validate the selection
|
|
175
|
+
list_season_select = manage_selection(index_season_selected, seasons_count)
|
|
176
|
+
list_season_select = validate_selection(list_season_select, seasons_count)
|
|
177
|
+
|
|
178
|
+
# Loop through the selected seasons and download episodes
|
|
179
|
+
for i_season in list_season_select:
|
|
180
|
+
if len(list_season_select) > 1 or index_season_selected == "*":
|
|
181
|
+
# Download all episodes if multiple seasons are selected or if '*' is used
|
|
182
|
+
download_episode(i_season, scrape_serie, download_all=True)
|
|
183
|
+
|
|
184
|
+
else:
|
|
185
|
+
# Otherwise, let the user select specific episodes for the single season
|
|
186
|
+
download_episode(i_season, scrape_serie, download_all=False, episode_selection=episode_selection)
|