You've already forked lubo_toolkit
							
							支持设置视频输出位置
This commit is contained in:
		
							
								
								
									
										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)
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user