支持设置视频输出位置

This commit is contained in:
Jerry Yan 2022-05-18 09:30:02 +08:00
parent b1e065d1f9
commit 52317ca39b
2 changed files with 60 additions and 42 deletions

View File

@ -33,6 +33,8 @@ VIDEO_CLIP_OVERFLOW_SEC = 5
BILILIVE_RECORDER_DIRECTORY = "./"
# xigua_dir
XIGUALIVE_RECORDER_DIRECTORY = "./"
# output_dir
VIDEO_OUTPUT_DIR = "./"
def load_config():
@ -65,10 +67,11 @@ def load_config():
FFMPEG_USE_INTEL_GPU = section.getboolean('intel_gpu', FFMPEG_USE_INTEL_GPU)
VIDEO_BITRATE = section.get('bitrate', VIDEO_BITRATE)
if config.has_section("recorder"):
global BILILIVE_RECORDER_DIRECTORY, XIGUALIVE_RECORDER_DIRECTORY
global BILILIVE_RECORDER_DIRECTORY, XIGUALIVE_RECORDER_DIRECTORY, VIDEO_OUTPUT_DIR
section = config['recorder']
BILILIVE_RECORDER_DIRECTORY = section.get('bili_dir', BILILIVE_RECORDER_DIRECTORY)
XIGUALIVE_RECORDER_DIRECTORY = section.get('xigua_dir', XIGUALIVE_RECORDER_DIRECTORY)
VIDEO_OUTPUT_DIR = section.get('output_dir', VIDEO_OUTPUT_DIR)
return True
@ -90,6 +93,11 @@ def get_config():
'intel_gpu': FFMPEG_USE_INTEL_GPU,
'bitrate': VIDEO_BITRATE,
},
'recorder': {
'bili_dir': BILILIVE_RECORDER_DIRECTORY,
'xigua_dir': XIGUALIVE_RECORDER_DIRECTORY,
'output_dir': VIDEO_OUTPUT_DIR,
},
}
return config

View File

@ -12,9 +12,10 @@ from PyQt5 import QtGui
from PyQt5.QtCore import Qt, QThread, pyqtSignal
from PyQt5.QtWidgets import QWidget, QLabel, QApplication, QFrame, QVBoxLayout, QPushButton, \
QSizePolicy, QMessageBox
from danmaku_xml_helper import get_file_start, diff_danmaku_files
from danmaku_xml_helper import get_file_start, diff_danmaku_files, NoDanmakuException
from config import load_config, FFMPEG_EXEC, DANMAKU_FACTORY_EXEC, FFMPEG_USE_INTEL_GPU, FFMPEG_USE_NVIDIA_GPU, \
VIDEO_BITRATE, VIDEO_CLIP_EACH_SEC, VIDEO_CLIP_OVERFLOW_SEC, VIDEO_RESOLUTION, DANMAKU_SPEED, DEFAULT_FONT_NAME
VIDEO_BITRATE, VIDEO_CLIP_EACH_SEC, VIDEO_CLIP_OVERFLOW_SEC, VIDEO_RESOLUTION, DANMAKU_SPEED, DEFAULT_FONT_NAME, \
VIDEO_OUTPUT_DIR
class Job:
@ -302,11 +303,17 @@ class WorkerThread(QThread):
def run_danmaku_encode(self, job: Job):
base_danmaku = job.danmaku.pop(0)
time_shift = 0
try:
base_start_ts = get_file_start(base_danmaku)
except NoDanmakuException:
return
new_subtitle_name = danmaku_to_subtitle(base_danmaku, time_shift)
job.subtitles.append(new_subtitle_name)
for danmaku in job.danmaku:
try:
time_shift = diff_danmaku_files(base_danmaku, danmaku)
except NoDanmakuException:
continue
new_subtitle_name = danmaku_to_subtitle(danmaku, time_shift)
job.subtitles.append(new_subtitle_name)
# 压制
@ -380,47 +387,44 @@ class WorkerThread(QThread):
def multi_gpu_encode_video_with_subtitles(self, orig_filename: str, subtitles: list[str], base_ts: float):
new_filename = base_ts_to_filename(base_ts)
new_fullpath = os.path.join(VIDEO_OUTPUT_DIR, new_filename)
if not (FFMPEG_USE_NVIDIA_GPU and FFMPEG_USE_INTEL_GPU):
print("[!]Not Enabled Both GPU")
self.encode_video_with_subtitles(orig_filename, subtitles, new_filename)
return [new_filename]
duration = self.get_video_real_duration(orig_filename)
print("[>]Duration:", duration)
self.encode_video_with_subtitles(orig_filename, subtitles, new_fullpath)
return [new_fullpath]
_duration_str = self.get_video_real_duration(orig_filename)
duration = duration_str_to_float(_duration_str)
if duration > (VIDEO_CLIP_EACH_SEC * 5):
# qsv 压制前2段剩余交由nvenc压制
_slices = int(duration / VIDEO_CLIP_EACH_SEC)
new_filename0 = base_ts_to_filename(base_ts + (_slices - 1) * VIDEO_CLIP_EACH_SEC)
new_filename1 = base_ts_to_filename(base_ts)
new_fullpath0 = os.path.join(VIDEO_OUTPUT_DIR, new_filename0)
new_fullpath1 = os.path.join(VIDEO_OUTPUT_DIR, new_filename1)
print("[+]Use Intel QSV Acceleration")
encode_process0 = subprocess.Popen([
FFMPEG_EXEC, "-hide_banner", "-progress", "-", "-loglevel", "error", "-y",
"-hwaccel", "qsv", "-ss", str((_slices - 1) * VIDEO_CLIP_EACH_SEC),
"-copyts", "-i", orig_filename, "-vf",
",".join("subtitles=%s" % i for i in subtitles),
"-c:a", "copy", "-c:v", "h264_qsv", "-ss", str((_slices - 1) * VIDEO_CLIP_EACH_SEC),
"-f", "mp4", "-preset:v", "fast", "-profile:v", "high", "-level", "4.1",
"-b:v", VIDEO_BITRATE, "-rc:v", "vbr", "-tune:v", "hq",
"-qmin", "10", "-qmax", "32", "-crf", "16",
"-fflags", "+genpts", "-shortest", "-movflags", "faststart",
"-c:a", "copy", "-c:v", "h264_qsv",
"-f", "mp4", "-b:v", VIDEO_BITRATE, "-rc:v", "vbr", "-tune:v", "hq",
*_common_ffmpeg_params(),
# "-t", "10",
new_filename0
new_fullpath0
], **subprocess_args(True))
print("[+]Use Nvidia NvEnc Acceleration")
encode_process1 = subprocess.Popen([
FFMPEG_EXEC, "-hide_banner", "-progress", "-", "-loglevel", "error", "-y",
"-t", str((_slices - 1) * VIDEO_CLIP_EACH_SEC + (VIDEO_CLIP_OVERFLOW_SEC * 0.5)),
"-t", str((_slices - 1) * VIDEO_CLIP_EACH_SEC + (VIDEO_CLIP_OVERFLOW_SEC * 0.8)),
"-i", orig_filename, "-vf",
",".join("subtitles=%s" % i for i in subtitles),
"-c:a", "copy", "-c:v", "h264_nvenc",
"-f", "mp4", "-preset:v", "fast", "-profile:v", "high", "-level", "4.1",
"-b:v", VIDEO_BITRATE, "-rc:v", "vbr", "-tune:v", "hq",
"-qmin", "10", "-qmax", "32", "-crf", "16",
"-fflags", "+genpts", "-shortest", "-movflags", "faststart",
"-c:a", "copy", "-c:v", "h264_nvenc", "-ss", str(VIDEO_CLIP_EACH_SEC * 2),
"-f", "mp4", "-b:v", VIDEO_BITRATE, "-rc:v", "vbr", "-tune:v", "hq",
*_common_ffmpeg_params(),
# "-t", "10",
new_filename1
new_fullpath1
], **subprocess_args(True))
threading.Thread(target=self.handle_ffmpeg_output, args=(encode_process0.stdout, True,)).start()
threading.Thread(target=self.handle_ffmpeg_output, args=(encode_process1.stdout,)).start()
encode_process0.wait()
encode_process1.wait()
return [new_filename0, new_filename1]
@ -429,42 +433,40 @@ class WorkerThread(QThread):
_slices = int(duration / VIDEO_CLIP_EACH_SEC)
new_filename0 = base_ts_to_filename(base_ts + _slices * VIDEO_CLIP_EACH_SEC, True)
new_filename1 = base_ts_to_filename(base_ts)
new_fullpath0 = os.path.join(VIDEO_OUTPUT_DIR, new_filename0)
new_fullpath1 = os.path.join(VIDEO_OUTPUT_DIR, new_filename1)
print("[+]Use Intel QSV Acceleration")
encode_process0 = subprocess.Popen([
FFMPEG_EXEC, "-hide_banner", "-progress", "-", "-loglevel", "error", "-y",
"-hwaccel", "qsv", "-ss", str(_slices * VIDEO_CLIP_EACH_SEC),
"-copyts", "-i", orig_filename, "-vf",
",".join("subtitles=%s" % i for i in subtitles),
"-c:a", "copy", "-c:v", "h264_qsv", "-ss", str(_slices * VIDEO_CLIP_EACH_SEC),
"-f", "mp4", "-preset:v", "fast", "-profile:v", "high", "-level", "4.1",
"-b:v", VIDEO_BITRATE, "-rc:v", "vbr", "-tune:v", "hq",
"-qmin", "10", "-qmax", "32", "-crf", "16",
"-fflags", "+genpts", "-shortest", "-movflags", "faststart",
"-c:a", "copy", "-c:v", "h264_qsv",
"-f", "mp4", "-b:v", VIDEO_BITRATE, "-rc:v", "vbr", "-tune:v", "hq",
*_common_ffmpeg_params(),
# "-t", "10",
new_filename0
new_fullpath0
], **subprocess_args(True))
print("[+]Use Nvidia NvEnc Acceleration")
encode_process1 = subprocess.Popen([
FFMPEG_EXEC, "-hide_banner", "-progress", "-", "-loglevel", "error", "-y",
"-t", str(_slices * VIDEO_CLIP_EACH_SEC + VIDEO_CLIP_OVERFLOW_SEC * 0.5),
"-t", str(_slices * VIDEO_CLIP_EACH_SEC + (VIDEO_CLIP_OVERFLOW_SEC * 0.8)),
"-i", orig_filename, "-vf",
",".join("subtitles=%s" % i for i in subtitles),
"-c:a", "copy", "-c:v", "h264_nvenc",
"-f", "mp4", "-preset:v", "fast", "-profile:v", "high", "-level", "4.1",
"-b:v", VIDEO_BITRATE, "-rc:v", "vbr", "-tune:v", "hq",
"-qmin", "10", "-qmax", "32", "-crf", "16",
"-fflags", "+genpts", "-shortest", "-movflags", "faststart",
"-c:a", "copy", "-c:v", "h264_nvenc", "-ss", str(VIDEO_CLIP_EACH_SEC),
"-f", "mp4", "-b:v", VIDEO_BITRATE, "-rc:v", "vbr", "-tune:v", "hq",
*_common_ffmpeg_params(),
# "-t", "10",
new_filename1
new_fullpath1
], **subprocess_args(True))
threading.Thread(target=self.handle_ffmpeg_output, args=(encode_process0.stdout, True,)).start()
threading.Thread(target=self.handle_ffmpeg_output, args=(encode_process1.stdout,)).start()
encode_process0.wait()
encode_process1.wait()
encode_process0.wait()
return [new_filename1]
else:
self.encode_video_with_subtitles(orig_filename, subtitles, new_filename)
return [new_filename]
print("[-]VideoClip to short,", duration)
print("[-]Fallback to normal")
self.encode_video_with_subtitles(orig_filename, subtitles, new_fullpath)
return [new_fullpath]
def quick_split_video(self, file):
if not os.path.isfile(file):
@ -648,6 +650,14 @@ def check_all_prerequisite():
exit(1)
def _common_ffmpeg_params():
return (
"-preset:v", "fast", "-profile:v", "high", "-level", "4.1",
"-qmin", "10", "-qmax", "48", "-crf", "26",
"-fflags", "+genpts", "-shortest"
)
def main():
check_all_prerequisite()
app = QApplication(sys.argv)