fix bug path

This commit is contained in:
Ghost 2024-01-04 19:56:44 +01:00
parent b96afc9de8
commit 38be06a7c6
11 changed files with 114 additions and 217 deletions

View File

@ -2,8 +2,8 @@
# Class import
from Stream.util.headers import get_headers
from Stream.util.console import console
from Stream.util.m3u8 import dw_m3u8
from Stream.util.util import convert_utf8_name
# General import
import requests, sys, re, json
@ -43,9 +43,12 @@ def get_m3u8_key(json_win_video, json_win_param, title_name):
def main_dw_film(id_film, title_name, domain):
lower_title_name = str(title_name).lower()
title_name = convert_utf8_name(lower_title_name) # ERROR LATIN 1 IN REQ WITH ò à ù ...
embed_content = get_iframe(id_film, domain)
json_win_video, json_win_param = parse_content(embed_content)
m3u8_url = get_m3u8_url(json_win_video, json_win_param)
m3u8_key = get_m3u8_key(json_win_video, json_win_param, title_name)
dw_m3u8(m3u8_url, requests.get(m3u8_url, headers={"User-agent": get_headers()}).text, "", m3u8_key, str(title_name).replace("+", " ").replace(",", "") + ".mp4")
dw_m3u8(m3u8_url, requests.get(m3u8_url, headers={"User-agent": get_headers()}).text, "", m3u8_key, lower_title_name.replace("+", " ").replace(",", "") + ".mp4")

View File

@ -21,7 +21,6 @@ def get_version(domain):
return json.loads(info_data_page)['version']
except:
console.log("[red]UPDATE DOMANIN")
sys.exit(0)

View File

@ -2,8 +2,9 @@
# Class import
from Stream.util.headers import get_headers
from Stream.util.console import console, msg, console_print
from Stream.util.console import console, msg
from Stream.util.m3u8 import dw_m3u8, join_audio_to_video
from Stream.util.util import convert_utf8_name, check_audio_presence
# General import
import requests, os, re, json
@ -80,27 +81,34 @@ def main_dw_tv(tv_id, tv_name, version, domain):
token = get_token(tv_id, domain)
tv_name = str(tv_name.replace('+', '-')).lower()
console.log(f"[blue]Season find: [red]{get_info_tv(tv_id, tv_name, version, domain)}")
season_select = msg.ask("[green]Insert season number: ")
lower_tv_name = str(tv_name).lower()
tv_name = convert_utf8_name(lower_tv_name) # ERROR LATIN 1 IN REQ WITH ò à ù ...
console.print(f"[blue]Season find: [red]{get_info_tv(tv_id, tv_name, version, domain)}")
season_select = msg.ask("\n[green]Insert season number: ")
eps = get_info_season(tv_id, tv_name, domain, version, token, season_select)
for ep in eps:
console_print(f"[green]Ep: [blue]{ep['n']} [green]=> [purple]{ep['name']}")
index_ep_select = int(msg.ask("[green]Insert ep number: ")) - 1
console.print(f"[green]Ep: [blue]{ep['n']} [green]=> [purple]{ep['name']}")
index_ep_select = int(msg.ask("\n[green]Insert ep number: ")) - 1
embed_content = get_iframe(tv_id, eps[index_ep_select]['id'], domain, token)
json_win_video, json_win_param = parse_content(embed_content)
m3u8_url = get_m3u8_url(json_win_video, json_win_param)
m3u8_key = get_m3u8_key_ep(json_win_video, json_win_param, tv_name, season_select, index_ep_select+1, eps[index_ep_select]['name'])
dw_m3u8(m3u8_url, requests.get(m3u8_url, headers={"User-agent": get_headers()}).text, "", m3u8_key, tv_name.replace("+", "_") + "_"+str(season_select)+"__"+str(index_ep_select+1) + ".mp4")
mp4_name = lower_tv_name.replace("+", "_") + "_"+str(season_select)+"__"+str(index_ep_select+1)
mp4_format = mp4_name + ".mp4"
base_path_mp4 = os.path.join("videos", mp4_format)
base_audio_path = os.path.join("videos", mp4_format + "_audio.mp4")
is_down_audio = msg.ask("[blue]Download audio [red](!!! Only for recent upload, !!! Use all CPU) [blue][y \ n]").strip()
if str(is_down_audio) == "y":
dw_m3u8(m3u8_url, requests.get(m3u8_url, headers={"User-agent": get_headers()}).text, "", m3u8_key, mp4_format)
if not check_audio_presence(base_path_mp4):
console.log("[red]Audio is not present, start download (Use all CPU)")
m3u8_url_audio = get_m3u8_audio(json_win_video, json_win_param, tv_name, season_select, index_ep_select+1, eps[index_ep_select]['name'])
dw_m3u8(m3u8_url_audio, requests.get(m3u8_url_audio, headers={"User-agent": get_headers()}).text, "", m3u8_key, "audio.mp4")
join_audio_to_video("videos//audio.mp4", "videos//" + tv_name.replace("+", "_") + "_"+str(season_select)+"__"+str(index_ep_select+1) + ".mp4", "videos//" + tv_name.replace("+", "_") + "_"+str(season_select)+"__"+str(index_ep_select+1) + "_audio.mp4")
os.remove("videos//audio.mp4")
os.remove("videos//" + tv_name.replace("+", "_") + "_"+str(season_select)+"__"+str(index_ep_select+1) + ".mp4")
temp_audio_path = os.path.join("videos", "audio.mp4")
join_audio_to_video(temp_audio_path, base_path_mp4, base_audio_path)
os.remove(temp_audio_path)
os.remove(base_path_mp4)

View File

@ -1,5 +1,5 @@
__title__ = 'Streaming_community'
__version__ = 'v0.5.0'
__version__ = 'v0.6.0'
__author__ = 'Ghost6446'
__description__ = 'A command-line program to download film'
__license__ = 'MIT License'

View File

@ -1,13 +1,12 @@
# 26.12.2023
# Class import
from Stream.util.console import console
# 13.09.2023
# General import
from Stream.util.console import console
import os, requests, time
# Variable
github_repo_name = "StreamingCommunity_api"
repo_name = "StreamingCommunity_api"
repo_user = "ghost6446"
main = os.path.abspath(os.path.dirname(__file__))
base = "\\".join(main.split("\\")[:-1])
@ -19,24 +18,19 @@ def get_install_version():
def main_update():
json = requests.get(f"https://api.github.com/repos/ghost6446/{github_repo_name}/releases").json()[0]
stargazers_count = requests.get(f"https://api.github.com/repos/ghost6446/{github_repo_name}").json()['stargazers_count']
json = requests.get(f"https://api.github.com/repos/{repo_user}/{repo_name}/releases").json()[0]
stargazers_count = requests.get(f"https://api.github.com/repos/{repo_user}/{repo_name}").json()['stargazers_count']
last_version = json['name']
down_count = json['assets'][0]['download_count']
# Get percentaul star
if down_count > 0 and stargazers_count > 0:
percentual_stars = round(stargazers_count / down_count * 100, 2)
if down_count > 0 and stargazers_count > 0: percentual_stars = round(stargazers_count / down_count * 100, 2)
else: percentual_stars = 0
if get_install_version() != last_version:
console.log(f"[red]A new version is available")
else:
console.log("[red]Everything up to date")
if get_install_version() != last_version: console.print(f"[red]=> A new version is available")
else: console.print("[red]=> Everything up to date")
print("\n")
console.log(f"[red]Only was downloaded [yellow]{down_count} [red]times, but only [yellow]{percentual_stars} [red]of You(!) have starred it. \n\
[cyan]Help the repository grow today, by leaving a [yellow]star [cyan]on it and sharing it to others online!")
time.sleep(5)
console.print(f"[red]{repo_name} was downloaded [yellow]{down_count} [red]times, but only [yellow]{percentual_stars}% [red]of You(!!) have starred it. \n\
[cyan]Help the repository grow today, by leaving a [yellow]star [cyan]and [yellow]sharing [cyan]it to others online!")
time.sleep(2.5)
print("\n")

View File

@ -3,7 +3,6 @@
# Import
from rich.console import Console
from rich.prompt import Prompt
from rich import print as console_print
# Variable
msg = Prompt()

View File

@ -9,4 +9,5 @@ def get_headers():
software_names = [SoftwareName.CHROME.value]
operating_systems = [OperatingSystem.WINDOWS.value, OperatingSystem.LINUX.value]
user_agent_rotator = UserAgent(software_names=software_names, operating_systems=operating_systems, limit=10)
return user_agent_rotator.get_random_user_agent()

View File

@ -6,10 +6,8 @@ from functools import partial
from multiprocessing.dummy import Pool
from tqdm.rich import tqdm
import moviepy.editor as mp
from Stream.util.platform import *
# Class import
#from Stream.util.console import console
from Stream.util.console import console
# Disable warning
@ -17,35 +15,27 @@ import warnings
from tqdm import TqdmExperimentalWarning
warnings.filterwarnings("ignore", category=TqdmExperimentalWarning)
# Variable
main_out_folder = "videos"
os.makedirs("videos", exist_ok=True)
os.makedirs(main_out_folder, exist_ok=True)
path_out_without_key = "temp_ts"
path_out_with_key = "out_ts"
# [ decoder ] -> costant = ou_ts
class Video_Decoder(object):
iv = ""
uri = ""
method = ""
# [ decoder ]
def decode_aes_128(path_video_frame, decript_key, x_key):
frame_name = path_video_frame.split("\\")[-1].split("-")[0] + ".ts"
iv = x_key["IV"].lstrip("0x") if "IV" in x_key.keys() else ""
def __init__(self, x_key, uri):
self.method = x_key["METHOD"] if "METHOD" in x_key.keys() else ""
self.uri = uri
self.iv = x_key["IV"].lstrip("0x") if "IV" in x_key.keys() else ""
def decode_aes_128(self, video_fname: str):
if is_platform_linux():
frame_name = video_fname.split("/")[-1].split("-")[0] + ".ts"
else:
frame_name = video_fname.split("\\")[-1].split("-")[0] + ".ts"
res_cmd = subprocess.run(["openssl","aes-128-cbc","-d","-in", video_fname,"-out", "ou_ts/"+frame_name,"-nosalt","-iv", self.iv,"-K", self.uri ], capture_output=True)
res_cmd_str = res_cmd.stderr.decode("utf-8")
res_cmd_fix = res_cmd_str.replace("b", "").replace("\n", "").replace("\r", "")
if "lengthad" in res_cmd_fix:
console.log("[red]Wrong m3u8 key or remove key from input !!!")
sys.exit(0)
out = subprocess.run([
"openssl",
"aes-128-cbc", "-d",
"-in", path_video_frame,
"-out", os.path.join(path_out_with_key, frame_name),
"-nosalt","-iv", iv,
"-K", decript_key
], capture_output=True)
def decode_ext_x_key(key_str: str):
key_str = key_str.replace('"', '').lstrip("#EXT-X-KEY:")
@ -60,7 +50,6 @@ def save_in_part(folder_ts, merged_mp4, file_extension = ".ts"):
# Get list of ts file in order
os.chdir(folder_ts)
# Order all ts file
try: ordered_ts_names = sorted(glob.glob(f"*{file_extension}"), key=lambda x:float(re.findall("(\d+)", x.split("_")[1])[0]))
except:
@ -78,10 +67,8 @@ def save_in_part(folder_ts, merged_mp4, file_extension = ".ts"):
# Create mp4 from start ts to end
def save_part_ts(start, end, part):
#console.log(f"[blue]Process part [green][[red]{part}[green]]")
list_mp4_part.append(f"{part}.mp4")
with open(f"{part}_concat.txt", "w") as f:
for i in range(start, end):
f.write(f"file {ordered_ts_names[i]} \n")
@ -119,12 +106,9 @@ def download_ts_file(ts_url: str, store_dir: str, headers):
# Get ts name and folder
ts_name = ts_url.split('/')[-1].split("?")[0]
ts_dir = store_dir + "/" + ts_name
ts_dir = os.path.join(store_dir, ts_name)
# Check if exist
if(not os.path.isfile(ts_dir)):
# Download
ts_res = requests.get(ts_url, headers=headers)
if(ts_res.status_code == 200):
@ -135,187 +119,82 @@ def download_ts_file(ts_url: str, store_dir: str, headers):
time.sleep(0.5)
def download_vvt_sub(content, language, folder_id):
# Get content of vvt
url_main_sub = ""
vvt = content.split("\n")
# Find main url or vvt
for i in range(len(vvt)):
line = str(vvt[i])
if line.startswith("#EXTINF"):
url_main_sub = vvt[i+1]
# Save subtitle to main folder out
path = os.path.join(main_out_folder, str(folder_id))
os.makedirs(path, exist_ok=True)
open(os.path.join(path, "sub_"+str(language)+".vtt"), "wb").write(requests.get(url_main_sub).content)
# [ donwload ]
def dw_m3u8(m3u8_link, m3u8_content, m3u8_headers="", decrypt_key="", merged_mp4="test.mp4"):
# Reading the m3u8 file
m3u8_http_base = m3u8_link.rstrip(m3u8_link.split("/")[-1])
m3u8_base_url = m3u8_link.rstrip(m3u8_link.split("/")[-1])
m3u8 = m3u8_content.split('\n')
ts_url_list = []
ts_names = []
x_key_dict = dict()
is_encryped = False
os.makedirs(path_out_without_key, exist_ok=True)
os.makedirs(path_out_with_key, exist_ok=True)
# Parsing the content in m3u8 with creation of url_list with url of ts file
for i_str in range(len(m3u8)):
line_str = m3u8[i_str]
if "AES-128" in str(line_str):
for i in range(len(m3u8)):
if "AES-128" in str(m3u8[i]):
is_encryped = True
if line_str.startswith("#EXT-X-KEY:"):
x_key_dict = decode_ext_x_key(line_str)
if m3u8[i].startswith("#EXT-X-KEY:"):
x_key_dict = decode_ext_x_key(m3u8[i])
if line_str.startswith("#EXTINF"):
ts_url = m3u8[i_str+1]
if m3u8[i].startswith("#EXTINF"):
ts_url = m3u8[i+1]
ts_names.append(ts_url.split('/')[-1])
if not ts_url.startswith("http"):
ts_url = m3u8_http_base + ts_url
ts_url = m3u8_base_url + ts_url
ts_url_list.append(ts_url)
#console.log(f"[blue]Find [white]=> [red]{len(ts_url_list)}[blue] ts file to download")
#console.log(f"[green]Is m3u8 encryped => [red]{is_encryped}")
console.log(f"[blue]Find [white]=> [red]{len(ts_url_list)}[blue] ts file to download")
if is_encryped and decrypt_key == "":
console.log(f"[red]M3U8 Is encryped")
sys.exit(0)
if is_encryped:
#console.log(f"[blue]Use decrypting")
video_decoder = Video_Decoder(x_key=x_key_dict, uri=decrypt_key)
os.makedirs("ou_ts", exist_ok=True)
# Using multithreading to download all ts file
os.makedirs("temp_ts", exist_ok=True)
pool = Pool(15)
gen = pool.imap(partial(download_ts_file, store_dir="temp_ts", headers=m3u8_headers), ts_url_list)
for _ in tqdm(gen, total=len(ts_url_list), unit="bytes", unit_scale=True, unit_divisor=1024, desc="[yellow]Download"):
gen = pool.imap(partial(download_ts_file, store_dir=path_out_without_key, headers=m3u8_headers), ts_url_list)
for _ in tqdm(gen, total=len(ts_url_list), unit="bytes", unit_scale=True, unit_divisor=1024, desc="[yellow]Download m3u8"):
pass
pool.close()
pool.join()
# Merge all ts
if is_encryped:
path = ""
if is_platform_linux():
path = "temp_ts/*.ts"
else:
path = "temp_ts\*.ts"
for ts_fname in tqdm(glob.glob(path), desc="[yellow]Decoding"):
video_decoder.decode_aes_128(ts_fname)
# Start to merge all *.ts files
save_in_part("ou_ts", merged_mp4)
for ts_fname in tqdm(glob.glob(f"{path_out_without_key}/*.ts"), desc="[yellow]Decoding m3u8"):
decode_aes_128(ts_fname, decrypt_key, x_key_dict)
save_in_part(path_out_with_key, merged_mp4)
else:
save_in_part("temp_ts", merged_mp4)
save_in_part(path_out_without_key, merged_mp4)
# Clean temp file
os.chdir("..")
console.log("[green]Clean")
# Move mp4 file to main folder
if is_encryped: shutil.move(path_out_with_key+"/"+merged_mp4 , main_out_folder+"/")
else: shutil.move(path_out_without_key+"/"+merged_mp4 , main_out_folder+"/")
if is_platform_linux():
if is_encryped:
shutil.move("ou_ts/"+merged_mp4 , main_out_folder+"/")
else:
shutil.move("temp_ts/"+merged_mp4 , main_out_folder+"/")
else:
if is_encryped:
shutil.move("ou_ts\\"+merged_mp4 , main_out_folder+"\\")
else:
shutil.move("temp_ts\\"+merged_mp4 , main_out_folder+"\\")
shutil.rmtree("ou_ts", ignore_errors=True)
shutil.rmtree("temp_ts", ignore_errors=True)
def dw_aac(m3u8_link, m3u8_content, m3u8_headers, merged_mp3):
# Reading the m3u8 file
url_base = m3u8_link.rstrip(m3u8_link.split("/")[-1])
m3u8 = m3u8_content.split('\n')
ts_url_list = []
ts_names = []
# Parsing the content in m3u8 with creation of url_list with url of ts file
for i in range(len(m3u8)):
line = m3u8[i]
if line.startswith("#EXTINF"):
ts_url = m3u8[i+1]
ts_names.append(ts_url.split('/')[-1])
if not ts_url.startswith("http"):
ts_url = url_base + ts_url
ts_url_list.append(ts_url)
console.log(f"[blue]Find [white]=> [red]{len(ts_url_list)}[blue] ts file to download")
# Using multithreading to download all ts file
os.makedirs("temp_ts", exist_ok=True)
pool = Pool(15)
gen = pool.imap(partial(download_ts_file, store_dir="temp_ts", headers=m3u8_headers), ts_url_list)
for _ in tqdm(gen, total=len(ts_url_list), unit="bytes", unit_scale=True, unit_divisor=1024, desc="[yellow]Download"):
pass
pool.close()
pool.join()
save_in_part("temp_ts", merged_mp3, file_extension=".aac")
# Clean temp file
os.chdir("..")
console.log("[green]Clean")
shutil.move("temp_ts\\"+merged_mp3 , ".")
shutil.rmtree("ou_ts", ignore_errors=True)
shutil.rmtree("temp_ts", ignore_errors=True)
def dw_vvt_sub(url, headers, folder_id) -> (None):
print(url, headers, folder_id)
# Get content of m3u8 vvt
req = requests.get(url, headers=headers)
vvts = req.text.split('\n')
vvt_data = []
# Parsing the content in m3u8 of vvt with creation of url_list with url and name of language
for line in vvts:
line = line.split(",")
if line[0] == "#EXT-X-MEDIA:TYPE=SUBTITLES":
vvt_data.append({
'language': line[2].split("=")[1].replace('"', ""),
'url': line[-1].split("URI=")[1].replace('"', "")
})
# Check array is not empty
if len(vvt_data) > 0:
# Download all subtitle
for i in range(len(vvts)):
console.log(f"[blue]Download [red]sub => [green]{vvt_data[i]['language']}")
download_vvt_sub(requests.get(vvt_data[i]['url']).text, vvt_data[i]['language'], folder_id)
else:
console.log("[red]Cant find info of subtitle [SKIP]")
# Remove folder out_ts and temp_ts
shutil.rmtree(path_out_with_key, ignore_errors=True)
shutil.rmtree(path_out_without_key, ignore_errors=True)
def join_audio_to_video(audio_path, video_path, out_path):
# Get audio and video
audio = mp.AudioFileClip(audio_path)
video1 = mp.VideoFileClip(video_path)
# Add audio
final = video1.set_audio(audio)
final.write_videofile(out_path)
# Join all
final.write_videofile(out_path)

View File

@ -1,7 +0,0 @@
import platform
def is_platform_windows():
return platform.system() == "Windows"
def is_platform_linux():
return platform.system() == "Linux"

15
Stream/util/util.py Normal file
View File

@ -0,0 +1,15 @@
# 4.01.2023
# Import
from moviepy.editor import VideoFileClip
def convert_utf8_name(name):
return str(name).encode('utf-8').decode('latin-1')
def check_audio_presence(file_path):
try:
video_clip = VideoFileClip(file_path)
audio = video_clip.audio
return audio is not None
except Exception as e:
print(f"Si è verificato un errore: {str(e)}")

16
run.py
View File

@ -4,23 +4,29 @@
import Stream.api.page as Page
from Stream.util.message import msg_start
from Stream.upload.update import main_update
from Stream.util.console import console, msg, console_print
from Stream.util.console import console, msg
from Stream.api.film import main_dw_film as download_film
from Stream.api.tv import main_dw_tv as download_tv
# General import
import sys
# Variable
domain = "cz"
site_version = Page.get_version(domain)
def main():
msg_start()
main_update()
film_search = msg.ask("[blue]Insert film to search: ").strip()
console.print(f"[blue]Find system [white]=> [red]{sys.platform} \n")
film_search = msg.ask("[blue]Insert word to search in all site: ").strip()
db_title = Page.search(film_search, domain)
for i in range(len(db_title)):
console_print(f"[yellow]{i} [white]-> [green]{db_title[i]['name']} [white]- [cyan]{db_title[i]['type']}")
index_select = int(msg.ask("[blue]Index to download: "))
console.print(f"[yellow]{i} [white]-> [green]{db_title[i]['name']} [white]- [cyan]{db_title[i]['type']}")
index_select = int(msg.ask("\n[blue]Index to download: "))
if db_title[index_select]['type'] == "movie":
console.log(f"[green]Movie select: {db_title[index_select]['name']}")