diff --git a/README.md b/README.md
index 563a136..5bcb5ff 100644
--- a/README.md
+++ b/README.md
@@ -2,10 +2,10 @@
-
-This repository provide a simple script designed to facilitate the downloading of films and series from a popular streaming community platform. The script allows users to download individual films, entire series, or specific episodes, providing a seamless experience for content consumers.
+This repository provide a simple script designed to downloading films and series from a variety of supported streaming platforms. [SITE](#website-status-)
## Join us 🌟
+
You can chat, help improve this repo, or just hang around for some fun in the **Git_StreamingCommunity** Discord [Server](https://discord.com/invite/8vV68UGRc7)
# Table of Contents
@@ -18,7 +18,7 @@ You can chat, help improve this repo, or just hang around for some fun in the **
* [Requirement](#requirement)
* [Usage](#usage-manual)
* [Win 7](https://github.com/Ghost6446/StreamingCommunity_api/wiki/Installation#win-7)
- * [Termux](https://github.com/Ghost6446/StreamingCommunity_api/wiki/Termux)
+ * [Termux](https://github.com/Ghost6446/StreamingCommunity_api/wiki/Termux)
* [Update](#update)
* [CONFIGURATION](#configuration)
* [DOCKER](#docker)
@@ -28,55 +28,70 @@ You can chat, help improve this repo, or just hang around for some fun in the **
# INSTALLATION
## Automatic Installation
-
+
+``
+
### Supported OSs for Automatic Installation 💿
+
- Supported ✔️
- Not tested ⏳
- Not supported ❌
-| OS | Automatic Installation Support |
-|:--------------------|:--------------------:|
-| Windows 10/11 | ✔️ |
-| Windows 7 | ❌ |
-| Debian Linux | ✔️ |
-| Arch Linux | ✔️ |
-| CentOS Stream 9 | ✔️ |
-| FreeBSD | ⏳ |
-| MacOS | ✔️ |
-| Termux | ❌ |
+| OS | Automatic Installation Support |
+| :-------------- | :----------------------------: |
+| Windows 10/11 | ✔️ |
+| Windows 7 | ❌ |
+| Debian Linux | ✔️ |
+| Arch Linux | ✔️ |
+| CentOS Stream 9 | ✔️ |
+| FreeBSD | ⏳ |
+| MacOS | ✔️ |
+| Termux | ❌ |
### Installation ⚙️
+
Run the following command inside the main directory:
+
#### On Windows:
+
```powershell
.\win_install.bat
```
#### On Linux/MacOS/BSD:
+
```bash
sudo chmod +x unix_install.sh && ./unix_install.sh
```
-
+``
+
### Usage 📚
Run the script with the following command:
+
#### On Windows:
+
```powershell
python .\run.py
```
+
or
+
```powershell
source .venv/bin/activate && python run.py && deactivate
```
#### On Linux/MacOS/BSD:
+
```bash
./run.py
```
## Manual Installation
-
+
+``
+
### Requirement 📋
Make sure you have the following prerequisites installed on your system:
@@ -93,7 +108,6 @@ Install the required Python libraries using the following command:
pip install -r requirements.txt
```
-
### Usage 📚
Run the script with the following command:
@@ -110,8 +124,7 @@ python run.py
python3 run.py
```
-
-## Update
+### Update
Keep your script up to date with the latest features by running:
@@ -127,91 +140,150 @@ python update_version.py
python3 update_version.py
```
-
## Configuration ⚙️
You can change some behaviors by tweaking the configuration file.
-
- DEFAULT
+The configuration file is divided into several main sections:
- * **debug**: Enables or disables debug mode.
- - **Default Value**: `false`
+### DEFAULT Settings
- * **root_path**: Path where the script will add movies and TV series folders (see [Path Examples](#Path-examples)).
- - **Default Value**: `Video`
+```json
+{
+ "root_path": "Video",
+ "map_episode_name": "%(tv_name)_S%(season)E%(episode)_%(episode_name)",
+ "special_chars_to_remove": "!@#$%^&*()[]{}<>|`~'\";:,?=+\u00e2\u20ac\u00a6",
+ "not_close": false,
+ "show_trending": false
+}
+```
- * **map_episode_name**: Mapping to choose the name of all episodes of TV Shows (see [Episode Name Usage](#Episode-name-usage)).
- - **Default Value**: `%(tv_name)_S%(season)E%(episode)_%(episode_name)`
+- `root_path`: Directory where all videos will be saved
- * **not_close**: When activated, prevents the script from closing after its initial execution, allowing it to restart automatically after completing the first run.
- - **Default Value**: `false`
+ #### Path examples:
-
-
- REQUESTS
+ * Windows: `C:\\MyLibrary\\Folder` or `\\\\MyServer\\MyLibrary` (if you want to use a network folder)
+ * Linux/MacOS: `Desktop/MyLibrary/Folder`
+ `
`
+- `map_episode_name`: Template for TV series episode filenames
- * **timeout**: The timeout value for requests.
- - **Default Value**: `15`
+ #### Episode name usage:
- * **verify_ssl**: Whether to verify SSL certificates.
- - **Default Value**: `false`
+ You can choose different vars:
- * **proxy**: To use proxy create a file with name list_proxy.txt and copy ip and port like "122.114.232.137:8080". They need to be http
-
+ * `%(tv_name)` : Is the name of TV Show
+ * `%(season)` : Is the number of the season
+ * `%(episode)` : Is the number of the episode
+ * `%(episode_name)` : Is the name of the episode
+ `
`
+- `special_chars_to_remove`: Special characters to be removed from filenames
+- `not_close`: If true, continues running after downloading
+- `show_trending`: Display trending content on startup
-
- M3U8_DOWNLOAD
+#### qBittorrent Configuration
- * **tqdm_use_large_bar**: Whether to use large progress bars during downloads (Downloading %desc: %percentage:.2f %bar %elapsed < %remaining %postfix
- - **Default Value**: `true`
- - **Example Value**: `false` with Proc: %percentage:.2f %remaining %postfix
+```json
+{
+ "config_qbit_tor": {
+ "host": "192.168.1.59",
+ "port": "8080",
+ "user": "admin",
+ "pass": "adminadmin"
+ }
+}
+```
- * **specific_list_audio**: A list of specific audio languages to download.
- - **Example Value**: `['ita']`
+To enable qBittorrent integration, follow the setup guide [here](https://github.com/lgallard/qBittorrent-Controller/wiki/How-to-enable-the-qBittorrent-Web-UI).
- * **specific_list_subtitles**: A list of specific subtitle languages to download.
- - **Example Value**: `['ara', 'baq', 'cat', 'chi', 'cze', 'dan', 'dut', 'eng', 'fil', 'fin', 'forced-ita', 'fre', 'ger', 'glg', 'gre', 'heb', 'hin', 'hun', 'ind', 'ita', 'jpn', 'kan', 'kor', 'mal', 'may', 'nob', 'nor', 'pol', 'por', 'rum', 'rus', 'spa', 'swe', 'tam', 'tel', 'tha', 'tur', 'ukr', 'vie']`
+### REQUESTS Settings
- * **cleanup_tmp_folder**: Upon final conversion, ensures the removal of all unformatted audio, video tracks, and subtitles from the temporary folder, thereby maintaining cleanliness and efficiency.
- - **Default Value**: `false`
+```json
+{
+ "timeout": 20,
+ "max_retry": 3
+}
+```
-
+- `timeout`: Maximum timeout (in seconds) for each request
+- `max_retry`: Number of retry attempts per segment during M3U8 index download
-
- M3U8_PARSER
+### BROWSER Settings
- * **force_resolution**: Forces the use of a specific resolution. `-1` means no forced resolution.
- - **Default Value**: `-1`
- - **Example Value**: `1080`
+```json
+{
+ "headless": false
+}
+```
- * **get_only_link**: Print hls m3u8 link and path file.
- - **Default Value**: `false`
+- `headless`: Controls whether to run browser in headless mode
-
+### M3U8_DOWNLOAD Settings
+
+```json
+{
+ "tqdm_delay": 0.01,
+ "tqdm_use_large_bar": true,
+ "default_video_workser": 12,
+ "default_audio_workser": 12,
+ "cleanup_tmp_folder": true
+}
+```
+
+- `tqdm_delay`: Delay between progress bar updates
+- `tqdm_use_large_bar`: Use detailed progress bar (recommended for desktop) set to false for mobile
+- `default_video_workser`: Number of threads for video download
+- `default_audio_workser`: Number of threads for audio download
+- `cleanup_tmp_folder`: Remove temporary .ts files after download
+
+#### Language Settings
+
+The following codes can be used for `specific_list_audio` and `specific_list_subtitles`:
+
+```
+ara - Arabic eng - English ita - Italian por - Portuguese
+baq - Basque fil - Filipino jpn - Japanese rum - Romanian
+cat - Catalan fin - Finnish kan - Kannada rus - Russian
+chi - Chinese fre - French kor - Korean spa - Spanish
+cze - Czech ger - German mal - Malayalam swe - Swedish
+dan - Danish glg - Galician may - Malay tam - Tamil
+dut - Dutch gre - Greek nob - Norw. Bokm tel - Telugu
+ heb - Hebrew nor - Norwegian tha - Thai
+forced-ita hin - Hindi pol - Polish tur - Turkish
+ hun - Hungarian ukr - Ukrainian
+ ind - Indonesian vie - Vietnamese
+```
> [!IMPORTANT]
-> If you're on **Windows** you'll need to use double back slash. On Linux/MacOS, one slash is fine.
+> Language code availability may vary by site. Some platforms might:
+>
+> - Use different language codes
+> - Support only a subset of these languages
+> - Offer additional languages not listed here
+>
+> Check the specific site's available options if downloads fail.
-#### Path examples:
+> [!TIP]
+> You can configure multiple languages by adding them to the lists:
+>
+> ```json
+> "specific_list_audio": ["ita", "eng", "spa"],
+> "specific_list_subtitles": ["ita", "eng", "spa"]
+> ```
-* Windows: `C:\\MyLibrary\\Folder` or `\\\\MyServer\\MyLibrary` (if you want to use a network folder).
-* Linux/MacOS: `Desktop/MyLibrary/Folder`
+### M3U8_PARSER Settings
-#### Episode name usage:
+```json
+{
+ "force_resolution": -1,
+ "get_only_link": false
+}
+```
-You can choose different vars:
+- `force_resolution`: Force specific resolution (-1 for best available, or specify 1080, 720, 360)
+- `get_only_link`: Return M3U8 playlist/index URL instead of downloading
-* `%(tv_name)` : Is the name of TV Show
-* `%(season)` : Is the number of the season
-* `%(episode)` : Is the number of the episode
-* `%(episode_name)` : Is the name of the episode
-
-> NOTE: You don't need to add .mp4 at the end
-
-
## Docker 🐳
You can run the script in a docker container, to build the image just run
@@ -245,14 +317,31 @@ make LOCAL_DIR=/path/to/download run-container
The `run-container` command mounts also the `config.json` file, so any change to the configuration file is reflected immediately without having to rebuild the image.
-
+### Website Status 🌐
+
+- Working ✅
+- Not Working ❌
+
+| Website | Status |
+| :----------------- | :----: |
+| 1337xx | ✅ |
+| Altadefinizione | ❌ |
+| AnimeUnity | ✅ |
+| BitSearch | ✅ |
+| CB01New | ✅ |
+| DDLStreamItaly | ✅ |
+| GuardaSerie | ✅ |
+| MostraGuarda | ✅ |
+| PirateBays | ✅ |
+| StreamingCommunity | ✅ |
+
## Tutorial 📖
[win](https://www.youtube.com/watch?v=mZGqK4wdN-k)
[linux](https://www.youtube.com/watch?v=0qUNXPE_mTg)
-
## To do 📝
+
- GUI
- Website api
- Add other site
diff --git a/Src/Api/altadefinizione/Player/supervideo.py b/Src/Api/altadefinizione/Player/supervideo.py
index ce53e26..f5eee67 100644
--- a/Src/Api/altadefinizione/Player/supervideo.py
+++ b/Src/Api/altadefinizione/Player/supervideo.py
@@ -28,7 +28,12 @@ class VideoSource:
- url (str): The URL of the video.
"""
self.url = url
- self.headers = {'user-agent': get_headers()}
+ self.headers = {
+ 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
+ 'accept-language': 'it-IT,it;q=0.9,en-US;q=0.8,en;q=0.7',
+ 'User-Agent': get_headers()
+ }
+ self.client = httpx.Client()
def setup(self, url: str) -> None:
"""
@@ -51,7 +56,7 @@ class VideoSource:
"""
try:
- response = httpx.get(url, headers=self.headers, follow_redirects=True, timeout=max_timeout)
+ response = self.client.get(url, headers=self.headers, follow_redirects=True, timeout=max_timeout)
response.raise_for_status()
return response.text
diff --git a/Src/Api/altadefinizione/site.py b/Src/Api/altadefinizione/site.py
index 4844dbd..153aa3c 100644
--- a/Src/Api/altadefinizione/site.py
+++ b/Src/Api/altadefinizione/site.py
@@ -16,7 +16,7 @@ from ..Template.Class.SearchType import MediaManager
# Variable
-from .costant import SITE_NAME
+from .costant import SITE_NAME, DOMAIN_NOW
media_search_manager = MediaManager()
table_show_manager = TVShowManager()
@@ -31,16 +31,21 @@ def title_search(title_search: str) -> int:
Returns:
int: The number of titles found.
"""
+ client = httpx.Client()
# Find new domain if prev dont work
max_timeout = config_manager.get_int("REQUESTS", "timeout")
- domain_to_use, _ = search_domain(SITE_NAME, f"https://{SITE_NAME}")
+ #domain_to_use, _ = search_domain(SITE_NAME, f"https://{SITE_NAME}")
# Send request to search for title
try:
- response = httpx.get(
- url=f"https://{SITE_NAME}.{domain_to_use}/?story={unidecode(title_search.replace(' ', '+'))}&do=search&subaction=search&titleonly=3",
- headers={'user-agent': get_headers()},
+ response = client.get(
+ url=f"https://{SITE_NAME}.{DOMAIN_NOW}/?story={unidecode(title_search.replace(' ', '+'))}&do=search&subaction=search&titleonly=3",
+ headers={
+ 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
+ 'accept-language': 'it-IT,it;q=0.9,en-US;q=0.8,en;q=0.7',
+ 'User-Agent': get_headers()
+ },
timeout=max_timeout
)
response.raise_for_status()
diff --git a/Src/Api/cb01new/__init__.py b/Src/Api/cb01new/__init__.py
index be0c4c4..a9afa9a 100644
--- a/Src/Api/cb01new/__init__.py
+++ b/Src/Api/cb01new/__init__.py
@@ -5,7 +5,7 @@ from Src.Util.console import console, msg
# Logic class
-from .site import title_search, run_get_select_title
+from .site import title_search, run_get_select_title, media_search_manager
from .film import download_film
@@ -17,15 +17,21 @@ _priority = 2
_engineDownload = "mp4"
-def search():
+def search(string_to_search: str = None, get_onylDatabase:bool = False):
"""
Main function of the application for film and series.
"""
- # Make request to site to get content that corrsisponde to that string
- string_to_search = msg.ask("\n[purple]Insert word to search in all site").strip()
+ if string_to_search is None:
+ string_to_search = msg.ask("\n[purple]Insert word to search in all site").strip()
+
+ # Search on database
len_database = title_search(string_to_search)
+ # Return list of elements
+ if get_onylDatabase:
+ return media_search_manager
+
if len_database > 0:
# Select title from list
diff --git a/Src/Lib/Downloader/HLS/downloader.py b/Src/Lib/Downloader/HLS/downloader.py
index 69d9d14..b3fc0fa 100644
--- a/Src/Lib/Downloader/HLS/downloader.py
+++ b/Src/Lib/Downloader/HLS/downloader.py
@@ -74,6 +74,7 @@ class PathManager:
# Create the base path by removing the '.mp4' extension from the output filename
self.base_path = str(output_filename).replace(".mp4", "")
+ logging.info(f"class 'PathManager'; set base path: {self.base_path}")
# Define the path for a temporary directory where segments will be stored
self.base_temp = os.path.join(self.base_path, "tmp")
@@ -106,6 +107,7 @@ class HttpClient:
Returns:
str: The response body as text if the request is successful, None otherwise.
"""
+ logging.info(f"class 'HttpClient'; make request: {url}")
try:
response = httpx.get(
url=url,
@@ -127,6 +129,7 @@ class HttpClient:
Returns:
bytes: The response content as bytes if the request is successful, None otherwise.
"""
+ logging.info(f"class 'HttpClient'; make request: {url}")
try:
response = httpx.get(
url=url,
@@ -168,6 +171,7 @@ class ContentExtractor:
"""
It checks for available audio languages and the specific audio tracks to download.
"""
+ logging.info(f"class 'ContentExtractor'; call _collect_audio()")
# Collect available audio tracks and their corresponding URIs and names
self.list_available_audio = self.obj_parse._audio.get_all_uris_and_names()
@@ -197,6 +201,7 @@ class ContentExtractor:
"""
It checks for available subtitle languages and the specific subtitles to download.
"""
+ logging.info(f"class 'ContentExtractor'; call _collect_subtitle()")
# Collect available subtitles and their corresponding URIs and names
self.list_available_subtitles = self.obj_parse._subtitle.get_all_uris_and_names()
@@ -226,6 +231,7 @@ class ContentExtractor:
"""
It identifies the best video quality and displays relevant information to the user.
"""
+ logging.info(f"class 'ContentExtractor'; call _collect_video()")
# Collect custom quality video if a specific resolution is set
if FILTER_CUSTOM_REOLUTION != -1:
@@ -297,6 +303,8 @@ class DownloadTracker:
Args:
available_video (str): The URL of the video to be downloaded.
"""
+ logging.info(f"class 'DownloadTracker'; call add_video() with parameter: {available_video}")
+
self.downloaded_video.append({
'type': 'video',
'url': available_video,
@@ -310,6 +318,8 @@ class DownloadTracker:
Args:
list_available_audio (list): A list of available audio track objects.
"""
+ logging.info(f"class 'DownloadTracker'; call add_audio() with parameter: {list_available_audio}")
+
for obj_audio in list_available_audio:
# Check if specific audio languages are set for download
@@ -337,6 +347,7 @@ class DownloadTracker:
Args:
list_available_subtitles (list): A list of available subtitle objects.
"""
+ logging.info(f"class 'DownloadTracker'; call add_subtitle() with parameter: {list_available_subtitles}")
for obj_subtitle in list_available_subtitles:
@@ -377,6 +388,7 @@ class ContentDownloader:
Args:
downloaded_video (list): A list containing information about the video to download.
"""
+ logging.info(f"class 'ContentDownloader'; call download_video() with parameter: {downloaded_video}")
# Check if the video file already exists
if not os.path.exists(downloaded_video[0].get('path')):
@@ -407,6 +419,8 @@ class ContentDownloader:
Args:
downloaded_audio (list): A list containing information about audio tracks to download.
"""
+ logging.info(f"class 'ContentDownloader'; call download_audio() with parameter: {downloaded_audio}")
+
for obj_audio in downloaded_audio:
folder_name = os.path.dirname(obj_audio.get('path'))
@@ -435,6 +449,8 @@ class ContentDownloader:
Args:
downloaded_subtitle (list): A list containing information about subtitles to download.
"""
+ logging.info(f"class 'ContentDownloader'; call download_subtitle() with parameter: {downloaded_subtitle}")
+
for obj_subtitle in downloaded_subtitle:
sub_language = obj_subtitle.get('language')
@@ -670,6 +686,10 @@ class HLS_Downloader:
is_playlist_url (bool): Flag indicating if the m3u8_playlist is a URL.
is_index_url (bool): Flag indicating if the m3u8_index is a URL.
"""
+ if ((m3u8_playlist == None or m3u8_playlist == "") and output_filename is None) or ((m3u8_index == None or m3u8_index == "") and output_filename is None):
+ logging.info(f"class 'HLS_Downloader'; call __init__(); no parameter")
+ sys.exit(0)
+
self.output_filename = self._generate_output_filename(output_filename, m3u8_playlist, m3u8_index)
self.path_manager = PathManager(self.output_filename)
self.download_tracker = DownloadTracker(self.path_manager)
@@ -684,6 +704,13 @@ class HLS_Downloader:
self.expected_real_time = None
self.instace_parserClass = M3U8_Parser()
+ self.request_m3u8_playlist = None
+ self.request_m3u8_index = None
+ if (m3u8_playlist == None or m3u8_playlist == ""):
+ self.request_m3u8_index = HttpClient().get(self.m3u8_index)
+ if (m3u8_index == None or m3u8_index == ""):
+ self.request_m3u8_playlist = HttpClient().get(self.m3u8_playlist)
+
def _generate_output_filename(self, output_filename, m3u8_playlist, m3u8_index):
"""
Generates a valid output filename based on provided parameters.
@@ -699,6 +726,7 @@ class HLS_Downloader:
root_path = config_manager.get('DEFAULT', 'root_path')
new_filename = None
new_folder = os.path.join(root_path, "undefined")
+ logging.info(f"class 'HLS_Downloader'; call _generate_output_filename(); destination folder: {new_folder}")
# Auto-generate output file name if not present
if (output_filename is None) or ("mp4" not in output_filename):
@@ -727,7 +755,8 @@ class HLS_Downloader:
# Parse to only ASCII for compatibility across platforms
new_filename = os.path.join(folder, base_name)
new_filename = unidecode(new_filename)
-
+
+ logging.info(f"class 'HLS_Downloader'; call _generate_output_filename(); return path: {new_filename}")
return new_filename
def start(self):
@@ -736,18 +765,17 @@ class HLS_Downloader:
"""
if os.path.exists(self.output_filename):
console.log("[red]Output file already exists.")
- return
+ return 400
self.path_manager.create_directories()
# Determine whether to process a playlist or index
if self.m3u8_playlist:
if self.m3u8_playlist is not None:
+ if self.request_m3u8_playlist != 404:
+ logging.info(f"class 'HLS_Downloader'; call start(); parse m3u8 data")
- # Parse data from url and check if is a master playlist
- test_raw_content = HttpClient().get(self.m3u8_playlist)
- if test_raw_content != 404:
- self.instace_parserClass.parse_data(uri=self.m3u8_playlist, raw_content=test_raw_content)
+ self.instace_parserClass.parse_data(uri=self.m3u8_playlist, raw_content=self.request_m3u8_playlist)
is_masterPlaylist = self.instace_parserClass.is_master_playlist
# Check if it's a real master playlist
@@ -766,18 +794,19 @@ class HLS_Downloader:
'url': self.m3u8_playlist
}
+ else:
+ console.log("[red]Error: URL passed to M3U8_Parser is an index playlist; expected a master playlist. Crucimorfo strikes again!")
else:
- console.log("[red]Error: URL passed to M3U8_Parser is an index playlist; expected a master playlist. Crucimorfo strikes again!")
+ console.log("[red]Error: m3u8_playlist failed request")
else:
console.log("[red]Error: m3u8_playlist is None")
elif self.m3u8_index:
if self.m3u8_index is not None:
+ if self.request_m3u8_index != 404:
+ logging.info(f"class 'HLS_Downloader'; call start(); parse m3u8 data")
- # Parse data from url and check if is a master playlist
- test_raw_content = HttpClient().get(self.m3u8_index)
- if test_raw_content != 404:
- self.instace_parserClass.parse_data(uri=self.m3u8_index, raw_content=test_raw_content)
+ self.instace_parserClass.parse_data(uri=self.m3u8_index, raw_content=self.request_m3u8_index)
is_masterPlaylist = self.instace_parserClass.is_master_playlist
# Check if it's a real index playlist
@@ -792,12 +821,13 @@ class HLS_Downloader:
'url': self.m3u8_index
}
+ else:
+ console.log("[red]Error: URL passed to M3U8_Parser is an master playlist; expected a index playlist. Crucimorfo strikes again!")
else:
- console.log("[red]Error: URL passed to M3U8_Parser is an master playlist; expected a index playlist. Crucimorfo strikes again!")
+ console.log("[red]Error: m3u8_index failed request")
else:
console.log("[red]Error: m3u8_index is None")
-
def _clean(self, out_path: str) -> None:
"""
Cleans up temporary files and folders after downloading and processing.
@@ -874,20 +904,20 @@ class HLS_Downloader:
else:
logging.info("Video file converted already exists.")
- def _process_playlist(self):
+ def _valida_playlist(self):
"""
- Processes the m3u8 playlist to download video, audio, and subtitles.
+ Validates the m3u8 playlist content, saves it to a temporary file, and collects playlist information.
"""
+ logging.info("class 'HLS_Downloader'; call _valida_playlist()")
# Retrieve the m3u8 playlist content
if self.is_playlist_url:
- response_text = HttpClient(headers=headers_index).get(self.m3u8_playlist)
-
- if response_text != 404:
- m3u8_playlist_text = response_text
+ if self.request_m3u8_playlist != 404:
+ m3u8_playlist_text = self.request_m3u8_playlist
m3u8_url_fixer.set_playlist(self.m3u8_playlist)
else:
+ logging.info(f"class 'HLS_Downloader'; call _process_playlist(); return 404")
return 404
else:
@@ -907,6 +937,12 @@ class HLS_Downloader:
else:
self.content_extractor.start("https://fake.com", m3u8_playlist_text)
+ def _process_playlist(self):
+ """
+ Processes the m3u8 playlist to download video, audio, and subtitles.
+ """
+ self._valida_playlist()
+
# Add downloaded elements to the tracker
self.download_tracker.add_video(self.content_extractor.m3u8_index)
self.download_tracker.add_audio(self.content_extractor.list_available_audio)
@@ -941,4 +977,3 @@ class HLS_Downloader:
# Clean up temporary files and directories
self._clean(self.content_joiner.converted_out_path)
-
\ No newline at end of file
diff --git a/Src/Lib/M3U8/parser.py b/Src/Lib/M3U8/parser.py
index 302e919..df7d89d 100644
--- a/Src/Lib/M3U8/parser.py
+++ b/Src/Lib/M3U8/parser.py
@@ -609,7 +609,6 @@ class M3U8_Parser:
"""
try:
-
for segment in m3u8_obj.segments:
# Parse key
diff --git a/Src/Upload/version.py b/Src/Upload/version.py
index 878b886..ee79c49 100644
--- a/Src/Upload/version.py
+++ b/Src/Upload/version.py
@@ -1,5 +1,5 @@
__title__ = 'StreamingCommunity'
-__version__ = 'v1.6.0'
+__version__ = 'v1.7.0'
__author__ = 'Lovi-0'
__description__ = 'A command-line program to download film'
__copyright__ = 'Copyright 2024'
diff --git a/Test/Download_HLS.py b/Test/Download_HLS.py
index 682f155..2447cc0 100644
--- a/Test/Download_HLS.py
+++ b/Test/Download_HLS.py
@@ -9,11 +9,15 @@ sys.path.append(src_path)
# Import
+from Src.Util.message import start_message
+from Src.Util.logger import Logger
from Src.Lib.Downloader import HLS_Downloader
# Test
-HLS_Downloader(
+start_message()
+logger = Logger()
+print("Return: ", HLS_Downloader(
output_filename="",
- m3u8_playlist=""
-).start()
\ No newline at end of file
+ m3u8_index=""
+).start())
\ No newline at end of file
diff --git a/Test/Download_MP4.py b/Test/Download_MP4.py
index 72eadbd..c94291c 100644
--- a/Test/Download_MP4.py
+++ b/Test/Download_MP4.py
@@ -9,11 +9,15 @@ sys.path.append(src_path)
# Import
+from Src.Util.message import start_message
+from Src.Util.logger import Logger
from Src.Lib.Downloader import MP4_downloader
# Test
-MP4_downloader(
+start_message()
+logger = Logger()
+print("Return: ", MP4_downloader(
"",
".\Video\undefined.mp4"
-)
+))
diff --git a/Test/Download_TOR.py b/Test/Download_TOR.py
index 6200140..6c2ccd6 100644
--- a/Test/Download_TOR.py
+++ b/Test/Download_TOR.py
@@ -9,10 +9,14 @@ sys.path.append(src_path)
# Import
+from Src.Util.message import start_message
+from Src.Util.logger import Logger
from Src.Lib.Downloader import TOR_downloader
# Test
+start_message()
+logger = Logger()
manager = TOR_downloader()
magnet_link = "magnet:?x"
diff --git a/run.py b/run.py
index 6e37621..ab8ed31 100644
--- a/run.py
+++ b/run.py
@@ -195,5 +195,5 @@ def main():
if __name__ == '__main__':
- initialize()
+ #initialize()
main()