StreamingCommunity 3.2.5__py3-none-any.whl → 3.2.7__py3-none-any.whl

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.

Files changed (36) hide show
  1. StreamingCommunity/Api/Site/altadefinizione/film.py +2 -2
  2. StreamingCommunity/Api/Site/altadefinizione/series.py +1 -1
  3. StreamingCommunity/Api/Site/animeunity/serie.py +1 -1
  4. StreamingCommunity/Api/Site/animeworld/film.py +1 -1
  5. StreamingCommunity/Api/Site/animeworld/serie.py +1 -2
  6. StreamingCommunity/Api/Site/cb01new/film.py +1 -1
  7. StreamingCommunity/Api/Site/crunchyroll/film.py +3 -4
  8. StreamingCommunity/Api/Site/crunchyroll/series.py +10 -6
  9. StreamingCommunity/Api/Site/crunchyroll/util/ScrapeSerie.py +20 -0
  10. StreamingCommunity/Api/Site/guardaserie/series.py +1 -2
  11. StreamingCommunity/Api/Site/mediasetinfinity/film.py +12 -3
  12. StreamingCommunity/Api/Site/mediasetinfinity/series.py +14 -6
  13. StreamingCommunity/Api/Site/mediasetinfinity/util/get_license.py +1 -4
  14. StreamingCommunity/Api/Site/raiplay/film.py +2 -2
  15. StreamingCommunity/Api/Site/raiplay/series.py +2 -1
  16. StreamingCommunity/Api/Site/streamingcommunity/film.py +1 -1
  17. StreamingCommunity/Api/Site/streamingcommunity/series.py +2 -2
  18. StreamingCommunity/Api/Site/streamingwatch/film.py +1 -1
  19. StreamingCommunity/Lib/Downloader/DASH/downloader.py +13 -15
  20. StreamingCommunity/Lib/Downloader/DASH/parser.py +1 -1
  21. StreamingCommunity/Lib/Downloader/HLS/downloader.py +9 -16
  22. StreamingCommunity/Lib/Downloader/HLS/segments.py +143 -260
  23. StreamingCommunity/TelegramHelp/config.json +0 -2
  24. StreamingCommunity/Upload/version.py +1 -1
  25. StreamingCommunity/Util/bento4_installer.py +191 -0
  26. StreamingCommunity/Util/config_json.py +1 -1
  27. StreamingCommunity/Util/headers.py +0 -3
  28. StreamingCommunity/Util/os.py +15 -46
  29. StreamingCommunity/__init__.py +2 -1
  30. StreamingCommunity/run.py +11 -10
  31. {streamingcommunity-3.2.5.dist-info → streamingcommunity-3.2.7.dist-info}/METADATA +4 -8
  32. {streamingcommunity-3.2.5.dist-info → streamingcommunity-3.2.7.dist-info}/RECORD +36 -35
  33. {streamingcommunity-3.2.5.dist-info → streamingcommunity-3.2.7.dist-info}/WHEEL +0 -0
  34. {streamingcommunity-3.2.5.dist-info → streamingcommunity-3.2.7.dist-info}/entry_points.txt +0 -0
  35. {streamingcommunity-3.2.5.dist-info → streamingcommunity-3.2.7.dist-info}/licenses/LICENSE +0 -0
  36. {streamingcommunity-3.2.5.dist-info → streamingcommunity-3.2.7.dist-info}/top_level.txt +0 -0
@@ -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
 
@@ -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
 
@@ -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
 
@@ -9,11 +9,9 @@ from rich.console import Console
9
9
 
10
10
 
11
11
  # Internal utilities
12
- from StreamingCommunity.Util.os import os_manager
13
12
  from StreamingCommunity.Util.message import start_message
14
13
  from StreamingCommunity.Util.config_json import config_manager
15
- from StreamingCommunity.Util.os import get_wvd_path
16
- from StreamingCommunity.Lib.Downloader.DASH.downloader import DASH_Download
14
+ from StreamingCommunity.Util.os import os_manager, get_wvd_path
17
15
 
18
16
 
19
17
  # Logic class
@@ -22,6 +20,7 @@ from StreamingCommunity.Api.Template.Class.SearchType import MediaItem
22
20
 
23
21
 
24
22
  # Player
23
+ from StreamingCommunity import DASH_Downloader
25
24
  from .util.get_license import get_playback_session, get_auth_token, generate_device_id
26
25
 
27
26
 
@@ -55,7 +54,7 @@ def download_film(select_title: MediaItem) -> str:
55
54
  query_params = parse_qs(parsed_url.query)
56
55
 
57
56
  # Download the episode
58
- r_proc = DASH_Download(
57
+ r_proc = DASH_Downloader(
59
58
  cdm_device=get_wvd_path(),
60
59
  license_url='https://www.crunchyroll.com/license/v1/license/widevine',
61
60
  mpd_url=mpd_url,
@@ -12,13 +12,11 @@ from rich.prompt import Prompt
12
12
 
13
13
  # Internal utilities
14
14
  from StreamingCommunity.Util.message import start_message
15
- from StreamingCommunity.Util.os import os_manager
16
- from StreamingCommunity.Util.os import get_wvd_path
17
- from StreamingCommunity.Lib.Downloader.DASH.downloader import DASH_Download
15
+ from StreamingCommunity.Util.os import os_manager, get_wvd_path
18
16
 
19
17
 
20
18
  # Logic class
21
- from .util.ScrapeSerie import GetSerieInfo
19
+ from .util.ScrapeSerie import GetSerieInfo, delete_stream_episode
22
20
  from StreamingCommunity.Api.Template.Util import (
23
21
  manage_selection,
24
22
  map_episode_title,
@@ -31,6 +29,7 @@ from StreamingCommunity.Api.Template.Class.SearchType import MediaItem
31
29
 
32
30
 
33
31
  # Player
32
+ from StreamingCommunity import DASH_Downloader
34
33
  from .util.get_license import get_playback_session, get_auth_token, generate_device_id
35
34
 
36
35
 
@@ -65,12 +64,14 @@ def download_video(index_season_selected: int, index_episode_selected: int, scra
65
64
  # Generate mpd and license URLs
66
65
  url_id = obj_episode.get('url').split('/')[-1]
67
66
  device_id = generate_device_id()
68
- mpd_url, mpd_headers = get_playback_session(get_auth_token(device_id), device_id, url_id)
67
+ token_mpd = get_auth_token(device_id)
68
+
69
+ mpd_url, mpd_headers = get_playback_session(token_mpd, device_id, url_id)
69
70
  parsed_url = urlparse(mpd_url)
70
71
  query_params = parse_qs(parsed_url.query)
71
72
 
72
73
  # Download the episode
73
- r_proc = DASH_Download(
74
+ r_proc = DASH_Downloader(
74
75
  cdm_device=get_wvd_path(),
75
76
  license_url='https://www.crunchyroll.com/license/v1/license/widevine',
76
77
  mpd_url=mpd_url,
@@ -95,6 +96,9 @@ def download_video(index_season_selected: int, index_episode_selected: int, scra
95
96
  try: os.remove(status['path'])
96
97
  except Exception: pass
97
98
 
99
+ # Delete episode stream
100
+ delete_stream_episode(url_id, query_params['playbackGuid'][0], mpd_headers)
101
+
98
102
  return status['path'], status['stopped']
99
103
 
100
104
  def download_episode(index_season_selected: int, scrape_serie: GetSerieInfo, download_all: bool = False, episode_selection: str = None) -> None:
@@ -45,6 +45,26 @@ def get_season_episodes(season_id, headers, params):
45
45
  )
46
46
  return response
47
47
 
48
+ def delete_stream_episode(episode_id, stream_id, headers):
49
+ """
50
+ Deletes a specific stream episode by episode ID and stream ID.
51
+ """
52
+ url = f'https://www.crunchyroll.com/playback/v1/token/{episode_id}/{stream_id}'
53
+ headers = get_headers()
54
+
55
+ response = requests.delete(
56
+ url,
57
+ headers=headers,
58
+ impersonate="chrome110"
59
+ )
60
+
61
+ if response.status_code == 204:
62
+ return True
63
+
64
+ else:
65
+ logging.error(f"Failed to delete stream episode: {response.status_code} - {response.text}")
66
+ return False
67
+
48
68
 
49
69
  class GetSerieInfo:
50
70
  def __init__(self, series_id):
@@ -1,7 +1,6 @@
1
1
  # 13.06.24
2
2
 
3
3
  import os
4
- import logging
5
4
  from typing import Tuple
6
5
 
7
6
 
@@ -12,7 +11,6 @@ from rich.prompt import Prompt
12
11
 
13
12
  # Internal utilities
14
13
  from StreamingCommunity.Util.message import start_message
15
- from StreamingCommunity.Lib.Downloader import HLS_Downloader
16
14
 
17
15
 
18
16
  # Logic class
@@ -30,6 +28,7 @@ from StreamingCommunity.Api.Template.Class.SearchType import MediaItem
30
28
 
31
29
  # Player
32
30
  from .util.ScrapeSerie import GetSerieInfo
31
+ from StreamingCommunity import HLS_Downloader
33
32
  from StreamingCommunity.Api.Player.supervideo import VideoSource
34
33
 
35
34
 
@@ -12,7 +12,6 @@ from rich.console import Console
12
12
  from StreamingCommunity.Util.os import os_manager, get_wvd_path
13
13
  from StreamingCommunity.Util.message import start_message
14
14
  from StreamingCommunity.Util.headers import get_headers
15
- from StreamingCommunity.Lib.Downloader.DASH.downloader import DASH_Download
16
15
 
17
16
 
18
17
  # Logic class
@@ -22,6 +21,7 @@ from StreamingCommunity.Api.Template.Class.SearchType import MediaItem
22
21
 
23
22
  # Player
24
23
  from .util.fix_mpd import get_manifest
24
+ from StreamingCommunity import DASH_Downloader
25
25
  from .util.get_license import get_bearer_token, get_playback_url, get_tracking_info, generate_license_url
26
26
 
27
27
 
@@ -48,14 +48,23 @@ def download_film(select_title: MediaItem) -> Tuple[str, bool]:
48
48
 
49
49
  # Generate mpd and license URLs
50
50
  bearer = get_bearer_token()
51
- playback_json = get_playback_url(bearer, select_title.url.split('_')[-1])
51
+
52
+ # Extract ID from the episode URL
53
+ episode_id = select_title.url.split('_')[-1]
54
+ if "http" in episode_id:
55
+ try: episode_id = select_title.url.split('/')[-1]
56
+ except Exception:
57
+ console.print(f"[red]Error:[/red] Failed to parse episode ID from URL: {select_title.url}")
58
+ return None, True
59
+
60
+ playback_json = get_playback_url(bearer, episode_id)
52
61
  tracking_info = get_tracking_info(bearer, playback_json)[0]
53
62
 
54
63
  license_url = generate_license_url(bearer, tracking_info)
55
64
  mpd_url = get_manifest(tracking_info['video_src'])
56
65
 
57
66
  # Download the episode
58
- r_proc = DASH_Download(
67
+ r_proc = DASH_Downloader(
59
68
  cdm_device=get_wvd_path(),
60
69
  license_url=license_url,
61
70
  mpd_url=mpd_url,
@@ -10,11 +10,9 @@ from rich.prompt import Prompt
10
10
 
11
11
 
12
12
  # Internal utilities
13
- from StreamingCommunity.Util.message import start_message
14
- from StreamingCommunity.Util.os import os_manager
15
13
  from StreamingCommunity.Util.headers import get_headers
16
- from StreamingCommunity.Util.os import get_wvd_path
17
- from StreamingCommunity.Lib.Downloader.DASH.downloader import DASH_Download
14
+ from StreamingCommunity.Util.message import start_message
15
+ from StreamingCommunity.Util.os import os_manager, get_wvd_path
18
16
 
19
17
 
20
18
  # Logic class
@@ -32,6 +30,7 @@ from StreamingCommunity.Api.Template.Class.SearchType import MediaItem
32
30
 
33
31
  # Player
34
32
  from .util.fix_mpd import get_manifest
33
+ from StreamingCommunity import DASH_Downloader
35
34
  from .util.get_license import get_bearer_token, get_playback_url, get_tracking_info, generate_license_url
36
35
 
37
36
 
@@ -65,14 +64,23 @@ def download_video(index_season_selected: int, index_episode_selected: int, scra
65
64
 
66
65
  # Generate mpd and license URLs
67
66
  bearer = get_bearer_token()
68
- playback_json = get_playback_url(bearer, obj_episode.url.split('_')[-1])
67
+
68
+ # Extract ID from the episode URL
69
+ episode_id = obj_episode.url.split('_')[-1]
70
+ if "http" in episode_id:
71
+ try: episode_id = obj_episode.url.split('/')[-1]
72
+ except Exception:
73
+ console.print(f"[red]Error:[/red] Failed to parse episode ID from URL: {obj_episode.url}")
74
+ return None, True
75
+
76
+ playback_json = get_playback_url(bearer, episode_id)
69
77
  tracking_info = get_tracking_info(bearer, playback_json)[0]
70
78
 
71
79
  license_url = generate_license_url(bearer, tracking_info)
72
80
  mpd_url = get_manifest(tracking_info['video_src'])
73
81
 
74
82
  # Download the episode
75
- r_proc = DASH_Download(
83
+ r_proc = DASH_Downloader(
76
84
  cdm_device=get_wvd_path(),
77
85
  license_url=license_url,
78
86
  mpd_url=mpd_url,
@@ -71,10 +71,7 @@ def get_playback_url(BEARER_TOKEN, CONTENT_ID):
71
71
 
72
72
  json_data = {
73
73
  'contentId': CONTENT_ID,
74
- 'streamType': 'VOD',
75
- 'delivery': 'Streaming',
76
- 'createDevice': True,
77
- 'overrideAppName': 'web//mediasetplay-web/5.11.8-f16d93c',
74
+ 'streamType': 'VOD'
78
75
  }
79
76
 
80
77
  try:
@@ -11,9 +11,8 @@ from rich.console import Console
11
11
 
12
12
  # Internal utilities
13
13
  from StreamingCommunity.Util.os import os_manager
14
- from StreamingCommunity.Util.message import start_message
15
- from StreamingCommunity.Lib.Downloader import HLS_Downloader
16
14
  from StreamingCommunity.Util.headers import get_headers
15
+ from StreamingCommunity.Util.message import start_message
17
16
 
18
17
 
19
18
  # Logic class
@@ -22,6 +21,7 @@ from StreamingCommunity.Api.Template.Class.SearchType import MediaItem
22
21
 
23
22
 
24
23
  # Player
24
+ from StreamingCommunity import HLS_Downloader
25
25
  from StreamingCommunity.Api.Player.mediapolisvod import VideoSource
26
26
 
27
27
 
@@ -11,7 +11,7 @@ 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
14
+
15
15
 
16
16
  # Logic class
17
17
  from .util.ScrapeSerie import GetSerieInfo
@@ -27,6 +27,7 @@ from StreamingCommunity.Api.Template.Class.SearchType import MediaItem
27
27
 
28
28
 
29
29
  # Player
30
+ from StreamingCommunity import HLS_Downloader
30
31
  from StreamingCommunity.Api.Player.mediapolisvod import VideoSource
31
32
 
32
33
 
@@ -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
  from StreamingCommunity.TelegramHelp.telegram_bot import TelegramSession, get_bot_instance
15
14
 
16
15
 
@@ -20,6 +19,7 @@ from StreamingCommunity.Api.Template.Class.SearchType import MediaItem
20
19
 
21
20
 
22
21
  # Player
22
+ from StreamingCommunity import HLS_Downloader
23
23
  from StreamingCommunity.Api.Player.vixcloud import VideoSource
24
24
 
25
25
 
@@ -11,15 +11,14 @@ 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 TelegramSession, get_bot_instance
16
15
 
16
+
17
17
  # Logic class
18
18
  from .util.ScrapeSerie import GetSerieInfo
19
19
  from StreamingCommunity.Api.Template.Util import (
20
20
  manage_selection,
21
21
  map_episode_title,
22
- dynamic_format_number,
23
22
  validate_selection,
24
23
  validate_episode_selection,
25
24
  display_episodes_list
@@ -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.vixcloud import VideoSource
33
33
 
34
34
 
@@ -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.hdplayer import VideoSource
23
23
 
24
24
 
@@ -2,12 +2,14 @@
2
2
 
3
3
  import os
4
4
  import shutil
5
+
6
+
7
+ # External libraries
5
8
  from rich.console import Console
6
9
 
7
10
 
8
11
  # Internal utilities
9
12
  from StreamingCommunity.Util.config_json import config_manager
10
- from StreamingCommunity.Util.os import os_manager
11
13
  from StreamingCommunity.Lib.FFmpeg.command import join_audios, join_video
12
14
 
13
15
 
@@ -19,17 +21,16 @@ from .cdm_helpher import get_widevine_keys
19
21
 
20
22
 
21
23
  # Config
22
- ENABLE_AUDIO = config_manager.get_bool('M3U8_DOWNLOAD', 'download_audio')
23
24
  DOWNLOAD_SPECIFIC_AUDIO = config_manager.get_list('M3U8_DOWNLOAD', 'specific_list_audio')
24
- CLEANUP_TMP = config_manager.get_bool('M3U8_DOWNLOAD', 'cleanup_tmp_folder')
25
25
  FILTER_CUSTOM_REOLUTION = str(config_manager.get('M3U8_PARSER', 'force_resolution')).strip().lower()
26
+ CLEANUP_TMP = config_manager.get_bool('M3U8_DOWNLOAD', 'cleanup_tmp_folder')
26
27
 
27
28
 
28
29
  # Variable
29
30
  console = Console()
30
31
 
31
32
 
32
- class DASH_Download:
33
+ class DASH_Downloader:
33
34
  def __init__(self, cdm_device, license_url, mpd_url, output_path):
34
35
  self.cdm_device = cdm_device
35
36
  self.license_url = license_url
@@ -69,17 +70,14 @@ class DASH_Download:
69
70
  )
70
71
  self.selected_video = selected_video
71
72
 
72
- # Audio info (only if enabled)
73
- if ENABLE_AUDIO:
74
- selected_audio, list_available_audio_langs, filter_custom_audio, downloadable_audio = self.parser.select_audio(DOWNLOAD_SPECIFIC_AUDIO)
75
- console.print(
76
- f"[cyan bold]Audio [/cyan bold] [green]Available:[/green] [purple]{', '.join(list_available_audio_langs)}[/purple] | "
77
- f"[red]Set:[/red] [purple]{filter_custom_audio}[/purple] | "
78
- f"[yellow]Downloadable:[/yellow] [purple]{downloadable_audio}[/purple]"
79
- )
80
- self.selected_audio = selected_audio
81
- else:
82
- self.selected_audio = None
73
+ # Audio info
74
+ selected_audio, list_available_audio_langs, filter_custom_audio, downloadable_audio = self.parser.select_audio(DOWNLOAD_SPECIFIC_AUDIO)
75
+ console.print(
76
+ f"[cyan bold]Audio [/cyan bold] [green]Available:[/green] [purple]{', '.join(list_available_audio_langs)}[/purple] | "
77
+ f"[red]Set:[/red] [purple]{filter_custom_audio}[/purple] | "
78
+ f"[yellow]Downloadable:[/yellow] [purple]{downloadable_audio}[/purple]"
79
+ )
80
+ self.selected_audio = selected_audio
83
81
 
84
82
  def get_representation_by_type(self, typ):
85
83
  if typ == "video":
@@ -61,7 +61,7 @@ class MPDParser:
61
61
  self.base_url = mpd_url.rsplit('/', 1)[0] + '/'
62
62
 
63
63
  def parse(self, custom_headers):
64
- response = httpx.get(self.mpd_url, headers=custom_headers, timeout=max_timeout, follow_redirects=True)
64
+ response = httpx.get(self.mpd_url, headers=custom_headers, timeout=max_timeout)
65
65
  response.raise_for_status()
66
66
 
67
67
  root = ET.fromstring(response.content)
@@ -17,7 +17,7 @@ from rich.panel import Panel
17
17
  # Internal utilities
18
18
  from StreamingCommunity.Util.config_json import config_manager
19
19
  from StreamingCommunity.Util.headers import get_userAgent
20
- from StreamingCommunity.Util.os import compute_sha1_hash, os_manager, internet_manager
20
+ from StreamingCommunity.Util.os import os_manager, internet_manager
21
21
  from StreamingCommunity.TelegramHelp.telegram_bot import get_bot_instance
22
22
 
23
23
 
@@ -33,11 +33,9 @@ from .segments import M3U8_Segments
33
33
 
34
34
 
35
35
  # Config
36
- ENABLE_AUDIO = config_manager.get_bool('M3U8_DOWNLOAD', 'download_audio')
37
36
  ENABLE_SUBTITLE = config_manager.get_bool('M3U8_DOWNLOAD', 'download_subtitle')
38
37
  DOWNLOAD_SPECIFIC_AUDIO = config_manager.get_list('M3U8_DOWNLOAD', 'specific_list_audio')
39
38
  DOWNLOAD_SPECIFIC_SUBTITLE = config_manager.get_list('M3U8_DOWNLOAD', 'specific_list_subtitles')
40
- MERGE_AUDIO = config_manager.get_bool('M3U8_DOWNLOAD', 'merge_audio')
41
39
  MERGE_SUBTITLE = config_manager.get_bool('M3U8_DOWNLOAD', 'merge_subs')
42
40
  CLEANUP_TMP = config_manager.get_bool('M3U8_DOWNLOAD', 'cleanup_tmp_folder')
43
41
  FILTER_CUSTOM_REOLUTION = str(config_manager.get('M3U8_PARSER', 'force_resolution')).strip().lower()
@@ -65,6 +63,7 @@ class HLSClient:
65
63
  Response content/text or None if all retries fail
66
64
  """
67
65
  client = httpx.Client(headers=self.headers, timeout=MAX_TIMEOUT, follow_redirects=True)
66
+
68
67
  for attempt in range(RETRY_LIMIT):
69
68
  try:
70
69
  response = client.get(url)
@@ -95,11 +94,6 @@ class PathManager:
95
94
  Ensures output path is valid and follows expected format.
96
95
  Creates a hash-based filename if no path is provided.
97
96
  """
98
- if not path:
99
- root = config_manager.get('OUT_FOLDER', 'root_path')
100
- hash_name = compute_sha1_hash(self.m3u8_url) + ".mp4"
101
- return os.path.join(root, "undefined", hash_name)
102
-
103
97
  if not path.endswith(".mp4"):
104
98
  path += ".mp4"
105
99
 
@@ -171,12 +165,11 @@ class M3U8Manager:
171
165
  logging.error("Resolution not recognized.")
172
166
  self.video_url, self.video_res = self.parser._video.get_best_uri()
173
167
 
174
- self.audio_streams = []
175
- if ENABLE_AUDIO:
176
- self.audio_streams = [
177
- s for s in (self.parser._audio.get_all_uris_and_names() or [])
178
- if s.get('language') in DOWNLOAD_SPECIFIC_AUDIO
179
- ]
168
+ # Audio info
169
+ self.audio_streams = [
170
+ s for s in (self.parser._audio.get_all_uris_and_names() or [])
171
+ if s.get('language') in DOWNLOAD_SPECIFIC_AUDIO
172
+ ]
180
173
 
181
174
  self.sub_streams = []
182
175
  if ENABLE_SUBTITLE:
@@ -308,8 +301,8 @@ class DownloadManager:
308
301
  Downloads all selected streams (video, audio, subtitles).
309
302
  """
310
303
  return_stopped = False
311
-
312
304
  video_file = os.path.join(self.temp_dir, 'video', '0.ts')
305
+
313
306
  if not os.path.exists(video_file):
314
307
  if self.download_video(video_url):
315
308
  if not return_stopped:
@@ -374,7 +367,7 @@ class MergeManager:
374
367
  )
375
368
 
376
369
  else:
377
- if MERGE_AUDIO and self.audio_streams:
370
+ if self.audio_streams:
378
371
  audio_tracks = [{
379
372
  'path': os.path.join(self.temp_dir, 'audio', a['language'], '0.ts'),
380
373
  'name': a['language']