mirror of
https://github.com/Arrowar/StreamingCommunity.git
synced 2025-06-07 12:05:35 +00:00
fix(subtitles): add subtitles to corresponding folder
This commit is contained in:
parent
3f716739c4
commit
04431a12a7
@ -10,6 +10,7 @@ from Src.Lib.FFmpeg.my_m3u8 import download_m3u8
|
||||
import requests, os, re, json, sys, binascii
|
||||
from bs4 import BeautifulSoup
|
||||
|
||||
|
||||
# [func]
|
||||
def get_iframe(id_title, domain):
|
||||
req = requests.get(url = f"https://streamingcommunity.{domain}/iframe/{id_title}", headers = {
|
||||
@ -30,6 +31,7 @@ def get_iframe(id_title, domain):
|
||||
console.log(f"[red]Error: {req.status_code}")
|
||||
sys.exit(0)
|
||||
|
||||
|
||||
def select_quality(json_win_param):
|
||||
|
||||
if json_win_param['token1080p']:
|
||||
@ -41,6 +43,7 @@ def select_quality(json_win_param):
|
||||
else:
|
||||
return "360p"
|
||||
|
||||
|
||||
def parse_content(embed_content):
|
||||
|
||||
# Parse parameter from req embed content
|
||||
@ -53,10 +56,12 @@ def parse_content(embed_content):
|
||||
json_win_param = json_win_param.replace(",}", "}").replace("'", '"')
|
||||
return json.loads(json_win_video), json.loads(json_win_param), select_quality(json.loads(json_win_param))
|
||||
|
||||
|
||||
def get_m3u8_url(json_win_video, json_win_param, render_quality):
|
||||
token_render = f"token{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(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"]}',
|
||||
@ -68,6 +73,7 @@ def get_m3u8_key(json_win_video, json_win_param, title_name, token_render):
|
||||
console.log(f"[red]Error: {response.status_code}")
|
||||
sys.exit(0)
|
||||
|
||||
|
||||
def get_m3u8_audio(json_win_video, json_win_param, title_name, token_render):
|
||||
req = requests.get(f'https://vixcloud.co/playlist/{json_win_video["id"]}', params={'token': json_win_param['token'], 'expires': json_win_param["expires"] }, 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"]}'
|
||||
@ -101,7 +107,7 @@ def main_dw_film(id_film, title_name, domain):
|
||||
|
||||
m3u8_url_audio = get_m3u8_audio(json_win_video, json_win_param, title_name, token_render)
|
||||
|
||||
if m3u8_url_audio != None:
|
||||
if m3u8_url_audio is not None:
|
||||
console.print("[blue]Using m3u8 audio => [red]True")
|
||||
|
||||
download_m3u8(m3u8_index=m3u8_url, m3u8_audio=m3u8_url_audio, m3u8_subtitle=m3u8_url, key=m3u8_key, output_filename=mp4_path)
|
||||
subtitle_path = os.path.join(config['root_path'], config['series_folder_name'], mp4_name)
|
||||
download_m3u8(m3u8_index=m3u8_url, m3u8_audio=m3u8_url_audio, m3u8_subtitle=m3u8_url, key=m3u8_key, output_filename=mp4_path, subtitle_folder=subtitle_path, content_name=mp4_name)
|
||||
|
@ -17,6 +17,7 @@ def get_token(id_tv, domain):
|
||||
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={
|
||||
@ -31,6 +32,7 @@ def get_info_tv(id_film, title_name, site_version, domain):
|
||||
console.log(f"[red]Error: {req.status_code}")
|
||||
sys.exit(0)
|
||||
|
||||
|
||||
def get_info_season(tv_id, tv_name, domain, version, token, n_stagione):
|
||||
req = requests.get(f'https://streamingcommunity.{domain}/titles/{tv_id}-{tv_name}/stagione-{n_stagione}', headers={
|
||||
'authority': f'streamingcommunity.{domain}', 'referer': f'https://streamingcommunity.broker/titles/{tv_id}-{tv_name}',
|
||||
@ -43,6 +45,7 @@ def get_info_season(tv_id, tv_name, domain, version, token, n_stagione):
|
||||
console.log(f"[red]Error: {req.status_code}")
|
||||
sys.exit(0)
|
||||
|
||||
|
||||
def get_iframe(tv_id, ep_id, domain, token):
|
||||
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}',
|
||||
@ -86,14 +89,17 @@ def parse_content(embed_content):
|
||||
json_win_param = json_win_param.replace(",}", "}").replace("'", '"')
|
||||
return json.loads(json_win_video), json.loads(json_win_param), select_quality(json.loads(json_win_param))
|
||||
|
||||
|
||||
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_url(json_win_video, json_win_param, render_quality):
|
||||
token_render = f"token{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_stagione, 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_stagione}%3AE{n_ep}+{ep_title}&nextEpisode=1',
|
||||
@ -124,7 +130,7 @@ def get_m3u8_playlist(json_win_video, json_win_param, tv_name, n_stagione, n_ep,
|
||||
# [func \ main]
|
||||
def dw_single_ep(tv_id, eps, index_ep_select, domain, token, tv_name, season_select):
|
||||
|
||||
enccoded_name = urllib.parse.quote(eps[index_ep_select]['name'])
|
||||
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)
|
||||
@ -135,19 +141,22 @@ 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, enccoded_name, token_render)
|
||||
m3u8_key = get_m3u8_key_ep(json_win_video, json_win_param, tv_name, season_select, index_ep_select+1, encoded_name, token_render)
|
||||
|
||||
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"
|
||||
season = mp4_name.rsplit("E", 1)[0]
|
||||
mp4_path = os.path.join(config['root_path'], config['series_folder_name'], tv_name, season, mp4_format)
|
||||
|
||||
m3u8_url_audio = get_m3u8_playlist(json_win_video, json_win_param, tv_name, season_select, index_ep_select+1, enccoded_name, token_render)
|
||||
m3u8_url_audio = get_m3u8_playlist(json_win_video, json_win_param, tv_name, season_select, index_ep_select+1, encoded_name, token_render)
|
||||
|
||||
if m3u8_url_audio != None:
|
||||
if m3u8_url_audio is not None:
|
||||
console.print("[blue]Using m3u8 audio => [red]True")
|
||||
# Movie_Name.[Language_Code].vtt
|
||||
# Movie_Name.[Language_Code].forced.vtt
|
||||
subtitle_path = os.path.join(config['root_path'], config['series_folder_name'], mp4_name, season)
|
||||
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)
|
||||
|
||||
download_m3u8(m3u8_index=m3u8_url, m3u8_audio=m3u8_url_audio, m3u8_subtitle=m3u8_playlist, key=m3u8_key, output_filename=mp4_path)
|
||||
|
||||
def main_dw_tv(tv_id, tv_name, version, domain):
|
||||
|
||||
|
@ -66,7 +66,7 @@ class M3U8_Parser:
|
||||
})
|
||||
|
||||
for key in m3u8_obj.keys:
|
||||
if key != None:
|
||||
if key is not None:
|
||||
self.keys = ({
|
||||
"method": key.method,
|
||||
"uri": key.uri,
|
||||
@ -91,7 +91,6 @@ class M3U8_Parser:
|
||||
"uri": media.uri
|
||||
})
|
||||
|
||||
|
||||
for segment in m3u8_obj.segments:
|
||||
if "vtt" not in segment.uri:
|
||||
self.segments.append(segment.uri)
|
||||
@ -111,10 +110,10 @@ class M3U8_Parser:
|
||||
print("No video playlist found")
|
||||
return None
|
||||
|
||||
def download_subtitle(self):
|
||||
def download_subtitle(self, subtitle_path, content_name):
|
||||
"""Download all subtitle if present"""
|
||||
|
||||
path = os.path.join(config['root_path'], "Film o Serie", "nome film o stagione serie")
|
||||
path = subtitle_path
|
||||
|
||||
if self.subtitle_playlist:
|
||||
for sub_info in self.subtitle_playlist:
|
||||
@ -130,9 +129,12 @@ class M3U8_Parser:
|
||||
sub_parse = 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
|
||||
open(os.path.join(path, "nome film o serie" ,f".{name_language}" + "se conteneva forced: .forced" + ".vtt"), "wb").write(requests.get(url_subtitle).content)
|
||||
# Movie_Name.[Language_Code].forced.vtt # If forced
|
||||
# Implementare "forced"
|
||||
open(os.path.join(path, content_name + f".{name_language}" + ".vtt"), "wb").write(requests.get(url_subtitle).content)
|
||||
|
||||
else:
|
||||
console.log("[red]No subtitle found")
|
||||
@ -143,7 +145,7 @@ class M3U8_Parser:
|
||||
if self.audio_ts:
|
||||
console.log(f"[cyan]Found {len(self.audio_ts)}, playlist with audio")
|
||||
|
||||
if language_name != None:
|
||||
if language_name is not None:
|
||||
for obj_audio in self.audio_ts:
|
||||
if obj_audio.get("name") == language_name:
|
||||
return obj_audio.get("uri")
|
||||
@ -153,11 +155,12 @@ 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
|
||||
self.key = key
|
||||
if key != None:
|
||||
if key is not None:
|
||||
self.decription = Decryption(key)
|
||||
|
||||
self.temp_folder = os.path.join("tmp", "segments")
|
||||
@ -173,7 +176,7 @@ class M3U8_Segments:
|
||||
m3u8_parser.parse_data(m3u8_content)
|
||||
|
||||
# Add decryption iv if present
|
||||
if self.key != None and m3u8_parser.keys:
|
||||
if self.key is not None and m3u8_parser.keys:
|
||||
self.decription.parse_key(m3u8_parser.keys.get("iv"))
|
||||
|
||||
# Add all segments
|
||||
@ -228,7 +231,6 @@ class M3U8_Segments:
|
||||
# print("Skip ", ts_url, " arr ", failed_segments)
|
||||
return None
|
||||
|
||||
|
||||
def save_ts(self, index, progress_counter, quit_event):
|
||||
"""Save ts file and decrypt if there is iv present in decryption class"""
|
||||
|
||||
@ -249,7 +251,7 @@ class M3U8_Segments:
|
||||
progress_counter.update(1)
|
||||
|
||||
def download_ts(self):
|
||||
"""Loop to donwload all segment of playlist m3u8 and break it if there is no progress"""
|
||||
"""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")
|
||||
|
||||
@ -313,6 +315,7 @@ class M3U8_Segments:
|
||||
file_list_path = os.path.join(current_dir, 'file_list.txt')
|
||||
|
||||
ts_files = [f for f in os.listdir(self.temp_folder) if f.endswith(".ts")]
|
||||
|
||||
def extract_number(file_name):
|
||||
return int(''.join(filter(str.isdigit, file_name)))
|
||||
ts_files.sort(key=extract_number)
|
||||
@ -321,7 +324,6 @@ class M3U8_Segments:
|
||||
console.log("[red]Couldn't find any segments to join, retry")
|
||||
sys.exit(0)
|
||||
|
||||
|
||||
with open(file_list_path, 'w') as f:
|
||||
for ts_file in ts_files:
|
||||
relative_path = os.path.relpath(os.path.join(self.temp_folder, ts_file), current_dir)
|
||||
@ -338,6 +340,7 @@ class M3U8_Segments:
|
||||
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
|
||||
@ -355,7 +358,7 @@ class M3U8_Downloader:
|
||||
print_duration_table(self.video_path)
|
||||
print("\n")
|
||||
|
||||
if self.m3u8_audio != None:
|
||||
if self.m3u8_audio is not None:
|
||||
audio_m3u8 = M3U8_Segments(self.m3u8_audio, self.key)
|
||||
console.log("[green]Downloading audio ts")
|
||||
audio_m3u8.get_info()
|
||||
@ -407,6 +410,7 @@ 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"""
|
||||
|
||||
@ -416,12 +420,13 @@ def download_subtitle(url, name_language):
|
||||
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):
|
||||
|
||||
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=""):
|
||||
|
||||
# Get byte of key
|
||||
key = bytes.fromhex(key) if key is not None else key
|
||||
|
||||
if m3u8_playlist != None:
|
||||
if m3u8_playlist is not None:
|
||||
console.log(f"[green]Downloading m3u8 from playlist")
|
||||
|
||||
# Parse m3u8 playlist
|
||||
@ -433,15 +438,13 @@ def download_m3u8(m3u8_playlist=None, m3u8_index = None, m3u8_audio=None, m3u8_s
|
||||
else:
|
||||
parse_class_m3u8.parse_data(m3u8_playlist)
|
||||
|
||||
|
||||
# Get italian language if present as default
|
||||
if DOWNLOAD_DEFAULT_LANGUAGE:
|
||||
m3u8_audio = parse_class_m3u8.get_track_audio("Italian")
|
||||
console.log(f"[green]Selected language => [purple]{m3u8_audio}")
|
||||
|
||||
|
||||
# Get best quality
|
||||
if m3u8_index == None:
|
||||
if m3u8_index is None:
|
||||
m3u8_index = parse_class_m3u8.get_best_quality()
|
||||
if "https" in m3u8_index:
|
||||
if log: console.log(f"[green]Selected m3u8 index => [purple]{m3u8_index}")
|
||||
@ -449,12 +452,11 @@ def download_m3u8(m3u8_playlist=None, m3u8_index = None, m3u8_audio=None, m3u8_s
|
||||
console.log("[red]Couldn't find a valid m3u8 index")
|
||||
sys.exit(0)
|
||||
|
||||
|
||||
# Download subtitle if present ( normally in m3u8 playlist )
|
||||
if DOWNLOAD_SUB:
|
||||
parse_class_m3u8.download_subtitle()
|
||||
parse_class_m3u8.download_subtitle(subtitle_path=subtitle_folder, content_name=content_name)
|
||||
|
||||
if m3u8_subtitle != None:
|
||||
if m3u8_subtitle is not None:
|
||||
|
||||
parse_class_m3u8_sub = M3U8_Parser()
|
||||
|
||||
@ -466,8 +468,7 @@ def download_m3u8(m3u8_playlist=None, m3u8_index = None, m3u8_audio=None, m3u8_s
|
||||
|
||||
# Download subtitle if present ( normally in m3u8 playlist )
|
||||
if DOWNLOAD_SUB:
|
||||
parse_class_m3u8_sub.download_subtitle()
|
||||
|
||||
parse_class_m3u8_sub.download_subtitle(subtitle_path=subtitle_folder, content_name=content_name)
|
||||
|
||||
# Download m3u8 index, with segments
|
||||
# os.makedirs("videos", exist_ok=True)
|
||||
|
Loading…
x
Reference in New Issue
Block a user