mirror of
https://github.com/Arrowar/StreamingCommunity.git
synced 2025-06-06 11:35:29 +00:00
Fix missing ts check.
This commit is contained in:
parent
8e6c211822
commit
d9259a945e
@ -31,6 +31,7 @@ from Src.Util.os import (
|
|||||||
# Logic class
|
# Logic class
|
||||||
from ...FFmpeg import (
|
from ...FFmpeg import (
|
||||||
print_duration_table,
|
print_duration_table,
|
||||||
|
get_video_duration_s,
|
||||||
join_video,
|
join_video,
|
||||||
join_audios,
|
join_audios,
|
||||||
join_subtitle
|
join_subtitle
|
||||||
@ -137,7 +138,6 @@ class HLS_Downloader():
|
|||||||
|
|
||||||
# Send a GET request to the provided URL
|
# Send a GET request to the provided URL
|
||||||
logging.info(f"Test url: {url}")
|
logging.info(f"Test url: {url}")
|
||||||
headers_index = {'user-agent': get_headers()}
|
|
||||||
response = httpx.get(url, headers=headers_index)
|
response = httpx.get(url, headers=headers_index)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@ -485,6 +485,11 @@ class HLS_Downloader():
|
|||||||
end_output_seconds = dict_to_seconds(end_output_time)
|
end_output_seconds = dict_to_seconds(end_output_time)
|
||||||
missing_ts = not (expected_real_seconds - 3 <= end_output_seconds <= expected_real_seconds + 3)
|
missing_ts = not (expected_real_seconds - 3 <= end_output_seconds <= expected_real_seconds + 3)
|
||||||
|
|
||||||
|
# Second check
|
||||||
|
if not missing_ts:
|
||||||
|
if get_video_duration_s(self.output_filename) < int(expected_real_seconds) - 5:
|
||||||
|
missing_ts = True
|
||||||
|
|
||||||
panel_content = (
|
panel_content = (
|
||||||
f"[bold green]Download completed![/bold green]\n"
|
f"[bold green]Download completed![/bold green]\n"
|
||||||
f"[cyan]File size: [bold red]{formatted_size}[/bold red]\n"
|
f"[cyan]File size: [bold red]{formatted_size}[/bold red]\n"
|
||||||
@ -499,10 +504,11 @@ class HLS_Downloader():
|
|||||||
))
|
))
|
||||||
|
|
||||||
# Delete all files except the output file
|
# Delete all files except the output file
|
||||||
if not missing_ts:
|
if missing_ts:
|
||||||
delete_files_except_one(self.base_path, os.path.basename(self.output_filename))
|
os.rename(self.output_filename, self.output_filename.replace(".mp4", "_failed.mp4"))
|
||||||
else:
|
|
||||||
delete_files_except_one(self.base_path, os.path.basename(self.output_filename.replace(".mp4", "_failed.mp4")))
|
# Delete all other conversion
|
||||||
|
delete_files_except_one(self.base_path, os.path.basename(self.output_filename.replace(".mp4", "_failed.mp4")))
|
||||||
|
|
||||||
# Remove the base folder
|
# Remove the base folder
|
||||||
if REMOVE_SEGMENTS_FOLDER:
|
if REMOVE_SEGMENTS_FOLDER:
|
||||||
|
@ -1,8 +1,4 @@
|
|||||||
# 18.04.24
|
# 18.04.24
|
||||||
|
|
||||||
from .command import (
|
from .command import join_video, join_audios, join_subtitle
|
||||||
join_video,
|
from .util import print_duration_table, get_video_duration_s
|
||||||
join_audios,
|
|
||||||
join_subtitle,
|
|
||||||
)
|
|
||||||
from .util import print_duration_table
|
|
||||||
|
@ -1,13 +1,9 @@
|
|||||||
# 16.04.24
|
# 16.04.24
|
||||||
|
|
||||||
import re
|
import re
|
||||||
import sys
|
|
||||||
import logging
|
import logging
|
||||||
import threading
|
import threading
|
||||||
import subprocess
|
import subprocess
|
||||||
from datetime import datetime
|
|
||||||
|
|
||||||
from typing import Tuple
|
|
||||||
|
|
||||||
|
|
||||||
# Internal utilities
|
# Internal utilities
|
||||||
|
@ -12,7 +12,7 @@ from typing import List, Dict
|
|||||||
from Src.Util._jsonConfig import config_manager
|
from Src.Util._jsonConfig import config_manager
|
||||||
from Src.Util.os import check_file_existence, suppress_output
|
from Src.Util.os import check_file_existence, suppress_output
|
||||||
from Src.Util.console import console
|
from Src.Util.console import console
|
||||||
from .util import need_to_force_to_ts, check_ffmpeg_input, check_duration_v_a
|
from .util import need_to_force_to_ts, check_duration_v_a
|
||||||
from .capture import capture_ffmpeg_real_time
|
from .capture import capture_ffmpeg_real_time
|
||||||
from ..M3U8 import M3U8_Codec
|
from ..M3U8 import M3U8_Codec
|
||||||
|
|
||||||
@ -26,7 +26,6 @@ USE_ACODEC = config_manager.get_bool("M3U8_CONVERSION", "use_acodec")
|
|||||||
USE_BITRATE = config_manager.get_bool("M3U8_CONVERSION", "use_bitrate")
|
USE_BITRATE = config_manager.get_bool("M3U8_CONVERSION", "use_bitrate")
|
||||||
USE_GPU = config_manager.get_bool("M3U8_CONVERSION", "use_gpu")
|
USE_GPU = config_manager.get_bool("M3U8_CONVERSION", "use_gpu")
|
||||||
FFMPEG_DEFAULT_PRESET = config_manager.get("M3U8_CONVERSION", "default_preset")
|
FFMPEG_DEFAULT_PRESET = config_manager.get("M3U8_CONVERSION", "default_preset")
|
||||||
CHECK_OUTPUT_CONVERSION = config_manager.get_bool("M3U8_CONVERSION", "check_output_after_ffmpeg")
|
|
||||||
|
|
||||||
|
|
||||||
# Variable
|
# Variable
|
||||||
@ -116,12 +115,6 @@ def join_video(video_path: str, out_path: str, codec: M3U8_Codec = None):
|
|||||||
capture_ffmpeg_real_time(ffmpeg_cmd, "[cyan]Join video")
|
capture_ffmpeg_real_time(ffmpeg_cmd, "[cyan]Join video")
|
||||||
print()
|
print()
|
||||||
|
|
||||||
# Check file output
|
|
||||||
if CHECK_OUTPUT_CONVERSION:
|
|
||||||
console.log("[red]Check output ffmpeg")
|
|
||||||
time.sleep(0.5)
|
|
||||||
check_ffmpeg_input(out_path)
|
|
||||||
|
|
||||||
time.sleep(0.5)
|
time.sleep(0.5)
|
||||||
if not check_file_existence(out_path):
|
if not check_file_existence(out_path):
|
||||||
logging.error("Missing output video for ffmpeg conversion video.")
|
logging.error("Missing output video for ffmpeg conversion video.")
|
||||||
@ -224,12 +217,6 @@ def join_audios(video_path: str, audio_tracks: List[Dict[str, str]], out_path: s
|
|||||||
capture_ffmpeg_real_time(ffmpeg_cmd, "[cyan]Join audio")
|
capture_ffmpeg_real_time(ffmpeg_cmd, "[cyan]Join audio")
|
||||||
print()
|
print()
|
||||||
|
|
||||||
# Check file output
|
|
||||||
if CHECK_OUTPUT_CONVERSION:
|
|
||||||
console.log("[red]Check output ffmpeg")
|
|
||||||
time.sleep(0.5)
|
|
||||||
check_ffmpeg_input(out_path)
|
|
||||||
|
|
||||||
time.sleep(0.5)
|
time.sleep(0.5)
|
||||||
if not check_file_existence(out_path):
|
if not check_file_existence(out_path):
|
||||||
logging.error("Missing output video for ffmpeg conversion audio.")
|
logging.error("Missing output video for ffmpeg conversion audio.")
|
||||||
@ -295,13 +282,6 @@ def join_subtitle(video_path: str, subtitles_list: List[Dict[str, str]], out_pat
|
|||||||
capture_ffmpeg_real_time(ffmpeg_cmd, "[cyan]Join subtitle")
|
capture_ffmpeg_real_time(ffmpeg_cmd, "[cyan]Join subtitle")
|
||||||
print()
|
print()
|
||||||
|
|
||||||
|
|
||||||
# Check file output
|
|
||||||
if CHECK_OUTPUT_CONVERSION:
|
|
||||||
console.log("[red]Check output ffmpeg")
|
|
||||||
time.sleep(0.5)
|
|
||||||
check_ffmpeg_input(out_path)
|
|
||||||
|
|
||||||
time.sleep(0.5)
|
time.sleep(0.5)
|
||||||
if not check_file_existence(out_path):
|
if not check_file_existence(out_path):
|
||||||
logging.error("Missing output video for ffmpeg conversion subtitle.")
|
logging.error("Missing output video for ffmpeg conversion subtitle.")
|
||||||
|
@ -74,6 +74,36 @@ def get_video_duration(file_path: str) -> float:
|
|||||||
logging.error(f"Error get video duration: {e}")
|
logging.error(f"Error get video duration: {e}")
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
|
|
||||||
|
def get_video_duration_s(filename):
|
||||||
|
"""
|
||||||
|
Get the duration of a video file using ffprobe.
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
- filename (str): Path to the video file (e.g., 'sim.mp4')
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
- duration (float): Duration of the video in seconds, or None if an error occurs.
|
||||||
|
"""
|
||||||
|
ffprobe_cmd = ['ffprobe', '-v', 'error', '-show_entries', 'format=duration', '-of', 'default=noprint_wrappers=1:nokey=1', filename]
|
||||||
|
|
||||||
|
try:
|
||||||
|
|
||||||
|
# Run ffprobe command and capture output
|
||||||
|
result = subprocess.run(ffprobe_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, check=True, text=True)
|
||||||
|
|
||||||
|
# Extract duration from the output
|
||||||
|
duration_str = result.stdout.strip()
|
||||||
|
duration = float(duration_str) # Convert duration to float
|
||||||
|
|
||||||
|
return int(duration)
|
||||||
|
|
||||||
|
except subprocess.CalledProcessError as e:
|
||||||
|
print(f"Error running ffprobe: {e}")
|
||||||
|
return None
|
||||||
|
except ValueError as e:
|
||||||
|
print(f"Error converting duration to float: {e}")
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
def format_duration(seconds: float) -> Tuple[int, int, int]:
|
def format_duration(seconds: float) -> Tuple[int, int, int]:
|
||||||
"""
|
"""
|
||||||
@ -104,16 +134,6 @@ def print_duration_table(file_path: str, description: str = "Duration", return_s
|
|||||||
Returns:
|
Returns:
|
||||||
- str: The formatted duration string if return_string is True.
|
- str: The formatted duration string if return_string is True.
|
||||||
- dict: A dictionary with keys 'h', 'm', 's' representing hours, minutes, and seconds if return_string is False.
|
- dict: A dictionary with keys 'h', 'm', 's' representing hours, minutes, and seconds if return_string is False.
|
||||||
|
|
||||||
Example usage:
|
|
||||||
>>> print_duration_table("path/to/video.mp4")
|
|
||||||
[cyan]Duration for [white]([green]video.mp4[white]): [yellow]1[red]h [yellow]1[red]m [yellow]1[red]s
|
|
||||||
|
|
||||||
>>> print_duration_table("path/to/video.mp4", description=None)
|
|
||||||
'[yellow]1[red]h [yellow]1[red]m [yellow]1[red]s'
|
|
||||||
|
|
||||||
>>> print_duration_table("path/to/video.mp4", description=None, return_string=False)
|
|
||||||
{'h': 1, 'm': 1, 's': 1}
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
video_duration = get_video_duration(file_path)
|
video_duration = get_video_duration(file_path)
|
||||||
@ -197,45 +217,6 @@ def need_to_force_to_ts(file_path):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def check_ffmpeg_input(input_file):
|
|
||||||
"""
|
|
||||||
Check if an input file can be processed by FFmpeg.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
input_file (str): Path to the input file.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
bool: True if the input file is valid and can be processed by FFmpeg, False otherwise.
|
|
||||||
"""
|
|
||||||
command = [
|
|
||||||
'ffmpeg', '-v', 'error', '-i', input_file, '-f', 'null', '-'
|
|
||||||
]
|
|
||||||
logging.info(f"FFmpeg command check: {command}")
|
|
||||||
|
|
||||||
try:
|
|
||||||
# Run the FFmpeg command and capture output
|
|
||||||
result = subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
|
||||||
|
|
||||||
# Check the exit status
|
|
||||||
if result.returncode != 0:
|
|
||||||
logging.error("FFmpeg encountered an error with the input file:")
|
|
||||||
logging.error(result.stderr.decode('utf-8'))
|
|
||||||
return False
|
|
||||||
|
|
||||||
# Optionally, you can analyze the output to check for specific errors
|
|
||||||
stderr_output = result.stderr.decode('utf-8')
|
|
||||||
if 'error' in stderr_output.lower():
|
|
||||||
logging.error("FFmpeg reported an error in the input file:")
|
|
||||||
logging.error(stderr_output)
|
|
||||||
return False
|
|
||||||
|
|
||||||
logging.info(f"Input file is valid: {input_file}")
|
|
||||||
return True
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
logging.error(f"An unexpected error occurred: {e}")
|
|
||||||
return False
|
|
||||||
|
|
||||||
def check_duration_v_a(video_path, audio_path):
|
def check_duration_v_a(video_path, audio_path):
|
||||||
"""
|
"""
|
||||||
Check if the duration of the video and audio matches.
|
Check if the duration of the video and audio matches.
|
||||||
|
@ -56,7 +56,7 @@ class M3U8_Ts_Estimator:
|
|||||||
self.ts_file_sizes.append(size)
|
self.ts_file_sizes.append(size)
|
||||||
self.now_downloaded_size += size_download
|
self.now_downloaded_size += size_download
|
||||||
|
|
||||||
def capture_speed(self, interval: float = 0.8):
|
def capture_speed(self, interval: float = 1):
|
||||||
"""
|
"""
|
||||||
Capture the internet speed periodically and store the values in a deque.
|
Capture the internet speed periodically and store the values in a deque.
|
||||||
"""
|
"""
|
||||||
|
@ -1,9 +1,20 @@
|
|||||||
# 23.06.24
|
# 23.06.24
|
||||||
|
|
||||||
|
# Fix import
|
||||||
|
import time
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
src_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))
|
||||||
|
sys.path.append(src_path)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Import
|
||||||
from Src.Lib.Downloader import HLS_Downloader
|
from Src.Lib.Downloader import HLS_Downloader
|
||||||
|
|
||||||
|
|
||||||
|
# Test
|
||||||
HLS_Downloader(
|
HLS_Downloader(
|
||||||
output_filename="EP_1.mp4",
|
output_filename=r".\EP_1.mp4",
|
||||||
m3u8_playlist=""
|
m3u8_playlist=""
|
||||||
)
|
).start()
|
@ -1,7 +1,19 @@
|
|||||||
# 23.06.24
|
# 23.06.24
|
||||||
|
|
||||||
|
# Fix import
|
||||||
|
import time
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
src_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))
|
||||||
|
sys.path.append(src_path)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Import
|
||||||
from Src.Lib.Downloader import MP4_downloader
|
from Src.Lib.Downloader import MP4_downloader
|
||||||
|
|
||||||
|
|
||||||
|
# Test
|
||||||
MP4_downloader(
|
MP4_downloader(
|
||||||
"",
|
"",
|
||||||
"EP_1.mp4"
|
"EP_1.mp4"
|
||||||
|
@ -1,7 +1,21 @@
|
|||||||
# 23.06.24
|
# 23.06.24
|
||||||
|
|
||||||
|
|
||||||
|
# Fix import
|
||||||
|
import time
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
src_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))
|
||||||
|
sys.path.append(src_path)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Import
|
||||||
from Src.Lib.Downloader import TOR_downloader
|
from Src.Lib.Downloader import TOR_downloader
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Test
|
||||||
manager = TOR_downloader()
|
manager = TOR_downloader()
|
||||||
|
|
||||||
magnet_link = "magnet:?x"
|
magnet_link = "magnet:?x"
|
||||||
|
@ -49,8 +49,7 @@
|
|||||||
"use_acodec": true,
|
"use_acodec": true,
|
||||||
"use_bitrate": true,
|
"use_bitrate": true,
|
||||||
"use_gpu": false,
|
"use_gpu": false,
|
||||||
"default_preset": "ultrafast",
|
"default_preset": "ultrafast"
|
||||||
"check_output_after_ffmpeg": false
|
|
||||||
},
|
},
|
||||||
"M3U8_PARSER": {
|
"M3U8_PARSER": {
|
||||||
"force_resolution": -1
|
"force_resolution": -1
|
||||||
|
Loading…
x
Reference in New Issue
Block a user