Merge branch 'master' into windows_nvidia
# Conflicts: # entity/ffmpeg.py
This commit is contained in:
commit
f12422b346
@ -45,6 +45,7 @@ def parse_ffmpeg_task(task_info, template_info):
|
|||||||
output_file = "out_" + str(time.time()) + ".mp4"
|
output_file = "out_" + str(time.time()) + ".mp4"
|
||||||
task = FfmpegTask(tasks, output_file=output_file)
|
task = FfmpegTask(tasks, output_file=output_file)
|
||||||
overall = template_info.get("overall_template")
|
overall = template_info.get("overall_template")
|
||||||
|
task.mute = False
|
||||||
task.center_cut = template_info.get("crop_mode", None)
|
task.center_cut = template_info.get("crop_mode", None)
|
||||||
task.frame_rate = template_info.get("frame_rate", 25)
|
task.frame_rate = template_info.get("frame_rate", 25)
|
||||||
if overall.get('source', ''):
|
if overall.get('source', ''):
|
||||||
|
188
entity/ffmpeg.py
188
entity/ffmpeg.py
@ -1,9 +1,13 @@
|
|||||||
import json
|
import json
|
||||||
import time
|
import time
|
||||||
import uuid
|
import uuid
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
DEFAULT_ARGS = ("-shortest",)
|
||||||
ENCODER_ARGS = ("-c:v", "h264_nvenc", "-cq:v", "24", "-preset:v", "p7", "-tune:v", "hq",)
|
ENCODER_ARGS = ("-c:v", "h264_nvenc", "-cq:v", "24", "-preset:v", "p7", "-tune:v", "hq",)
|
||||||
PROFILE_LEVEL_ARGS = ("-profile:v", "high", "-level:v", "4")
|
VIDEO_ARGS = ("-profile:v", "high", "-level:v", "4", )
|
||||||
|
AUDIO_ARGS = ("-c:a", "aac", "-b:a", "128k", "-ar", "48000", "-ac", "2", )
|
||||||
|
MUTE_AUDIO_INPUT = ("-f", "lavfi", "-i", "anullsrc=cl=stereo:r=48000", )
|
||||||
|
|
||||||
|
|
||||||
class FfmpegTask(object):
|
class FfmpegTask(object):
|
||||||
@ -148,23 +152,22 @@ class FfmpegTask(object):
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
def check_audio_track(self):
|
def check_audio_track(self):
|
||||||
if len(self.audios) > 0:
|
...
|
||||||
self.mute = False
|
|
||||||
|
|
||||||
def get_ffmpeg_args(self):
|
def get_ffmpeg_args(self):
|
||||||
args = ['-y', '-hide_banner']
|
args = ['-y', '-hide_banner']
|
||||||
if self.task_type == 'encode':
|
if self.task_type == 'encode':
|
||||||
input_args = []
|
input_args = []
|
||||||
filter_args = []
|
filter_args = []
|
||||||
output_args = [*PROFILE_LEVEL_ARGS,"-shortest", *ENCODER_ARGS]
|
output_args = [*VIDEO_ARGS, *AUDIO_ARGS, *ENCODER_ARGS, *DEFAULT_ARGS]
|
||||||
if self.annexb:
|
if self.annexb:
|
||||||
output_args.append("-bsf:v")
|
output_args.append("-bsf:v")
|
||||||
output_args.append("h264_mp4toannexb")
|
output_args.append("h264_mp4toannexb")
|
||||||
output_args.append("-reset_timestamps")
|
output_args.append("-reset_timestamps")
|
||||||
output_args.append("1")
|
output_args.append("1")
|
||||||
video_output_str = "[0:v]"
|
video_output_str = "[0:v]"
|
||||||
audio_output_str = "[0:v]"
|
audio_output_str = ""
|
||||||
audio_input_count = 0
|
effect_index = 0
|
||||||
for input_file in self.input_file:
|
for input_file in self.input_file:
|
||||||
input_args.append("-i")
|
input_args.append("-i")
|
||||||
if type(input_file) is str:
|
if type(input_file) is str:
|
||||||
@ -178,28 +181,44 @@ class FfmpegTask(object):
|
|||||||
_f_x = pos_json.get('ltX', 0)
|
_f_x = pos_json.get('ltX', 0)
|
||||||
_f_x2 = pos_json.get('rbX', 0)
|
_f_x2 = pos_json.get('rbX', 0)
|
||||||
_x = f'{float((_f_x2 - _f_x)/(2 * _v_w)) :.4f}*iw'
|
_x = f'{float((_f_x2 - _f_x)/(2 * _v_w)) :.4f}*iw'
|
||||||
filter_args.append(f"{video_output_str}crop=x={_x}:y=0:w=ih*ih/iw:h=ih[v_cut]")
|
filter_args.append(f"{video_output_str}crop=x={_x}:y=0:w=ih*ih/iw:h=ih[v_cut{effect_index}]")
|
||||||
video_output_str = "[v_cut]"
|
video_output_str = f"[v_cut{effect_index}]"
|
||||||
|
effect_index += 1
|
||||||
for effect in self.effects:
|
for effect in self.effects:
|
||||||
if effect.startswith("cameraShot:"):
|
if effect.startswith("cameraShot:"):
|
||||||
param = effect.split(":", 2)[1]
|
param = effect.split(":", 2)[1]
|
||||||
if param == '':
|
if param == '':
|
||||||
param = "3,1"
|
param = "3,1,0"
|
||||||
_split = param.split(",")
|
_split = param.split(",")
|
||||||
start = 3
|
start = 3
|
||||||
duration = 1
|
duration = 1
|
||||||
|
rotate_deg = 0
|
||||||
|
if len(_split) >= 3:
|
||||||
|
if _split[2] == '':
|
||||||
|
rotate_deg = 0
|
||||||
|
else:
|
||||||
|
rotate_deg = int(_split[2])
|
||||||
if len(_split) >= 2:
|
if len(_split) >= 2:
|
||||||
start = int(_split[0])
|
duration = float(_split[1])
|
||||||
duration = int(_split[1])
|
if len(_split) >= 1:
|
||||||
elif len(_split) == 1:
|
start = float(_split[0])
|
||||||
start = int(_split[0])
|
|
||||||
_start_out_str = "[eff_s]"
|
_start_out_str = "[eff_s]"
|
||||||
|
_mid_out_str = "[eff_m]"
|
||||||
_end_out_str = "[eff_e]"
|
_end_out_str = "[eff_e]"
|
||||||
filter_args.append(f"{video_output_str}fps=fps={self.frame_rate},split{_start_out_str}{_end_out_str}")
|
filter_args.append(f"{video_output_str}split=3{_start_out_str}{_mid_out_str}{_end_out_str}")
|
||||||
filter_args.append(f"{_start_out_str}trim=start={0}:end={start+duration},freezeframes=first={start*self.frame_rate}:replace={start*self.frame_rate}{_start_out_str}")
|
filter_args.append(f"{_start_out_str}select=lt(n\,{int(start*self.frame_rate)}){_start_out_str}")
|
||||||
filter_args.append(f"{_end_out_str}trim=start={start}{_end_out_str}")
|
filter_args.append(f"{_end_out_str}select=gt(n\,{int(start*self.frame_rate)}){_end_out_str}")
|
||||||
video_output_str = "[v_eff]"
|
filter_args.append(f"{_mid_out_str}select=eq(n\,{int(start*self.frame_rate)}){_mid_out_str}")
|
||||||
filter_args.append(f"{_start_out_str}{_end_out_str}concat=n=2:v=1:a=0{video_output_str}")
|
filter_args.append(f"{_mid_out_str}tpad=start_mode=clone:start_duration={duration:.4f}{_mid_out_str}")
|
||||||
|
if rotate_deg != 0:
|
||||||
|
filter_args.append(f"{_mid_out_str}rotate=PI*{rotate_deg}/360{_mid_out_str}")
|
||||||
|
# filter_args.append(f"{video_output_str}trim=start=0:end={start+duration},tpad=stop_mode=clone:stop_duration={duration},setpts=PTS-STARTPTS{_start_out_str}")
|
||||||
|
# filter_args.append(f"tpad=start_mode=clone:start_duration={duration},setpts=PTS-STARTPTS{_start_out_str}")
|
||||||
|
# filter_args.append(f"{_end_out_str}trim=start={start}{_end_out_str}")
|
||||||
|
video_output_str = f"[v_eff{effect_index}]"
|
||||||
|
# filter_args.append(f"{_end_out_str}{_start_out_str}overlay=eof_action=pass{video_output_str}")
|
||||||
|
filter_args.append(f"{_start_out_str}{_mid_out_str}{_end_out_str}concat=n=3:v=1:a=0,setpts=N/{self.frame_rate}/TB{video_output_str}")
|
||||||
|
effect_index += 1
|
||||||
elif effect.startswith("zoom:"):
|
elif effect.startswith("zoom:"):
|
||||||
...
|
...
|
||||||
...
|
...
|
||||||
@ -220,90 +239,73 @@ class FfmpegTask(object):
|
|||||||
output_args.append("-r")
|
output_args.append("-r")
|
||||||
output_args.append(f"{self.frame_rate}")
|
output_args.append(f"{self.frame_rate}")
|
||||||
if self.mute:
|
if self.mute:
|
||||||
output_args.append("-an")
|
input_index = input_args.count("-i")
|
||||||
|
input_args += MUTE_AUDIO_INPUT
|
||||||
|
filter_args.append(f"[{input_index}:a]acopy[a]")
|
||||||
|
audio_output_str = "[a]"
|
||||||
else:
|
else:
|
||||||
input_index = 0
|
audio_output_str = "[0:a]"
|
||||||
for audio in self.audios:
|
for audio in self.audios:
|
||||||
input_index = input_args.count("-i")
|
input_index = input_args.count("-i")
|
||||||
input_args.append("-i")
|
input_args.append("-i")
|
||||||
input_args.append(audio.replace("\\", "/"))
|
input_args.append(audio.replace("\\", "/"))
|
||||||
if audio_input_count > 0:
|
if audio_output_str == "":
|
||||||
filter_args.append(f"{audio_output_str}[{input_index}:a]amix[a]")
|
filter_args.append(f"[{input_index}:a]acopy[a]")
|
||||||
audio_output_str = "[a]"
|
audio_output_str = "[a]"
|
||||||
else:
|
else:
|
||||||
audio_output_str = f"[{input_index}:a]"
|
filter_args.append(f"{audio_output_str}[{input_index}:a]amix[a]")
|
||||||
audio_input_count += 1
|
audio_output_str = "[a]"
|
||||||
if audio_input_count == 1:
|
if audio_output_str:
|
||||||
audio_output_str = f"{input_index}"
|
output_args.append("-map")
|
||||||
output_args.append(f"-map")
|
|
||||||
output_args.append(audio_output_str)
|
output_args.append(audio_output_str)
|
||||||
return args + input_args + ["-filter_complex", ";".join(filter_args)] + output_args + [self.get_output_file()]
|
_filter_args = [] if len(filter_args) == 0 else ["-filter_complex", ";".join(filter_args)]
|
||||||
|
return args + input_args + _filter_args + output_args + [self.get_output_file()]
|
||||||
elif self.task_type == 'concat':
|
elif self.task_type == 'concat':
|
||||||
# 无法通过 annexb 合并的
|
# 无法通过 annexb 合并的
|
||||||
input_args = []
|
input_args = []
|
||||||
output_args = ["-shortest"]
|
output_args = [*DEFAULT_ARGS]
|
||||||
if self.check_annexb() and len(self.audios) <= 1:
|
|
||||||
# output_args
|
|
||||||
if len(self.audios) > 0:
|
|
||||||
input_args.append("-an")
|
|
||||||
_tmp_file = "tmp_concat_"+str(time.time())+".txt"
|
|
||||||
with open(_tmp_file, "w", encoding="utf-8") as f:
|
|
||||||
for input_file in self.input_file:
|
|
||||||
if type(input_file) is str:
|
|
||||||
f.write("file '"+input_file+"'\n")
|
|
||||||
elif isinstance(input_file, FfmpegTask):
|
|
||||||
f.write("file '" + input_file.get_output_file() + "'\n")
|
|
||||||
input_args += ("-f", "concat", "-safe", "0", "-i", _tmp_file)
|
|
||||||
output_args.append("-c:v")
|
|
||||||
output_args.append("copy")
|
|
||||||
if len(self.audios) > 0:
|
|
||||||
input_args.append("-i")
|
|
||||||
input_args.append(self.audios[0])
|
|
||||||
output_args.append("-c:a")
|
|
||||||
output_args.append("copy")
|
|
||||||
output_args.append("-f")
|
|
||||||
output_args.append("mp4")
|
|
||||||
return args + input_args + output_args + [self.get_output_file()]
|
|
||||||
output_args += ["-r", f"{self.frame_rate}", *PROFILE_LEVEL_ARGS, *ENCODER_ARGS]
|
|
||||||
filter_args = []
|
filter_args = []
|
||||||
video_output_str = "[0:v]"
|
audio_output_str = ""
|
||||||
audio_output_str = "[0:a]"
|
audio_track_index = 0
|
||||||
video_input_count = 0
|
# output_args
|
||||||
audio_input_count = 0
|
_tmp_file = "tmp_concat_"+str(time.time())+".txt"
|
||||||
for input_file in self.input_file:
|
with open(_tmp_file, "w", encoding="utf-8") as f:
|
||||||
|
for input_file in self.input_file:
|
||||||
|
if type(input_file) is str:
|
||||||
|
f.write("file '"+input_file+"'\n")
|
||||||
|
elif isinstance(input_file, FfmpegTask):
|
||||||
|
f.write("file '" + input_file.get_output_file() + "'\n")
|
||||||
|
input_args += ["-f", "concat", "-safe", "0", "-i", _tmp_file]
|
||||||
|
output_args.append("-map")
|
||||||
|
output_args.append("0:v")
|
||||||
|
output_args.append("-c:v")
|
||||||
|
output_args.append("copy")
|
||||||
|
if self.mute:
|
||||||
|
input_index = input_args.count("-i")
|
||||||
|
input_args += MUTE_AUDIO_INPUT
|
||||||
|
audio_output_str = f"[{input_index}:a]"
|
||||||
|
audio_track_index += 1
|
||||||
|
else:
|
||||||
|
audio_output_str = "[0:a]"
|
||||||
|
audio_track_index += 1
|
||||||
|
for audio in self.audios:
|
||||||
input_index = input_args.count("-i")
|
input_index = input_args.count("-i")
|
||||||
input_args.append("-i")
|
input_args.append("-i")
|
||||||
if type(input_file) is str:
|
input_args.append(audio.replace("\\", "/"))
|
||||||
input_args.append(input_file.replace("\\", "/"))
|
audio_track_index += 1
|
||||||
elif isinstance(input_file, FfmpegTask):
|
filter_args.append(f"{audio_output_str}[{input_index}:a]amix[a]")
|
||||||
input_args.append(input_file.get_output_file().replace("\\", "/"))
|
audio_output_str = "[a]"
|
||||||
if video_input_count > 0:
|
if audio_output_str:
|
||||||
filter_args.append(f"{video_output_str}[{input_index}:v]concat=n=2:v=1:a=0[v]")
|
output_args.append("-map")
|
||||||
video_output_str = "[v]"
|
if audio_track_index <= 1:
|
||||||
|
output_args.append(audio_output_str[1:-1])
|
||||||
else:
|
else:
|
||||||
video_output_str = f"[{input_index}:v]"
|
output_args.append(audio_output_str)
|
||||||
video_input_count += 1
|
output_args += AUDIO_ARGS
|
||||||
output_args.append("-map")
|
output_args.append("-f")
|
||||||
output_args.append(video_output_str)
|
output_args.append("mp4")
|
||||||
if self.mute:
|
_filter_args = [] if len(filter_args) == 0 else ["-filter_complex", ";".join(filter_args)]
|
||||||
output_args.append("-an")
|
return args + input_args + _filter_args + output_args + [self.get_output_file()]
|
||||||
else:
|
|
||||||
input_index = 0
|
|
||||||
for audio in self.audios:
|
|
||||||
input_index = input_args.count("-i")
|
|
||||||
input_args.append("-i")
|
|
||||||
input_args.append(audio.replace("\\", "/"))
|
|
||||||
if audio_input_count > 0:
|
|
||||||
filter_args.append(f"{audio_output_str}[{input_index}:a]amix[a]")
|
|
||||||
audio_output_str = "[a]"
|
|
||||||
else:
|
|
||||||
audio_output_str = f"[{input_index}:a]"
|
|
||||||
audio_input_count += 1
|
|
||||||
if audio_input_count == 1:
|
|
||||||
audio_output_str = f"{input_index}"
|
|
||||||
output_args.append(f"-map")
|
|
||||||
output_args.append(audio_output_str)
|
|
||||||
return args + input_args + ["-filter_complex", ";".join(filter_args)] + output_args + [self.get_output_file()]
|
|
||||||
elif self.task_type == 'copy':
|
elif self.task_type == 'copy':
|
||||||
if len(self.input_file) == 1:
|
if len(self.input_file) == 1:
|
||||||
if type(self.input_file[0]) is str:
|
if type(self.input_file[0]) is str:
|
||||||
|
@ -5,7 +5,7 @@ import subprocess
|
|||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from typing import Optional, IO
|
from typing import Optional, IO
|
||||||
|
|
||||||
from entity.ffmpeg import FfmpegTask, ENCODER_ARGS, PROFILE_LEVEL_ARGS
|
from entity.ffmpeg import FfmpegTask, ENCODER_ARGS, VIDEO_ARGS, AUDIO_ARGS
|
||||||
from telemetry import get_tracer
|
from telemetry import get_tracer
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
@ -34,7 +34,7 @@ def re_encode_and_annexb(file):
|
|||||||
if not os.path.exists(file):
|
if not os.path.exists(file):
|
||||||
return file
|
return file
|
||||||
logger.info("ReEncodeAndAnnexb: %s", file)
|
logger.info("ReEncodeAndAnnexb: %s", file)
|
||||||
ffmpeg_process = subprocess.run(["ffmpeg", "-y", "-hide_banner", "-i", file, *PROFILE_LEVEL_ARGS, *ENCODER_ARGS, "-bsf:v", "h264_mp4toannexb",
|
ffmpeg_process = subprocess.run(["ffmpeg", "-y", "-hide_banner", "-i", file, *VIDEO_ARGS, *AUDIO_ARGS, *ENCODER_ARGS, "-bsf:v", "h264_mp4toannexb",
|
||||||
"-f", "mpegts", file +".ts"])
|
"-f", "mpegts", file +".ts"])
|
||||||
span.set_attribute("ffmpeg.args", json.dumps(ffmpeg_process.args))
|
span.set_attribute("ffmpeg.args", json.dumps(ffmpeg_process.args))
|
||||||
logger.info("ReEncodeAndAnnexb: %s, returned: %s", file, ffmpeg_process.returncode)
|
logger.info("ReEncodeAndAnnexb: %s, returned: %s", file, ffmpeg_process.returncode)
|
||||||
@ -55,12 +55,12 @@ def start_render(ffmpeg_task: FfmpegTask):
|
|||||||
ffmpeg_task.set_output_file(ffmpeg_task.input_file[0])
|
ffmpeg_task.set_output_file(ffmpeg_task.input_file[0])
|
||||||
return True
|
return True
|
||||||
ffmpeg_args = ffmpeg_task.get_ffmpeg_args()
|
ffmpeg_args = ffmpeg_task.get_ffmpeg_args()
|
||||||
logger.info(ffmpeg_args)
|
|
||||||
if len(ffmpeg_args) == 0:
|
if len(ffmpeg_args) == 0:
|
||||||
ffmpeg_task.set_output_file(ffmpeg_task.input_file[0])
|
ffmpeg_task.set_output_file(ffmpeg_task.input_file[0])
|
||||||
return True
|
return True
|
||||||
ffmpeg_process = subprocess.run(["ffmpeg", "-progress", "-", "-loglevel", "error", *ffmpeg_args], **subprocess_args(True))
|
ffmpeg_process = subprocess.run(["ffmpeg", "-progress", "-", "-loglevel", "error", *ffmpeg_args], **subprocess_args(True))
|
||||||
span.set_attribute("ffmpeg.args", json.dumps(ffmpeg_process.args))
|
span.set_attribute("ffmpeg.args", json.dumps(ffmpeg_process.args))
|
||||||
|
logger.info(ffmpeg_process.args)
|
||||||
ffmpeg_final_out = handle_ffmpeg_output(ffmpeg_process.stdout)
|
ffmpeg_final_out = handle_ffmpeg_output(ffmpeg_process.stdout)
|
||||||
span.set_attribute("ffmpeg.out", ffmpeg_final_out)
|
span.set_attribute("ffmpeg.out", ffmpeg_final_out)
|
||||||
logger.info("FINISH TASK, OUTPUT IS %s", ffmpeg_final_out)
|
logger.info("FINISH TASK, OUTPUT IS %s", ffmpeg_final_out)
|
||||||
|
41
util/oss.py
41
util/oss.py
@ -22,8 +22,9 @@ def upload_to_oss(url, file_path):
|
|||||||
max_retries = 5
|
max_retries = 5
|
||||||
retries = 0
|
retries = 0
|
||||||
while retries < max_retries:
|
while retries < max_retries:
|
||||||
try:
|
with tracer.start_as_current_span("upload_to_oss.request") as req_span:
|
||||||
with tracer.start_as_current_span("upload_to_oss.request") as req_span:
|
req_span.set_attribute("http.retry_count", retries)
|
||||||
|
try:
|
||||||
req_span.set_attribute("http.method", "PUT")
|
req_span.set_attribute("http.method", "PUT")
|
||||||
req_span.set_attribute("http.url", url)
|
req_span.set_attribute("http.url", url)
|
||||||
with open(file_path, 'rb') as f:
|
with open(file_path, 'rb') as f:
|
||||||
@ -31,13 +32,14 @@ def upload_to_oss(url, file_path):
|
|||||||
req_span.set_attribute("http.status_code", response.status_code)
|
req_span.set_attribute("http.status_code", response.status_code)
|
||||||
if response.status_code == 200:
|
if response.status_code == 200:
|
||||||
return True
|
return True
|
||||||
except requests.exceptions.Timeout:
|
except requests.exceptions.Timeout:
|
||||||
retries += 1
|
req_span.set_attribute("http.error", "Timeout")
|
||||||
logger.warning(f"Upload timed out. Retrying {retries}/{max_retries}...")
|
retries += 1
|
||||||
except Exception as e:
|
logger.warning(f"Upload timed out. Retrying {retries}/{max_retries}...")
|
||||||
retries += 1
|
except Exception as e:
|
||||||
span.set_attribute("oss.error", str(e))
|
req_span.set_attribute("http.error", str(e))
|
||||||
logger.warning(f"Upload failed. Retrying {retries}/{max_retries}...")
|
retries += 1
|
||||||
|
logger.warning(f"Upload failed. Retrying {retries}/{max_retries}...")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
@ -60,20 +62,23 @@ def download_from_oss(url, file_path):
|
|||||||
max_retries = 5
|
max_retries = 5
|
||||||
retries = 0
|
retries = 0
|
||||||
while retries < max_retries:
|
while retries < max_retries:
|
||||||
try:
|
with tracer.start_as_current_span("download_from_oss.request") as req_span:
|
||||||
with tracer.start_as_current_span("download_from_oss.request") as req_span:
|
req_span.set_attribute("http.retry_count", retries)
|
||||||
|
try:
|
||||||
req_span.set_attribute("http.method", "GET")
|
req_span.set_attribute("http.method", "GET")
|
||||||
req_span.set_attribute("http.url", url)
|
req_span.set_attribute("http.url", url)
|
||||||
response = requests.get(url, timeout=15) # 设置超时时间
|
response = requests.get(url, timeout=15) # 设置超时时间
|
||||||
req_span.set_attribute("http.status_code", response.status_code)
|
req_span.set_attribute("http.status_code", response.status_code)
|
||||||
with open(file_path, 'wb') as f:
|
with open(file_path, 'wb') as f:
|
||||||
f.write(response.content)
|
f.write(response.content)
|
||||||
|
span.set_attribute("file.size", os.path.getsize(file_path))
|
||||||
return True
|
return True
|
||||||
except requests.exceptions.Timeout:
|
except requests.exceptions.Timeout:
|
||||||
retries += 1
|
span.set_attribute("http.error", "Timeout")
|
||||||
logger.warning(f"Download timed out. Retrying {retries}/{max_retries}...")
|
retries += 1
|
||||||
except Exception as e:
|
logger.warning(f"Download timed out. Retrying {retries}/{max_retries}...")
|
||||||
retries += 1
|
except Exception as e:
|
||||||
span.set_attribute("oss.error", str(e))
|
span.set_attribute("http.error", str(e))
|
||||||
logger.warning(f"Download failed. Retrying {retries}/{max_retries}...")
|
retries += 1
|
||||||
|
logger.warning(f"Download failed. Retrying {retries}/{max_retries}...")
|
||||||
return False
|
return False
|
||||||
|
Loading…
x
Reference in New Issue
Block a user