mirror of
https://github.com/Arrowar/StreamingCommunity.git
synced 2025-06-07 12:05:35 +00:00
fix stuck 98%
This commit is contained in:
parent
715e0524d7
commit
0709edde7f
1
.gitignore
vendored
1
.gitignore
vendored
@ -7,4 +7,3 @@ pyvenv.cfg
|
|||||||
# Project specific
|
# Project specific
|
||||||
videos/
|
videos/
|
||||||
tmp/
|
tmp/
|
||||||
Src/Util/file_list.txt
|
|
@ -121,7 +121,7 @@ def dw_single_ep(tv_id, eps, index_ep_select, domain, token, tv_name, season_sel
|
|||||||
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'], token_render)
|
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'], token_render)
|
||||||
|
|
||||||
if m3u8_url_audio != None:
|
if m3u8_url_audio != None:
|
||||||
console.print("[red]=> Use m3u8 audio")
|
console.print("[blue]Use m3u8 audio => [red]True")
|
||||||
|
|
||||||
dw_m3u8(m3u8_url, m3u8_url_audio, m3u8_key, mp4_path)
|
dw_m3u8(m3u8_url, m3u8_url_audio, m3u8_key, mp4_path)
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
__title__ = 'Streaming_community'
|
__title__ = 'Streaming_community'
|
||||||
__version__ = 'v0.7.5'
|
__version__ = 'v0.7.8'
|
||||||
__author__ = 'Ghost6446'
|
__author__ = 'Ghost6446'
|
||||||
__description__ = 'A command-line program to download film'
|
__description__ = 'A command-line program to download film'
|
||||||
__license__ = 'MIT License'
|
__license__ = 'MIT License'
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
# 4.01.2023
|
# 4.01.2023
|
||||||
|
|
||||||
# Import
|
# Import
|
||||||
import ffmpeg
|
import ffmpeg, subprocess, re
|
||||||
|
|
||||||
def convert_utf8_name(name):
|
def convert_utf8_name(name):
|
||||||
return str(name).encode('utf-8').decode('latin-1')
|
return str(name).encode('utf-8').decode('latin-1')
|
||||||
@ -10,8 +10,15 @@ def there_is_audio(ts_file_path):
|
|||||||
probe = ffmpeg.probe(ts_file_path)
|
probe = ffmpeg.probe(ts_file_path)
|
||||||
return any(stream['codec_type'] == 'audio' for stream in probe['streams'])
|
return any(stream['codec_type'] == 'audio' for stream in probe['streams'])
|
||||||
|
|
||||||
|
|
||||||
def merge_ts_files(video_path, audio_path, output_path):
|
def merge_ts_files(video_path, audio_path, output_path):
|
||||||
input_video = ffmpeg.input(video_path)
|
input_video = ffmpeg.input(video_path)
|
||||||
input_audio = ffmpeg.input(audio_path)
|
input_audio = ffmpeg.input(audio_path)
|
||||||
ffmpeg.output(input_video, input_audio, output_path, format='mpegts', acodec='copy', vcodec='copy', loglevel='quiet').run()
|
|
||||||
|
ffmpeg_command = ffmpeg.output(input_video, input_audio, output_path, format='mpegts', acodec='copy', vcodec='copy', loglevel='quiet').compile()
|
||||||
|
|
||||||
|
try:
|
||||||
|
subprocess.run(ffmpeg_command, check=True, stderr=subprocess.PIPE)
|
||||||
|
return True
|
||||||
|
except subprocess.CalledProcessError as e:
|
||||||
|
#print(f"Failed convert: {video_path} \ {audio_path} to {output_path}")
|
||||||
|
return False
|
@ -1,12 +1,12 @@
|
|||||||
# 5.01.24 -> 7.01.24
|
# 5.01.24 -> 7.01.24
|
||||||
|
|
||||||
# Import
|
# Import
|
||||||
import requests, re, os, ffmpeg, shutil, time, sys
|
import requests, re, os, ffmpeg, shutil, time, sys, warnings
|
||||||
from tqdm.rich import tqdm
|
from tqdm.rich import tqdm
|
||||||
from concurrent.futures import ThreadPoolExecutor
|
from concurrent.futures import ThreadPoolExecutor
|
||||||
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
|
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
|
||||||
from cryptography.hazmat.backends import default_backend
|
from cryptography.hazmat.backends import default_backend
|
||||||
import moviepy.editor as mp
|
|
||||||
|
|
||||||
# Class import
|
# Class import
|
||||||
from Src.Util.Helper.console import console
|
from Src.Util.Helper.console import console
|
||||||
@ -14,6 +14,12 @@ from Src.Util.Helper.headers import get_headers
|
|||||||
from Src.Util.Helper.util import there_is_audio, merge_ts_files
|
from Src.Util.Helper.util import there_is_audio, merge_ts_files
|
||||||
|
|
||||||
|
|
||||||
|
# Disable warning
|
||||||
|
from tqdm import TqdmExperimentalWarning
|
||||||
|
warnings.filterwarnings("ignore", category=TqdmExperimentalWarning)
|
||||||
|
warnings.filterwarnings("ignore", category=UserWarning, module="cryptography")
|
||||||
|
|
||||||
|
|
||||||
# Variable
|
# Variable
|
||||||
os.makedirs("videos", exist_ok=True)
|
os.makedirs("videos", exist_ok=True)
|
||||||
|
|
||||||
@ -26,6 +32,9 @@ class M3U8Downloader:
|
|||||||
self.m3u8_audio = m3u8_audio
|
self.m3u8_audio = m3u8_audio
|
||||||
self.key = key
|
self.key = key
|
||||||
self.output_filename = output_filename
|
self.output_filename = output_filename
|
||||||
|
if output_filename == None:
|
||||||
|
console.log(f"Cant pass None as output file name")
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
self.segments = []
|
self.segments = []
|
||||||
self.segments_audio = []
|
self.segments_audio = []
|
||||||
@ -35,6 +44,8 @@ class M3U8Downloader:
|
|||||||
self.temp_folder = "tmp"
|
self.temp_folder = "tmp"
|
||||||
os.makedirs(self.temp_folder, exist_ok=True)
|
os.makedirs(self.temp_folder, exist_ok=True)
|
||||||
self.download_audio = False
|
self.download_audio = False
|
||||||
|
self.max_retry = 3
|
||||||
|
self.failed_segments = []
|
||||||
|
|
||||||
def decode_ext_x_key(self, key_str):
|
def decode_ext_x_key(self, key_str):
|
||||||
key_str = key_str.replace('"', '').lstrip("#EXT-X-KEY:")
|
key_str = key_str.replace('"', '').lstrip("#EXT-X-KEY:")
|
||||||
@ -119,6 +130,21 @@ class M3U8Downloader:
|
|||||||
|
|
||||||
return decrypted_data
|
return decrypted_data
|
||||||
|
|
||||||
|
def make_req_single_ts_file(self, ts_url, retry=0):
|
||||||
|
|
||||||
|
if retry == self.max_retry:
|
||||||
|
console.log(f"[red]Failed download: {ts_url}")
|
||||||
|
self.segments.remove(ts_url)
|
||||||
|
return None
|
||||||
|
|
||||||
|
req = requests.get(ts_url, headers={'user-agent': get_headers()}, timeout=10, allow_redirects=True)
|
||||||
|
|
||||||
|
if req.status_code == 200:
|
||||||
|
return req.content
|
||||||
|
else:
|
||||||
|
retry += 1
|
||||||
|
return self.make_req_single_ts_file(ts_url, retry)
|
||||||
|
|
||||||
def decrypt_and_save(self, index):
|
def decrypt_and_save(self, index):
|
||||||
|
|
||||||
video_ts_url = self.segments[index]
|
video_ts_url = self.segments[index]
|
||||||
@ -126,44 +152,57 @@ class M3U8Downloader:
|
|||||||
|
|
||||||
# Download video or audio ts file
|
# Download video or audio ts file
|
||||||
if not os.path.exists(video_ts_filename): # Only for media that not use audio
|
if not os.path.exists(video_ts_filename): # Only for media that not use audio
|
||||||
ts_response = requests.get(video_ts_url, headers={'user-agent': get_headers()}).content
|
ts_response = self.make_req_single_ts_file(video_ts_url)
|
||||||
|
|
||||||
if self.key and self.iv:
|
if ts_response != None:
|
||||||
decrypted_data = self.decrypt_ts(ts_response)
|
if self.key and self.iv:
|
||||||
with open(video_ts_filename, "wb") as ts_file:
|
decrypted_data = self.decrypt_ts(ts_response)
|
||||||
ts_file.write(decrypted_data)
|
with open(video_ts_filename, "wb") as ts_file:
|
||||||
|
ts_file.write(decrypted_data)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
with open(video_ts_filename, "wb") as ts_file:
|
with open(video_ts_filename, "wb") as ts_file:
|
||||||
ts_file.write(ts_response)
|
ts_file.write(ts_response)
|
||||||
|
|
||||||
# Donwload only audio ts file
|
# Donwload only audio ts file and merge with video
|
||||||
if self.download_audio:
|
if self.download_audio:
|
||||||
audio_ts_url = self.segments_audio[index]
|
audio_ts_url = self.segments_audio[index]
|
||||||
audio_ts_filename = os.path.join(self.temp_folder, f"{index}_a.ts")
|
audio_ts_filename = os.path.join(self.temp_folder, f"{index}_a.ts")
|
||||||
video_audio_ts_filename = os.path.join(self.temp_folder, f"{index}_v_a.ts")
|
video_audio_ts_filename = os.path.join(self.temp_folder, f"{index}_v_a.ts")
|
||||||
|
|
||||||
if not os.path.exists(video_audio_ts_filename): # Only for media use audio
|
if not os.path.exists(video_audio_ts_filename): # Only for media use audio
|
||||||
ts_response = requests.get(audio_ts_url, headers={'user-agent': get_headers()}).content
|
ts_response = self.make_req_single_ts_file(audio_ts_url)
|
||||||
|
|
||||||
if self.key and self.iv:
|
if ts_response != None:
|
||||||
decrypted_data = self.decrypt_ts(ts_response)
|
if self.key and self.iv:
|
||||||
with open(audio_ts_filename, "wb") as ts_file:
|
decrypted_data = self.decrypt_ts(ts_response)
|
||||||
ts_file.write(decrypted_data)
|
|
||||||
|
|
||||||
else:
|
with open(audio_ts_filename, "wb") as ts_file:
|
||||||
with open(audio_ts_filename, "wb") as ts_file:
|
ts_file.write(decrypted_data)
|
||||||
ts_file.write(ts_response)
|
|
||||||
|
|
||||||
# Join ts video and audio
|
else:
|
||||||
merge_ts_files(video_ts_filename, audio_ts_filename, video_audio_ts_filename)
|
with open(audio_ts_filename, "wb") as ts_file:
|
||||||
os.remove(video_ts_filename)
|
ts_file.write(ts_response)
|
||||||
os.remove(audio_ts_filename)
|
|
||||||
|
# Join ts video and audio
|
||||||
|
res_merge = merge_ts_files(video_ts_filename, audio_ts_filename, video_audio_ts_filename)
|
||||||
|
|
||||||
|
if res_merge:
|
||||||
|
os.remove(video_ts_filename)
|
||||||
|
os.remove(audio_ts_filename)
|
||||||
|
|
||||||
|
# If merge fail, so we have only video and audio, take only video
|
||||||
|
else:
|
||||||
|
self.failed_segments.append(index)
|
||||||
|
os.remove(audio_ts_filename)
|
||||||
|
|
||||||
def download_and_save_ts(self):
|
def download_and_save_ts(self):
|
||||||
with ThreadPoolExecutor(max_workers=30) as executor:
|
with ThreadPoolExecutor(max_workers=30) as executor:
|
||||||
list(tqdm(executor.map(self.decrypt_and_save, range(len(self.segments)) ), total=len(self.segments), unit="bytes", unit_scale=True, unit_divisor=1024, desc="[yellow]Download"))
|
list(tqdm(executor.map(self.decrypt_and_save, range(len(self.segments)) ), total=len(self.segments), unit="bytes", unit_scale=True, unit_divisor=1024, desc="[yellow]Download"))
|
||||||
|
|
||||||
|
if len(self.failed_segments) > 0:
|
||||||
|
console.log(f"[red]Segment ts: {self.failed_segments}, cant use audio")
|
||||||
|
|
||||||
def join_ts_files(self):
|
def join_ts_files(self):
|
||||||
|
|
||||||
current_dir = os.path.dirname(os.path.realpath(__file__))
|
current_dir = os.path.dirname(os.path.realpath(__file__))
|
||||||
|
4
run.py
4
run.py
@ -18,7 +18,9 @@ site_version = Page.get_version(domain)
|
|||||||
def main():
|
def main():
|
||||||
|
|
||||||
msg_start()
|
msg_start()
|
||||||
main_update()
|
try: main_update()
|
||||||
|
except: console.print("[blue]Req github [white]=> [red]Failed")
|
||||||
|
|
||||||
console.print(f"[blue]Find system [white]=> [red]{sys.platform} \n")
|
console.print(f"[blue]Find system [white]=> [red]{sys.platform} \n")
|
||||||
|
|
||||||
film_search = msg.ask("\n[blue]Insert word to search in all site: ").strip()
|
film_search = msg.ask("\n[blue]Insert word to search in all site: ").strip()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user