mirror of
https://github.com/Arrowar/StreamingCommunity.git
synced 2025-06-07 12:05:35 +00:00
remove token headers
This commit is contained in:
parent
30bfc207a4
commit
8fda9d59ce
@ -9,15 +9,16 @@ import requests
|
||||
import sys
|
||||
from bs4 import BeautifulSoup
|
||||
|
||||
|
||||
# Class import
|
||||
from Src.Lib.FFmpeg.my_m3u8 import download_m3u8
|
||||
from Src.Lib.FFmpeg.util import audio_extractor_m3u8
|
||||
from Src.Util.config import config
|
||||
from Src.Util.console import console
|
||||
# Class import
|
||||
from Src.Util.headers import get_headers
|
||||
|
||||
|
||||
# [func]
|
||||
|
||||
def get_iframe(id_title, domain):
|
||||
req = requests.get(url=f"https://streamingcommunity.{domain}/iframe/{id_title}", headers={
|
||||
"User-agent": get_headers()
|
||||
@ -72,10 +73,8 @@ def get_playlist(json_win_video, json_win_param, render_quality):
|
||||
token_render = f"token{render_quality}"
|
||||
return f"https://vixcloud.co/playlist/{json_win_video['id']}?token={json_win_param['token']}&{token_render}={json_win_param[token_render]}&expires={json_win_param['expires']}"
|
||||
|
||||
def get_m3u8_key(json_win_video, json_win_param, title_name, token_render):
|
||||
response = requests.get('https://vixcloud.co/storage/enc.key', headers={
|
||||
'referer': f'https://vixcloud.co/embed/{json_win_video["id"]}?token={json_win_param[token_render]}&title={title_name}&referer=1&expires={json_win_param["expires"]}',
|
||||
})
|
||||
def get_m3u8_key():
|
||||
response = requests.get('https://vixcloud.co/storage/enc.key')
|
||||
|
||||
if response.ok:
|
||||
return binascii.hexlify(response.content).decode('utf-8')
|
||||
@ -111,7 +110,7 @@ def main_dw_film(id_film, title_name, domain):
|
||||
console.print(f"[blue]Selected quality => [red]{render_quality}")
|
||||
|
||||
m3u8_url = get_m3u8_url(json_win_video, json_win_param, render_quality)
|
||||
m3u8_key = get_m3u8_key(json_win_video, json_win_param, title_name, token_render)
|
||||
m3u8_key = get_m3u8_key()
|
||||
m3u8_playlist = get_playlist(json_win_video, json_win_param, render_quality)
|
||||
|
||||
mp4_name = title_name.replace("+", " ").replace(",", "").replace("-", "_")
|
||||
@ -123,5 +122,6 @@ def main_dw_film(id_film, title_name, domain):
|
||||
if m3u8_url_audio is not None:
|
||||
console.print("[blue]Using m3u8 audio => [red]True")
|
||||
subtitle_path = os.path.join(config['root_path'], config['movies_folder_name'], mp4_name)
|
||||
|
||||
download_m3u8(m3u8_index=m3u8_url, m3u8_audio=m3u8_url_audio, m3u8_subtitle=m3u8_playlist, key=m3u8_key,
|
||||
output_filename=mp4_path, subtitle_folder=subtitle_path, content_name=mp4_name)
|
||||
|
@ -10,26 +10,19 @@ import sys
|
||||
import urllib
|
||||
from bs4 import BeautifulSoup
|
||||
|
||||
# Class import
|
||||
from Src.Lib.FFmpeg.my_m3u8 import download_m3u8
|
||||
from Src.Lib.FFmpeg.util import audio_extractor_m3u8
|
||||
from Src.Util.config import config
|
||||
from Src.Util.console import console, msg
|
||||
# Class import
|
||||
from Src.Util.headers import get_headers
|
||||
|
||||
|
||||
# [func]
|
||||
def get_token(id_tv, domain):
|
||||
session = requests.Session()
|
||||
session.get(f"https://streamingcommunity.{domain}/watch/{id_tv}")
|
||||
return session.cookies['XSRF-TOKEN']
|
||||
|
||||
|
||||
def get_info_tv(id_film, title_name, site_version, domain):
|
||||
req = requests.get(f"https://streamingcommunity.{domain}/titles/{id_film}-{title_name}", headers={
|
||||
'user-agent': get_headers(),
|
||||
'X-Inertia': 'true',
|
||||
'X-Inertia-Version': site_version,
|
||||
'User-Agent': get_headers()
|
||||
})
|
||||
|
||||
if req.ok:
|
||||
@ -39,16 +32,13 @@ def get_info_tv(id_film, title_name, site_version, domain):
|
||||
sys.exit(0)
|
||||
|
||||
|
||||
def get_info_season(tv_id, tv_name, domain, version, token, n_season):
|
||||
def get_info_season(tv_id, tv_name, domain, version, n_season):
|
||||
req = requests.get(
|
||||
f'https://streamingcommunity.{domain}/titles/{tv_id}-{tv_name}/stagione-{n_season}',
|
||||
headers={
|
||||
'authority': f'streamingcommunity.{domain}',
|
||||
'referer': f'https://streamingcommunity.broker/titles/{tv_id}-{tv_name}',
|
||||
'user-agent': get_headers(),
|
||||
'x-inertia': 'true',
|
||||
'x-inertia-version': version,
|
||||
'x-xsrf-token': token,
|
||||
})
|
||||
|
||||
if req.ok:
|
||||
@ -59,22 +49,11 @@ def get_info_season(tv_id, tv_name, domain, version, token, n_season):
|
||||
sys.exit(0)
|
||||
|
||||
|
||||
def get_iframe(tv_id, ep_id, domain, token):
|
||||
def get_iframe(tv_id, ep_id, domain):
|
||||
req = requests.get(f'https://streamingcommunity.{domain}/iframe/{tv_id}',
|
||||
params={'episode_id': ep_id, 'next_episode': '1'},
|
||||
cookies={'XSRF-TOKEN': token},
|
||||
headers={
|
||||
'referer': f'https://streamingcommunity.{domain}/watch/{tv_id}?e={ep_id}',
|
||||
'user-agent': get_headers()
|
||||
})
|
||||
|
||||
# Change user agent m3u8 (unused)
|
||||
"""
|
||||
custom_headers_req = {
|
||||
'referer': f'https://streamingcommunity.{domain}/watch/{tv_id}?e={ep_id}',
|
||||
'user-agent': get_headers()
|
||||
}
|
||||
"""
|
||||
headers={'user-agent': get_headers()}
|
||||
)
|
||||
|
||||
if req.ok:
|
||||
try:
|
||||
@ -122,10 +101,8 @@ def get_m3u8_url(json_win_video, json_win_param, render_quality):
|
||||
return f"https://vixcloud.co/playlist/{json_win_video['id']}?type=video&rendition={render_quality}&token={json_win_param[token_render]}&expires={json_win_param['expires']}"
|
||||
|
||||
|
||||
def get_m3u8_key_ep(json_win_video, json_win_param, tv_name, n_season, n_ep, ep_title, token_render):
|
||||
response = requests.get('https://vixcloud.co/storage/enc.key', headers={
|
||||
'referer': f'https://vixcloud.co/embed/{json_win_video["id"]}?token={json_win_param[token_render]}&title={tv_name}&referer=1&expires={json_win_param["expires"]}&description=S{n_season}%3AE{n_ep}+{ep_title}&nextEpisode=1',
|
||||
})
|
||||
def get_m3u8_key_ep():
|
||||
response = requests.get('https://vixcloud.co/storage/enc.key')
|
||||
|
||||
if response.ok:
|
||||
return binascii.hexlify(response.content).decode('utf-8')
|
||||
@ -151,12 +128,12 @@ def get_m3u8_audio(json_win_video, json_win_param, tv_name, n_season, n_ep, ep_t
|
||||
|
||||
|
||||
# [func \ main]
|
||||
def dw_single_ep(tv_id, eps, index_ep_select, domain, token, tv_name, season_select):
|
||||
def dw_single_ep(tv_id, eps, index_ep_select, domain, tv_name, season_select):
|
||||
encoded_name = urllib.parse.quote(eps[index_ep_select]['name'])
|
||||
|
||||
console.print(
|
||||
f"[green]Downloading episode: [blue]{eps[index_ep_select]['n']} [green]=> [purple]{eps[index_ep_select]['name']}")
|
||||
embed_content = get_iframe(tv_id, eps[index_ep_select]['id'], domain, token)
|
||||
embed_content = get_iframe(tv_id, eps[index_ep_select]['id'], domain)
|
||||
if embed_content is None:
|
||||
return
|
||||
json_win_video, json_win_param, render_quality = parse_content(embed_content)
|
||||
@ -166,8 +143,7 @@ def dw_single_ep(tv_id, eps, index_ep_select, domain, token, tv_name, season_sel
|
||||
|
||||
m3u8_playlist = get_playlist(json_win_video, json_win_param, render_quality)
|
||||
m3u8_url = get_m3u8_url(json_win_video, json_win_param, render_quality)
|
||||
m3u8_key = get_m3u8_key_ep(json_win_video, json_win_param, tv_name, season_select, index_ep_select + 1,
|
||||
encoded_name, token_render)
|
||||
m3u8_key = get_m3u8_key_ep()
|
||||
|
||||
mp4_name = f"{tv_name.replace('+', '_')}_S{str(season_select).zfill(2)}E{str(index_ep_select + 1).zfill(2)}"
|
||||
mp4_format = f"{mp4_name}.mp4"
|
||||
@ -186,7 +162,6 @@ def dw_single_ep(tv_id, eps, index_ep_select, domain, token, tv_name, season_sel
|
||||
|
||||
|
||||
def main_dw_tv(tv_id, tv_name, version, domain):
|
||||
token = get_token(tv_id, domain)
|
||||
|
||||
num_season_find = get_info_tv(tv_id, tv_name, version, domain)
|
||||
console.print(
|
||||
@ -197,14 +172,14 @@ def main_dw_tv(tv_id, tv_name, version, domain):
|
||||
start, end = map(int, season_select[1:-1].split('-'))
|
||||
result = list(range(start, end + 1))
|
||||
for n_season in result:
|
||||
eps = get_info_season(tv_id, tv_name, domain, version, token, n_season)
|
||||
eps = get_info_season(tv_id, tv_name, domain, version, n_season)
|
||||
for ep in eps:
|
||||
dw_single_ep(tv_id, eps, int(ep['n']) - 1, domain, token, tv_name, n_season)
|
||||
dw_single_ep(tv_id, eps, int(ep['n']) - 1, domain, tv_name, n_season)
|
||||
print("\n")
|
||||
elif season_select != "*":
|
||||
season_select = int(season_select)
|
||||
if 1 <= season_select <= num_season_find:
|
||||
eps = get_info_season(tv_id, tv_name, domain, version, token, season_select)
|
||||
eps = get_info_season(tv_id, tv_name, domain, version, season_select)
|
||||
|
||||
for ep in eps:
|
||||
console.print(f"[green]Episode: [blue]{ep['n']} [green]=> [purple]{ep['name']}")
|
||||
@ -218,27 +193,27 @@ def main_dw_tv(tv_id, tv_name, version, domain):
|
||||
|
||||
for n_range_ep in result:
|
||||
# index_ep_select = int(n_range_ep) # Unused
|
||||
dw_single_ep(tv_id, eps, n_range_ep - 1, domain, token, tv_name, season_select)
|
||||
dw_single_ep(tv_id, eps, n_range_ep - 1, domain, tv_name, season_select)
|
||||
|
||||
# Download single ep
|
||||
elif index_ep_select != "*":
|
||||
if 1 <= int(index_ep_select) <= len(eps):
|
||||
index_ep_select = int(index_ep_select) - 1
|
||||
dw_single_ep(tv_id, eps, index_ep_select, domain, token, tv_name, season_select)
|
||||
dw_single_ep(tv_id, eps, index_ep_select, domain, tv_name, season_select)
|
||||
else:
|
||||
console.print("[red]Wrong [yellow]INDEX [red]for the selected Episode")
|
||||
|
||||
# Download all
|
||||
else:
|
||||
for ep in eps:
|
||||
dw_single_ep(tv_id, eps, int(ep['n']) - 1, domain, token, tv_name, season_select)
|
||||
dw_single_ep(tv_id, eps, int(ep['n']) - 1, domain, tv_name, season_select)
|
||||
print("\n")
|
||||
|
||||
else:
|
||||
console.print("[red]Wrong [yellow]INDEX for the selected Season")
|
||||
else:
|
||||
for n_season in range(1, num_season_find + 1):
|
||||
eps = get_info_season(tv_id, tv_name, domain, version, token, n_season)
|
||||
eps = get_info_season(tv_id, tv_name, domain, version, n_season)
|
||||
for ep in eps:
|
||||
dw_single_ep(tv_id, eps, int(ep['n']) - 1, domain, token, tv_name, n_season)
|
||||
dw_single_ep(tv_id, eps, int(ep['n']) - 1, domain, tv_name, n_season)
|
||||
print("\n")
|
||||
|
@ -126,10 +126,6 @@ class M3U8_Parser:
|
||||
sub_parse.parse_data(req_sub_content.text)
|
||||
url_subtitle = sub_parse.subtitle[0]
|
||||
|
||||
# Subtitles convention:
|
||||
# Movie_Name.[Language_Code].vtt
|
||||
# Movie_Name.[Language_Code].forced.vtt # If forced
|
||||
|
||||
if "forced" in name_language.lower():
|
||||
name_language = name_language.lower().replace("forced", "").strip()
|
||||
name_language = name_language.lower().replace("-", "").strip()
|
||||
@ -161,7 +157,6 @@ class M3U8_Parser:
|
||||
else:
|
||||
console.log("[red]Couldn't find any playlist with audio")
|
||||
|
||||
|
||||
class M3U8_Segments:
|
||||
def __init__(self, url, key=None):
|
||||
self.url = url
|
||||
@ -195,7 +190,6 @@ class M3U8_Segments:
|
||||
|
||||
if response.ok:
|
||||
self.parse_data(response.text)
|
||||
# console.log(f"[red]Ts segments find [white]=> [yellow]{len(self.segments)}")
|
||||
|
||||
if len(self.segments) == 0:
|
||||
console.log("[red]Couldn't find any segments to download, retry")
|
||||
@ -224,17 +218,14 @@ class M3U8_Segments:
|
||||
if response.status_code == 200:
|
||||
return response.content
|
||||
else:
|
||||
# print(f"Failed to fetch {ts_url}: {response.status_code}")
|
||||
failed_segments.append(str(url_number))
|
||||
return None
|
||||
|
||||
except Exception as e:
|
||||
# print(f"Failed to fetch {ts_url}: {str(e)}")
|
||||
failed_segments.append(str(url_number))
|
||||
return None
|
||||
|
||||
else:
|
||||
# print("Skip ", ts_url, " arr ", failed_segments)
|
||||
return None
|
||||
|
||||
def save_ts(self, index, progress_counter, quit_event):
|
||||
@ -257,11 +248,8 @@ class M3U8_Segments:
|
||||
progress_counter.update(1)
|
||||
|
||||
def download_ts(self):
|
||||
"""Loop to download all segment of playlist m3u8 and break it if there is no progress"""
|
||||
|
||||
progress_counter = tqdm(total=len(self.segments), unit="bytes", desc="[yellow]Download")
|
||||
|
||||
# Event to signal when to quit
|
||||
quit_event = threading.Event()
|
||||
timeout_occurred = False
|
||||
|
||||
@ -272,7 +260,7 @@ class M3U8_Segments:
|
||||
with ThreadPoolExecutor(max_workers=MAX_WORKER) as executor:
|
||||
futures = []
|
||||
for index in range(len(self.segments)):
|
||||
if timeout_occurred: # Check if timeout occurred before submitting tasks
|
||||
if timeout_occurred:
|
||||
break
|
||||
future = executor.submit(self.save_ts, index, progress_counter, quit_event)
|
||||
futures.append(future)
|
||||
@ -282,13 +270,12 @@ class M3U8_Segments:
|
||||
future.result()
|
||||
except Exception as e:
|
||||
print(f"An error occurred: {str(e)}")
|
||||
# Handle the error as needed
|
||||
|
||||
finally:
|
||||
progress_counter.close()
|
||||
quit_event.set() # Signal the timer thread to quit
|
||||
timer_thread.join() # Ensure the timer thread is terminated
|
||||
quit_event.set()
|
||||
timer_thread.join()
|
||||
|
||||
# Continue with the rest of your code here...
|
||||
|
||||
def timer(self, progress_counter, quit_event, timeout_checker):
|
||||
start_time = time.time()
|
||||
@ -298,21 +285,20 @@ class M3U8_Segments:
|
||||
current_count = progress_counter.n
|
||||
|
||||
if current_count != last_count:
|
||||
start_time = time.time() # Update start time when progress is made
|
||||
start_time = time.time()
|
||||
last_count = current_count
|
||||
|
||||
elapsed_time = time.time() - start_time
|
||||
if elapsed_time > self.progress_timeout:
|
||||
console.log(f"[red]No progress for {self.progress_timeout} seconds.")
|
||||
console.log("[red]Breaking ThreadPoolExecutor...")
|
||||
timeout_checker() # Set the flag indicating a timeout
|
||||
quit_event.set() # Signal the main thread to quit
|
||||
break # Break the loop instead of exiting
|
||||
timeout_checker()
|
||||
quit_event.set()
|
||||
break
|
||||
|
||||
time.sleep(1)
|
||||
|
||||
# Execution reaches here when the loop is broken
|
||||
progress_counter.refresh() # Refresh the progress bar to reflect the last progress
|
||||
progress_counter.refresh()
|
||||
|
||||
def join(self, output_filename):
|
||||
"""Join all segments file to a mp4 file name"""
|
||||
@ -340,13 +326,11 @@ class M3U8_Segments:
|
||||
ffmpeg.input(file_list_path, format='concat', safe=0).output(output_filename, map_metadata='-1', c='copy', loglevel='error').run()
|
||||
except ffmpeg.Error as e:
|
||||
console.log(f"[red]Error saving MP4: {e.stdout}")
|
||||
#sys.exit(0)
|
||||
|
||||
console.log(f"[cyan]Clean ...")
|
||||
os.remove(file_list_path)
|
||||
shutil.rmtree("tmp", ignore_errors=True)
|
||||
|
||||
|
||||
class M3U8_Downloader:
|
||||
def __init__(self, m3u8_url, m3u8_audio = None, key=None, output_filename="output.mp4"):
|
||||
self.m3u8_url = m3u8_url
|
||||
@ -378,10 +362,7 @@ class M3U8_Downloader:
|
||||
if os.path.exists(f"{self.video_path}.mp4"):
|
||||
os.renames(f"{self.video_path}.mp4", self.video_path)
|
||||
|
||||
|
||||
|
||||
def join_audio(self):
|
||||
"""Join audio with video and sync it"""
|
||||
console.log("[cyan]Join audio and video")
|
||||
|
||||
try:
|
||||
@ -414,11 +395,8 @@ class M3U8_Downloader:
|
||||
os.remove(self.audio_path)
|
||||
|
||||
|
||||
|
||||
# [ main function ]
|
||||
def df_make_req(url):
|
||||
"""Make req to get text"""
|
||||
|
||||
response = requests.get(url)
|
||||
|
||||
if response.ok:
|
||||
@ -427,19 +405,16 @@ def df_make_req(url):
|
||||
console.log(f"[red]Wrong url, error: {response.status_code}")
|
||||
sys.exit(0)
|
||||
|
||||
|
||||
def download_subtitle(url, name_language):
|
||||
"""Make req to vtt url and save to video subtitle folder"""
|
||||
|
||||
path = os.path.join("videos", "subtitle")
|
||||
os.makedirs(path, exist_ok=True)
|
||||
|
||||
console.log(f"[green]Downloading subtitle: [red]{name_language}")
|
||||
open(os.path.join(path, name_language + ".vtt"), "wb").write(requests.get(url).content)
|
||||
|
||||
|
||||
def download_m3u8(m3u8_playlist=None, m3u8_index = None, m3u8_audio=None, m3u8_subtitle=None, key=None, output_filename=os.path.join("videos", "output.mp4"), log=False, subtitle_folder="subtitles", content_name=""):
|
||||
m3u8_audio_url=None
|
||||
# m3u8_playlist never use in this version
|
||||
|
||||
key = bytes.fromhex(key) if key is not None else key
|
||||
|
||||
@ -454,6 +429,7 @@ def download_m3u8(m3u8_playlist=None, m3u8_index = None, m3u8_audio=None, m3u8_s
|
||||
sys.exit(0)
|
||||
m3u8_audio_url = m3u8_audio_obj["url"]
|
||||
console.log(f"[green]Select language => [purple]{m3u8_audio_obj['lang']}")
|
||||
|
||||
if m3u8_subtitle != None:
|
||||
|
||||
parse_class_m3u8_sub = M3U8_Parser()
|
||||
|
Loading…
x
Reference in New Issue
Block a user