From 13f18c5e6c0c315fd3c5819b13bf1220c0484d52 Mon Sep 17 00:00:00 2001 From: Jerry Yan <792602257@qq.com> Date: Tue, 31 May 2022 16:45:35 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9gop=E5=90=8E=E5=88=87?= =?UTF-8?q?=E5=89=B2=EF=BC=8C=E9=81=BF=E5=85=8D=E6=B2=A1=E5=88=87=E5=88=B0?= =?UTF-8?q?keyframe?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- workflow/video.py | 59 ++++++++++++++-------------------------------- workflow/worker.py | 9 +++++-- 2 files changed, 25 insertions(+), 43 deletions(-) diff --git a/workflow/video.py b/workflow/video.py index 8024035..688ded8 100644 --- a/workflow/video.py +++ b/workflow/video.py @@ -23,40 +23,26 @@ def get_video_real_duration(filename): return handle_ffmpeg_output(ffmpeg_process.stdout) -def multi_gpu_encode_video_with_subtitles(orig_filename: str, subtitles: list[str], base_ts: float): - _duration_str = get_video_real_duration(orig_filename) - duration = duration_str_to_float(_duration_str) - current_sec = 0 - while current_sec < duration: - if (current_sec + VIDEO_CLIP_OVERFLOW_SEC * 2) > duration: - print("[-]Less than 2 overflow sec, skip") - break - new_filename = base_ts_to_filename(base_ts + current_sec, True) - new_fullpath = os.path.join(VIDEO_OUTPUT_DIR, new_filename) - print("CUR_FN", new_filename, "BIAS_T", current_sec) - if FFMPEG_USE_NVIDIA_GPU: - process = get_encode_process_use_nvenc(orig_filename, subtitles, new_fullpath, - current_sec, VIDEO_CLIP_EACH_SEC + VIDEO_CLIP_OVERFLOW_SEC) - elif FFMPEG_USE_INTEL_GPU: - process = get_encode_process_use_intel(orig_filename, subtitles, new_fullpath, - current_sec, VIDEO_CLIP_EACH_SEC + VIDEO_CLIP_OVERFLOW_SEC) - else: - process = get_encode_process_use_cpu(orig_filename, subtitles, new_fullpath, - current_sec, VIDEO_CLIP_EACH_SEC + VIDEO_CLIP_OVERFLOW_SEC) - handle_ffmpeg_output(process.stdout) - process.wait() - current_sec += VIDEO_CLIP_EACH_SEC +def encode_video_with_subtitles(orig_filename: str, subtitles: list[str], base_ts: float): + new_filename = base_ts_to_filename(base_ts, True) + new_fullpath = os.path.join(VIDEO_OUTPUT_DIR, new_filename) + if FFMPEG_USE_NVIDIA_GPU: + process = get_encode_process_use_nvenc(orig_filename, subtitles, new_fullpath) + elif FFMPEG_USE_INTEL_GPU: + process = get_encode_process_use_intel(orig_filename, subtitles, new_fullpath) + else: + process = get_encode_process_use_cpu(orig_filename, subtitles, new_fullpath) + handle_ffmpeg_output(process.stdout) + process.wait() + return [new_fullpath] -def get_encode_process_use_nvenc(orig_filename: str, subtitles: list[str], new_filename: str, - skip: float = 0, duration: float = 0): +def get_encode_process_use_nvenc(orig_filename: str, subtitles: list[str], new_filename: str): print("[+]Use Nvidia NvEnc Acceleration") encode_process = subprocess.Popen([ FFMPEG_EXEC, *_common_ffmpeg_setting(), - "-ss", str(skip), "-copyts", "-t", str(duration), "-i", orig_filename, "-vf", ",".join("subtitles=%s" % i for i in subtitles) + ",hwupload_cuda", - "-ss", str(skip), "-c:a", "copy", "-c:v", "h264_nvenc", "-f", "mp4", "-b:v", VIDEO_BITRATE, "-rc:v", "vbr", "-tune:v", "hq", *_common_ffmpeg_params(), @@ -66,16 +52,13 @@ def get_encode_process_use_nvenc(orig_filename: str, subtitles: list[str], new_f return encode_process -def get_encode_process_use_intel(orig_filename: str, subtitles: list[str], new_filename: str, - skip: float = 0, duration: float = 0): +def get_encode_process_use_intel(orig_filename: str, subtitles: list[str], new_filename: str): if platform.system().lower() == "windows": print("[+]Use Intel QSV Acceleration") encode_process = subprocess.Popen([ FFMPEG_EXEC, *_common_ffmpeg_setting(), - "-ss", str(skip), "-copyts", "-t", str(duration), "-hwaccel", "qsv", "-i", orig_filename, "-vf", ",".join("subtitles=%s" % i for i in subtitles), - "-ss", str(skip), "-c:a", "copy", "-c:v", "h264_qsv", "-f", "mp4", "-b:v", VIDEO_BITRATE, "-rc:v", "vbr", "-tune:v", "hq", *_common_ffmpeg_params(), @@ -86,10 +69,8 @@ def get_encode_process_use_intel(orig_filename: str, subtitles: list[str], new_f print("[+]Use Intel VAAPI Acceleration") encode_process = subprocess.Popen([ FFMPEG_EXEC, *_common_ffmpeg_setting(), - "-ss", str(skip), "-copyts", "-t", str(duration), "-hwaccel", "vaapi", "-i", orig_filename, "-vf", ",".join("subtitles=%s" % i for i in subtitles) + ",hwupload", - "-ss", str(skip), "-c:a", "copy", "-c:v", "h264_vaapi", "-f", "mp4", "-b:v", VIDEO_BITRATE, "-rc:v", "vbr", "-tune:v", "hq", *_common_ffmpeg_params(), @@ -99,15 +80,12 @@ def get_encode_process_use_intel(orig_filename: str, subtitles: list[str], new_f return encode_process -def get_encode_process_use_cpu(orig_filename: str, subtitles: list[str], new_filename: str, - skip: float = 0, duration: float = 0): +def get_encode_process_use_cpu(orig_filename: str, subtitles: list[str], new_filename: str): print("[+]Use CPU Encode") encode_process = subprocess.Popen([ FFMPEG_EXEC, *_common_ffmpeg_setting(), - "-ss", str(skip), "-copyts", "-t", str(duration), "-i", orig_filename, "-vf", ",".join("subtitles=%s" % i for i in subtitles), - "-ss", str(skip), "-c:a", "copy", "-c:v", "h264", "-f", "mp4", "-b:v", VIDEO_BITRATE, *_common_ffmpeg_params(), @@ -176,15 +154,14 @@ def quick_split_video(file): def _common_ffmpeg_setting(): return ( - "-y", "-hide_banner", "-progress", "-", "-loglevel", "error" + "-y", "-hide_banner", "-progress", "-", "-loglevel", "error", ) def _common_ffmpeg_params(): return ( "-f", "mp4", "-b:v", VIDEO_BITRATE, "-c:a", "copy", - "-sub_charenc", "UTF-8", - "-preset:v", "fast", "-profile:v", "main", - "-qmin", "12", "-qmax", "34", "-crf", "26", + "-preset:v", "fast", "-profile:v", "main", "-avoid_negative_ts", "1", + "-qmin", "12", "-qmax", "34", "-crf", "26", "-g:v", "60", "-fflags", "+genpts", "-shortest", "-movflags", "faststart" ) diff --git a/workflow/worker.py b/workflow/worker.py index edd2914..48fd76d 100644 --- a/workflow/worker.py +++ b/workflow/worker.py @@ -2,7 +2,7 @@ import os.path from exception.danmaku import DanmakuException from workflow.danmaku import get_file_start, diff_danmaku_files, danmaku_to_subtitle -from workflow.video import multi_gpu_encode_video_with_subtitles +from workflow.video import encode_video_with_subtitles, quick_split_video def do_workflow(video_file, danmaku_base_file, *danmaku_files): @@ -26,9 +26,14 @@ def do_workflow(video_file, danmaku_base_file, *danmaku_files): print("弹幕文件", danmaku_file, "异常") continue print(result) - multi_gpu_encode_video_with_subtitles(video_file, result, start_ts) + file_need_split = encode_video_with_subtitles(video_file, result, start_ts) + for file in file_need_split: + quick_split_video(file) # clean files for file in result: if os.path.isfile(file): os.remove(file) + for file in file_need_split: + if os.path.isfile(file): + os.remove(file)