diff --git a/biz/ffmpeg.py b/biz/ffmpeg.py index d7d9e4d..340211e 100644 --- a/biz/ffmpeg.py +++ b/biz/ffmpeg.py @@ -8,6 +8,7 @@ from entity.ffmpeg import FfmpegTask import logging from util import ffmpeg, oss +from util.ffmpeg import fade_out_audio from telemetry import get_tracer logger = logging.getLogger('biz/ffmpeg') diff --git a/biz/task.py b/biz/task.py index 2e2cc49..0cacded 100644 --- a/biz/task.py +++ b/biz/task.py @@ -2,7 +2,7 @@ import json from opentelemetry.trace import Status, StatusCode -from biz.ffmpeg import parse_ffmpeg_task, start_ffmpeg_task, clear_task_tmp_file, probe_video_info +from biz.ffmpeg import parse_ffmpeg_task, start_ffmpeg_task, clear_task_tmp_file, probe_video_info, fade_out_audio from telemetry import get_tracer from template import get_template_def from util import api @@ -20,12 +20,15 @@ def start_task(task_info): if not result: span.set_status(Status(StatusCode.ERROR)) return api.report_task_failed(task_info) + width, height, duration = probe_video_info(ffmpeg_task) + # 音频淡出 + new_fn = fade_out_audio(ffmpeg_task.get_output_file(), duration) + ffmpeg_task.set_output_file(new_fn) oss_result = api.upload_task_file(task_info, ffmpeg_task) if not oss_result: span.set_status(Status(StatusCode.ERROR)) return api.report_task_failed(task_info) # 获取视频长度宽度和时长 - width, height, duration = probe_video_info(ffmpeg_task) clear_task_tmp_file(ffmpeg_task) api.report_task_success(task_info, videoInfo={ "width": width, diff --git a/util/api.py b/util/api.py index b2d31a4..51ffeaa 100644 --- a/util/api.py +++ b/util/api.py @@ -189,7 +189,9 @@ def report_task_start(task_info): def report_task_failed(task_info, reason=''): tracer = get_tracer(__name__) - with tracer.start_as_current_span("report_task_failed"): + with tracer.start_as_current_span("report_task_failed") as span: + span.set_attribute("task_id", task_info.get("id")) + span.set_attribute("reason", reason) with tracer.start_as_current_span("report_task_failed.request") as req_span: try: req_span.set_attribute("http.method", "POST") diff --git a/util/ffmpeg.py b/util/ffmpeg.py index 4c0efb1..f2068aa 100644 --- a/util/ffmpeg.py +++ b/util/ffmpeg.py @@ -154,6 +154,43 @@ def probe_video_audio(video_file, type=None): return False return True + +# 音频淡出2秒 +def fade_out_audio(file, duration, fade_out_sec = 2): + if type(duration) == str: + try: + duration = float(duration) + except Exception as e: + logger.error("duration is not float: %s", e) + return file + tracer = get_tracer(__name__) + with tracer.start_as_current_span("fade_out_audio") as span: + span.set_attribute("audio.file", file) + if duration <= fade_out_sec: + return file + else: + new_fn = file + "_.mp4" + if os.path.exists(new_fn): + os.remove(new_fn) + logger.info("delete tmp file: " + new_fn) + try: + process = subprocess.run(["ffmpeg", "-i", file, "-c:v", "copy", "-c:a", "aac", "-af", "afade=t=out:st=" + str(duration - fade_out_sec) + ":d=" + str(fade_out_sec), "-y", new_fn], **subprocess_args(True)) + span.set_attribute("ffmpeg.args", json.dumps(process.args)) + logger.info(" ".join(process.args)) + if process.returncode != 0: + span.set_status(Status(StatusCode.ERROR)) + logger.error("FFMPEG ERROR: %s", process.stderr) + return file + else: + span.set_status(Status(StatusCode.OK)) + return new_fn + except Exception as e: + span.set_status(Status(StatusCode.ERROR)) + logger.error("FFMPEG ERROR: %s", e) + return file + + + # Create a set of arguments which make a ``subprocess.Popen`` (and # variants) call work with or without Pyinstaller, ``--noconsole`` or # not, on Windows and Linux. Typical use::