支持设置视频输出位置
This commit is contained in:
parent
b1e065d1f9
commit
52317ca39b
10
config.py
10
config.py
@ -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
|
||||
|
||||
|
@ -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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user