remove token headers

This commit is contained in:
Ghost 2024-03-10 15:17:54 +01:00
parent 30bfc207a4
commit 8fda9d59ce
4 changed files with 37 additions and 88 deletions

View File

@ -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)

View File

@ -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")

View File

@ -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()

2
run.py
View File

@ -31,7 +31,6 @@ def initialize():
check_ffmpeg()
print("\n")
def main():
initialize()
@ -90,6 +89,5 @@ def main():
console.print("[red]Done!")
if __name__ == '__main__':
main()