音频淡出

This commit is contained in:
Jerry Yan 2025-04-01 14:39:01 +08:00
parent ced0c1ad1e
commit 364ceb29a1
4 changed files with 46 additions and 3 deletions

View File

@ -8,6 +8,7 @@ from entity.ffmpeg import FfmpegTask
import logging import logging
from util import ffmpeg, oss from util import ffmpeg, oss
from util.ffmpeg import fade_out_audio
from telemetry import get_tracer from telemetry import get_tracer
logger = logging.getLogger('biz/ffmpeg') logger = logging.getLogger('biz/ffmpeg')

View File

@ -2,7 +2,7 @@ import json
from opentelemetry.trace import Status, StatusCode 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 telemetry import get_tracer
from template import get_template_def from template import get_template_def
from util import api from util import api
@ -20,12 +20,15 @@ def start_task(task_info):
if not result: if not result:
span.set_status(Status(StatusCode.ERROR)) span.set_status(Status(StatusCode.ERROR))
return api.report_task_failed(task_info) 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) oss_result = api.upload_task_file(task_info, ffmpeg_task)
if not oss_result: if not oss_result:
span.set_status(Status(StatusCode.ERROR)) span.set_status(Status(StatusCode.ERROR))
return api.report_task_failed(task_info) return api.report_task_failed(task_info)
# 获取视频长度宽度和时长 # 获取视频长度宽度和时长
width, height, duration = probe_video_info(ffmpeg_task)
clear_task_tmp_file(ffmpeg_task) clear_task_tmp_file(ffmpeg_task)
api.report_task_success(task_info, videoInfo={ api.report_task_success(task_info, videoInfo={
"width": width, "width": width,

View File

@ -189,7 +189,9 @@ def report_task_start(task_info):
def report_task_failed(task_info, reason=''): def report_task_failed(task_info, reason=''):
tracer = get_tracer(__name__) 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: with tracer.start_as_current_span("report_task_failed.request") as req_span:
try: try:
req_span.set_attribute("http.method", "POST") req_span.set_attribute("http.method", "POST")

View File

@ -154,6 +154,43 @@ def probe_video_audio(video_file, type=None):
return False return False
return True 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 # Create a set of arguments which make a ``subprocess.Popen`` (and
# variants) call work with or without Pyinstaller, ``--noconsole`` or # variants) call work with or without Pyinstaller, ``--noconsole`` or
# not, on Windows and Linux. Typical use:: # not, on Windows and Linux. Typical use::