From 8f0e69c3de02a385ea387a14e8e8f146f8fe13a1 Mon Sep 17 00:00:00 2001 From: Jerry Yan <792602257@qq.com> Date: Mon, 24 Mar 2025 10:30:36 +0800 Subject: [PATCH 1/6] =?UTF-8?q?overall=5Fspeed=E7=89=87=E6=AE=B5=E5=85=A8?= =?UTF-8?q?=E5=B1=80=E5=8F=98=E9=80=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- entity/ffmpeg.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/entity/ffmpeg.py b/entity/ffmpeg.py index d296647..678573b 100644 --- a/entity/ffmpeg.py +++ b/entity/ffmpeg.py @@ -220,6 +220,15 @@ class FfmpegTask(object): # 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("ospeed:"): + param = effect.split(":", 2)[1] + if param == '': + param = "1" + if param != "1": + # 视频变速 + effect_index += 1 + filter_args.append(f"{video_output_str}setpts={param}*PTS[v_eff{effect_index}]") + video_output_str = f"[v_eff{effect_index}]" elif effect.startswith("zoom:"): ... ... From 7c6e4a97b2411fef6a5f480009ec5a378abaa327 Mon Sep 17 00:00:00 2001 From: Jerry Yan <792602257@qq.com> Date: Fri, 28 Mar 2025 17:26:49 +0800 Subject: [PATCH 2/6] =?UTF-8?q?=E7=89=87=E6=AE=B5=E6=9C=89=E9=9F=B3?= =?UTF-8?q?=E9=A2=91=E4=B8=8D=E5=8F=AF=E4=BB=A5copy?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- entity/ffmpeg.py | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/entity/ffmpeg.py b/entity/ffmpeg.py index 678573b..d765b70 100644 --- a/entity/ffmpeg.py +++ b/entity/ffmpeg.py @@ -141,7 +141,7 @@ class FfmpegTask(object): return False if self.speed != 1: return False - if len(self.audios) > 1: + if len(self.audios) >= 1: return False if len(self.input_file) > 1: return False @@ -277,16 +277,26 @@ class FfmpegTask(object): audio_output_str = "" audio_track_index = 0 # output_args - _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] - from util.ffmpeg import probe_video_audio - self.mute = not probe_video_audio(_tmp_file, "concat") + if len(self.input_file) == 1: + _file = self.input_file[0] + from util.ffmpeg import probe_video_audio + if type(_file) is str: + input_args += ["-i", _file] + self.mute = not probe_video_audio(_file) + elif isinstance(_file, FfmpegTask): + input_args += ["-i", _file.get_output_file()] + self.mute = not probe_video_audio(_file.get_output_file()) + else: + _tmp_file = "tmp_concat_" + str(time.time()) + ".txt" + from util.ffmpeg import probe_video_audio + 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] + self.mute = not probe_video_audio(_tmp_file, "concat") output_args.append("-map") output_args.append("0:v") output_args.append("-c:v") From b25ad20dddfdd58c97850e4383e5639501943c9e Mon Sep 17 00:00:00 2001 From: Jerry Yan <792602257@qq.com> Date: Fri, 28 Mar 2025 17:27:24 +0800 Subject: [PATCH 3/6] =?UTF-8?q?=E6=97=A5=E5=BF=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- util/ffmpeg.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/util/ffmpeg.py b/util/ffmpeg.py index 4a3fe59..7e665cb 100644 --- a/util/ffmpeg.py +++ b/util/ffmpeg.py @@ -51,6 +51,7 @@ def re_encode_and_annexb(file): *AUDIO_ARGS, "-bsf:a", "setts=pts=DTS", *ENCODER_ARGS, "-shortest", "-f", "mpegts", file + ".ts"]) + logger.info(" ".join(ffmpeg_process.args)) span.set_attribute("ffmpeg.args", json.dumps(ffmpeg_process.args)) logger.info("ReEncodeAndAnnexb: %s, returned: %s", file, ffmpeg_process.returncode) span.set_attribute("ffmpeg.code", ffmpeg_process.returncode) @@ -67,7 +68,6 @@ def start_render(ffmpeg_task: FfmpegTask): tracer = get_tracer(__name__) with tracer.start_as_current_span("start_render") as span: span.set_attribute("ffmpeg.task", str(ffmpeg_task)) - logger.info(ffmpeg_task) if not ffmpeg_task.need_run(): ffmpeg_task.set_output_file(ffmpeg_task.input_file[0]) span.set_status(Status(StatusCode.OK)) @@ -79,7 +79,7 @@ def start_render(ffmpeg_task: FfmpegTask): return True ffmpeg_process = subprocess.run(["ffmpeg", "-progress", "-", "-loglevel", "error", *ffmpeg_args], **subprocess_args(True)) span.set_attribute("ffmpeg.args", json.dumps(ffmpeg_process.args)) - logger.info(ffmpeg_process.args) + logger.info(" ".join(ffmpeg_process.args)) ffmpeg_final_out = handle_ffmpeg_output(ffmpeg_process.stdout) span.set_attribute("ffmpeg.out", ffmpeg_final_out) logger.info("FINISH TASK, OUTPUT IS %s", ffmpeg_final_out) @@ -167,6 +167,7 @@ def probe_video_audio(video_file, type=None): args.append("-f") args.append("concat") args.append(video_file) + logger.info(" ".join(args)) result = subprocess.run(args, stderr=subprocess.STDOUT, **subprocess_args(True)) span.set_attribute("ffprobe.args", json.dumps(result.args)) span.set_attribute("ffprobe.code", result.returncode) From 52c2df8b65c7146849c27859795711a3e88232af Mon Sep 17 00:00:00 2001 From: Jerry Yan <792602257@qq.com> Date: Fri, 28 Mar 2025 17:30:28 +0800 Subject: [PATCH 4/6] =?UTF-8?q?=E5=88=A0=E9=99=A4=E6=97=A0=E7=94=A8?= =?UTF-8?q?=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- util/ffmpeg.py | 25 ------------------------- 1 file changed, 25 deletions(-) diff --git a/util/ffmpeg.py b/util/ffmpeg.py index 7e665cb..8684cd3 100644 --- a/util/ffmpeg.py +++ b/util/ffmpeg.py @@ -12,31 +12,6 @@ from telemetry import get_tracer logger = logging.getLogger(__name__) -def to_annexb(file): - with get_tracer("ffmpeg").start_as_current_span("to_annexb") as span: - span.set_attribute("file.path", file) - if not os.path.exists(file): - span.set_status(Status(StatusCode.ERROR)) - return file - logger.info("ToAnnexb: %s", file) - ffmpeg_process = subprocess.run(["ffmpeg", "-y", "-hide_banner", "-i", file, - *MUTE_AUDIO_INPUT, - "-map", "0:v", "-map", "1:a", - "-c:v", "copy", "-bsf:v", "h264_mp4toannexb", "-shortest", - "-c:a", "aac", "-b:a", "128k", "-ar", "48000", "-ac", "2", - "-f", "mpegts", file+".ts"]) - span.set_attribute("ffmpeg.args", json.dumps(ffmpeg_process.args)) - logger.info("ToAnnexb: %s, returned: %s", file, ffmpeg_process.returncode) - span.set_attribute("ffmpeg.code", ffmpeg_process.returncode) - if ffmpeg_process.returncode == 0: - span.set_status(Status(StatusCode.OK)) - span.set_attribute("file.size", os.path.getsize(file+".ts")) - os.remove(file) - return file+".ts" - else: - span.set_status(Status(StatusCode.ERROR)) - return file - def re_encode_and_annexb(file): with get_tracer("ffmpeg").start_as_current_span("re_encode_and_annexb") as span: span.set_attribute("file.path", file) From 09e0f5f3be16ec49f8b89fff35954a5cede74af5 Mon Sep 17 00:00:00 2001 From: Jerry Yan <792602257@qq.com> Date: Fri, 28 Mar 2025 18:07:57 +0800 Subject: [PATCH 5/6] =?UTF-8?q?concat=E6=94=AF=E6=8C=81annexb?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- entity/ffmpeg.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/entity/ffmpeg.py b/entity/ffmpeg.py index d765b70..1d6bb51 100644 --- a/entity/ffmpeg.py +++ b/entity/ffmpeg.py @@ -323,8 +323,13 @@ class FfmpegTask(object): else: output_args.append(audio_output_str) output_args += AUDIO_ARGS + if self.annexb: + output_args.append("-bsf:v") + output_args.append("h264_mp4toannexb") + output_args.append("-bsf:a") + output_args.append("setts=pts=DTS") output_args.append("-f") - output_args.append("mp4") + output_args.append("mpegts" if self.annexb else "mp4") _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 == 'copy': From 6e4dbfd8439e5e5568ab7a0a9e046d23ab89dfdc Mon Sep 17 00:00:00 2001 From: Jerry Yan <792602257@qq.com> Date: Fri, 28 Mar 2025 18:08:19 +0800 Subject: [PATCH 6/6] =?UTF-8?q?=E5=9B=BA=E5=AE=9A=E6=A8=A1=E6=9D=BF?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E9=9F=B3=E4=B9=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- util/ffmpeg.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/util/ffmpeg.py b/util/ffmpeg.py index 8684cd3..4c0efb1 100644 --- a/util/ffmpeg.py +++ b/util/ffmpeg.py @@ -19,12 +19,13 @@ def re_encode_and_annexb(file): span.set_status(Status(StatusCode.ERROR)) return file logger.info("ReEncodeAndAnnexb: %s", file) - ffmpeg_process = subprocess.run(["ffmpeg", "-y", "-hide_banner", "-i", file, - *MUTE_AUDIO_INPUT, - "-map", "0:v", "-map", "1:a", + has_audio = not not probe_video_audio(file) + ffmpeg_process = subprocess.run(["ffmpeg", "-y", "-hide_banner", "-vsync", "cfr", "-i", file, + *(set() if has_audio else MUTE_AUDIO_INPUT), + "-map", "0:v", "-map", "0:a" if has_audio else "1:a", *VIDEO_ARGS, "-bsf:v", "h264_mp4toannexb", *AUDIO_ARGS, "-bsf:a", "setts=pts=DTS", - *ENCODER_ARGS, "-shortest", + *ENCODER_ARGS, "-shortest", "-fflags", "+genpts", "-f", "mpegts", file + ".ts"]) logger.info(" ".join(ffmpeg_process.args)) span.set_attribute("ffmpeg.args", json.dumps(ffmpeg_process.args)) @@ -33,7 +34,7 @@ def re_encode_and_annexb(file): if ffmpeg_process.returncode == 0: span.set_status(Status(StatusCode.OK)) span.set_attribute("file.size", os.path.getsize(file+".ts")) - os.remove(file) + # os.remove(file) return file+".ts" else: span.set_status(Status(StatusCode.ERROR))