From b74c6f0ef736141e6ac1cee82538f9f15603315e Mon Sep 17 00:00:00 2001 From: Jerry Yan <792602257@qq.com> Date: Mon, 10 Oct 2022 14:35:28 +0800 Subject: [PATCH] =?UTF-8?q?=E6=94=AF=E6=8C=81vaapi=E3=80=81=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E5=AE=9A=E4=B9=89=E4=BD=BF=E7=94=A8=E5=93=AA=E7=A7=8D?= =?UTF-8?q?=E5=BC=B9=E5=B9=95=E8=BD=AC=E6=8D=A2=E5=B7=A5=E5=85=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config.py | 29 +++++++++++++++------ controller/api/collector_blueprint.py | 4 +-- templates/index.html | 15 +++++++++++ workflow/danmaku.py | 31 +++++++++++++++++----- workflow/video.py | 37 +++++++++++++++++++++++++-- 5 files changed, 98 insertions(+), 18 deletions(-) diff --git a/config.py b/config.py index 035b8ea..c3de16b 100644 --- a/config.py +++ b/config.py @@ -3,12 +3,16 @@ import os.path # [danmaku] +# use_danmu2ass +DANMAKU_USE_DANMU2ASS = False +# use_danmakufactory +DANMAKU_USE_DANMAKUFACTORY = True # exec -DANMAKU_FACTORY_EXEC = "DanmakuFactory" +DANMAKU_EXEC = "DanmakuFactory" # speed DANMAKU_SPEED = 12 # font -DEFAULT_FONT_NAME = "Sarasa Term SC" +DANMAKU_FONT_NAME = "Sarasa Term SC" # font_size DANMAKU_FONT_SIZE = 40 # resolution @@ -22,6 +26,8 @@ FFMPEG_USE_HEVC = False FFMPEG_USE_NVIDIA_GPU = False # intel_gpu FFMPEG_USE_INTEL_GPU = False +# vaapi +FFMPEG_USE_VAAPI = False # bitrate VIDEO_BITRATE = "2.5M" # crf @@ -66,10 +72,13 @@ def load_config(): config.read("config.ini", encoding="utf-8") if config.has_section("danmaku"): section = config['danmaku'] - global DANMAKU_FACTORY_EXEC, DANMAKU_SPEED, DEFAULT_FONT_NAME, VIDEO_RESOLUTION, DANMAKU_FONT_SIZE - DANMAKU_FACTORY_EXEC = section.get('exec', DANMAKU_FACTORY_EXEC) + global DANMAKU_EXEC, DANMAKU_SPEED, DANMAKU_FONT_NAME, VIDEO_RESOLUTION, DANMAKU_FONT_SIZE, \ + DANMAKU_USE_DANMU2ASS, DANMAKU_USE_DANMAKUFACTORY + DANMAKU_USE_DANMU2ASS = section.getboolean('use_danmu2ass', DANMAKU_USE_DANMU2ASS) + DANMAKU_USE_DANMAKUFACTORY = section.getboolean('use_danmakufactory', DANMAKU_USE_DANMAKUFACTORY) + DANMAKU_EXEC = section.get('exec', DANMAKU_EXEC) DANMAKU_SPEED = section.getfloat('speed', DANMAKU_SPEED) - DEFAULT_FONT_NAME = section.get('font', DEFAULT_FONT_NAME) + DANMAKU_FONT_NAME = section.get('font', DANMAKU_FONT_NAME) DANMAKU_FONT_SIZE = section.getint('font_size', DANMAKU_FONT_SIZE) VIDEO_RESOLUTION = section.get('resolution', VIDEO_RESOLUTION) if config.has_section("video"): @@ -88,11 +97,12 @@ def load_config(): if config.has_section("ffmpeg"): section = config['ffmpeg'] global FFMPEG_EXEC, FFMPEG_USE_HEVC, FFMPEG_USE_NVIDIA_GPU, FFMPEG_USE_INTEL_GPU, VIDEO_BITRATE, VIDEO_CRF, \ - VIDEO_GOP + VIDEO_GOP, FFMPEG_USE_VAAPI FFMPEG_EXEC = section.get('exec', FFMPEG_EXEC) FFMPEG_USE_HEVC = section.getboolean('hevc', FFMPEG_USE_HEVC) FFMPEG_USE_NVIDIA_GPU = section.getboolean('nvidia_gpu', FFMPEG_USE_NVIDIA_GPU) FFMPEG_USE_INTEL_GPU = section.getboolean('intel_gpu', FFMPEG_USE_INTEL_GPU) + FFMPEG_USE_VAAPI = section.getboolean('vaapi', FFMPEG_USE_VAAPI) VIDEO_BITRATE = section.get('bitrate', VIDEO_BITRATE) VIDEO_CRF = section.getfloat('crf', VIDEO_CRF) VIDEO_GOP = section.getfloat('gop', VIDEO_GOP) @@ -108,9 +118,11 @@ def load_config(): def get_config(): config = { 'danmaku': { - 'exec': DANMAKU_FACTORY_EXEC, + 'exec': DANMAKU_EXEC, + 'use_danmu2ass': DANMAKU_USE_DANMU2ASS, + 'use_danmakufactory': DANMAKU_USE_DANMAKUFACTORY, 'speed': DANMAKU_SPEED, - 'font': DEFAULT_FONT_NAME, + 'font': DANMAKU_FONT_NAME, 'font_size': DANMAKU_FONT_SIZE, 'resolution': VIDEO_RESOLUTION, }, @@ -130,6 +142,7 @@ def get_config(): 'hevc': FFMPEG_USE_HEVC, 'nvidia_gpu': FFMPEG_USE_NVIDIA_GPU, 'intel_gpu': FFMPEG_USE_INTEL_GPU, + 'vaapi': FFMPEG_USE_VAAPI, 'bitrate': VIDEO_BITRATE, 'crf': VIDEO_CRF, 'gop': VIDEO_GOP, diff --git a/controller/api/collector_blueprint.py b/controller/api/collector_blueprint.py index 98aee72..cec02b3 100644 --- a/controller/api/collector_blueprint.py +++ b/controller/api/collector_blueprint.py @@ -4,7 +4,7 @@ import platform import psutil from flask import Blueprint, jsonify -from config import DANMAKU_FACTORY_EXEC, FFMPEG_EXEC, BILILIVE_RECORDER_DIRECTORY, XIGUALIVE_RECORDER_DIRECTORY, VIDEO_OUTPUT_DIR +from config import DANMAKU_EXEC, FFMPEG_EXEC, BILILIVE_RECORDER_DIRECTORY, XIGUALIVE_RECORDER_DIRECTORY, VIDEO_OUTPUT_DIR from util.system import check_exec from workflow.bilibili import IS_LIVING, IS_UPLOADING @@ -60,7 +60,7 @@ def collect_basic_status(): }, 'exec': { 'ffmpeg': check_exec(FFMPEG_EXEC), - 'danmaku': check_exec(DANMAKU_FACTORY_EXEC), + 'danmaku': check_exec(DANMAKU_EXEC), }, 'system': { 'os': platform.system(), diff --git a/templates/index.html b/templates/index.html index 1b92eb7..db17265 100644 --- a/templates/index.html +++ b/templates/index.html @@ -84,6 +84,10 @@ HEVC + + VAAPI + + 嘤伟达GPU @@ -117,6 +121,14 @@ 命令 {{ config.danmaku.exec }} + + DANMU2ASS + + + + DanmakuFactory + + 滚动速度 {{ config.danmaku.speed }} @@ -285,6 +297,8 @@ config: { danmaku: { exec: "", + use_danmu2ass: false, + use_danmakufactory: false, speed: 0, font: "", font_size: 0, @@ -306,6 +320,7 @@ hevc: false, nvidia_gpu: false, intel_gpu: false, + vaapi: false, bitrate: "", crf: "", gop: "", diff --git a/workflow/danmaku.py b/workflow/danmaku.py index 80bec32..6f5e8b8 100644 --- a/workflow/danmaku.py +++ b/workflow/danmaku.py @@ -7,7 +7,8 @@ from typing import Union from bs4 import BeautifulSoup -from config import DANMAKU_FACTORY_EXEC, VIDEO_RESOLUTION, DANMAKU_SPEED, DEFAULT_FONT_NAME, DANMAKU_FONT_SIZE +from config import DANMAKU_EXEC, VIDEO_RESOLUTION, DANMAKU_SPEED, DANMAKU_FONT_NAME, DANMAKU_FONT_SIZE, \ + DANMAKU_USE_DANMU2ASS, DANMAKU_USE_DANMAKUFACTORY from exception.danmaku import NoDanmakuException, DanmakuFormatErrorException from util.file import check_file_exist @@ -34,15 +35,33 @@ def diff_danmaku_files(base_file: Union[os.PathLike[str], str], file: Union[os.P def danmaku_to_subtitle(file: Union[os.PathLike[str], str], time_shift: float): new_subtitle_name = md5(file.encode("utf-8")).hexdigest() + ".ass" - process = subprocess.Popen(( - DANMAKU_FACTORY_EXEC, "--ignore-warnings", + if DANMAKU_USE_DANMAKUFACTORY: + process = danmaku_to_subtitle_use_danmaku_factory(file, time_shift, new_subtitle_name) + elif DANMAKU_USE_DANMU2ASS: + process = danmaku_to_subtitle_use_danmu2ass(file, time_shift, new_subtitle_name) + else: + return + process.wait() + return new_subtitle_name + + +def danmaku_to_subtitle_use_danmaku_factory(file: Union[os.PathLike[str], str], time_shift: float, new_subtitle_name: str): + return subprocess.Popen(( + DANMAKU_EXEC, "--ignore-warnings", "-r", str(VIDEO_RESOLUTION), "-s", str(DANMAKU_SPEED), "-f", "5", - "-S", str(DANMAKU_FONT_SIZE), "-N", str(DEFAULT_FONT_NAME), "--showmsgbox", "FALSE", + "-S", str(DANMAKU_FONT_SIZE), "-N", str(DANMAKU_FONT_NAME), "--showmsgbox", "FALSE", "-O", "255", "-L", "1", "-D", "0", "-o", "ass", new_subtitle_name, "-i", file, "-t", str(time_shift) )) - process.wait() - return new_subtitle_name + + +def danmaku_to_subtitle_use_danmu2ass(file: Union[os.PathLike[str], str], time_shift: float, new_subtitle_name: str): + (_w, _h) = VIDEO_RESOLUTION.split("x") + return subprocess.Popen(( + DANMAKU_EXEC, "--force", "-a", "1", "-d", str(DANMAKU_SPEED), "--font", str(DANMAKU_FONT_NAME), + "--font-size", str(DANMAKU_FONT_SIZE), "--lane-size", str(DANMAKU_FONT_SIZE), "--width", _w, "--height", _h, + "-o", new_subtitle_name, "-p", "1", "--time-offset", str(time_shift), "--width-ratio", "1", file + )) if __name__ == '__main__': diff --git a/workflow/video.py b/workflow/video.py index ef6cba6..561acda 100644 --- a/workflow/video.py +++ b/workflow/video.py @@ -3,8 +3,9 @@ import subprocess from datetime import datetime, timedelta from typing import IO -from config import FFMPEG_EXEC, FFMPEG_USE_HEVC, VIDEO_BITRATE, FFMPEG_USE_NVIDIA_GPU, VIDEO_CLIP_EACH_SEC, VIDEO_CLIP_OVERFLOW_SEC, \ - FFMPEG_USE_INTEL_GPU, VIDEO_OUTPUT_DIR, VIDEO_CRF, VIDEO_GOP +from config import FFMPEG_EXEC, FFMPEG_USE_HEVC, VIDEO_BITRATE, FFMPEG_USE_NVIDIA_GPU, VIDEO_CLIP_EACH_SEC, \ + VIDEO_CLIP_OVERFLOW_SEC, \ + FFMPEG_USE_INTEL_GPU, VIDEO_OUTPUT_DIR, VIDEO_CRF, VIDEO_GOP, FFMPEG_USE_VAAPI from . import LOGGER @@ -29,6 +30,8 @@ def encode_video_with_subtitles(orig_filename: str, subtitles: list[str], base_t if FFMPEG_USE_HEVC: if FFMPEG_USE_NVIDIA_GPU: process = get_encode_hevc_process_use_nvenc(orig_filename, subtitles, new_fullpath) + elif FFMPEG_USE_VAAPI: + process = get_encode_hevc_process_use_vaapi(orig_filename, subtitles, new_fullpath) elif FFMPEG_USE_INTEL_GPU: process = get_encode_hevc_process_use_intel(orig_filename, subtitles, new_fullpath) else: @@ -36,6 +39,8 @@ def encode_video_with_subtitles(orig_filename: str, subtitles: list[str], base_t else: if FFMPEG_USE_NVIDIA_GPU: process = get_encode_process_use_nvenc(orig_filename, subtitles, new_fullpath) + elif FFMPEG_USE_VAAPI: + process = get_encode_process_use_vaapi(orig_filename, subtitles, new_fullpath) elif FFMPEG_USE_INTEL_GPU: process = get_encode_process_use_intel(orig_filename, subtitles, new_fullpath) else: @@ -73,6 +78,20 @@ def get_encode_process_use_intel(orig_filename: str, subtitles: list[str], new_f return encode_process +def get_encode_process_use_vaapi(orig_filename: str, subtitles: list[str], new_filename: str): + print("[+]Use VAAPI Acceleration") + encode_process = subprocess.Popen([ + FFMPEG_EXEC, *_common_ffmpeg_setting(), + "-hwaccel", "vaapi", "-hwaccel_output_format", "vaapi", "-i", orig_filename, "-vf", + ",".join("subtitles=%s" % i for i in subtitles), + "-c:v", "h264_vaapi", + *_common_ffmpeg_params(), + # "-t", "10", + new_filename + ], stdout=subprocess.PIPE) + return encode_process + + def get_encode_process_use_cpu(orig_filename: str, subtitles: list[str], new_filename: str): print("[+]Use CPU Encode") encode_process = subprocess.Popen([ @@ -101,6 +120,20 @@ def get_encode_hevc_process_use_nvenc(orig_filename: str, subtitles: list[str], return encode_process +def get_encode_hevc_process_use_vaapi(orig_filename: str, subtitles: list[str], new_filename: str): + print("[+]Use VAAPI Acceleration") + encode_process = subprocess.Popen([ + FFMPEG_EXEC, *_common_ffmpeg_setting(), + "-hwaccel", "vaapi", "-hwaccel_output_format", "vaapi", "-i", orig_filename, "-vf", + ",".join("subtitles=%s" % i for i in subtitles), + "-c:v", "hevc_vaapi", + *_common_ffmpeg_params(), + # "-t", "10", + new_filename + ], stdout=subprocess.PIPE) + return encode_process + + def get_encode_hevc_process_use_intel(orig_filename: str, subtitles: list[str], new_filename: str): print("[+]Use Intel QSV Acceleration") encode_process = subprocess.Popen([