UPD
This commit is contained in:
+43
-9
@@ -23,16 +23,20 @@ try:
|
||||
import proglog
|
||||
class WriteProgressLogger(proglog.ProgressBarLogger):
|
||||
"""Логгер прогресса записи видео для передачи в окно выполнения."""
|
||||
def __init__(self, callback):
|
||||
def __init__(self, callback=None, cancel_check=None, stage=STAGE_WRITE):
|
||||
super().__init__()
|
||||
self._callback = callback
|
||||
self._cancel_check = cancel_check if callable(cancel_check) else (lambda: False)
|
||||
self._stage = stage
|
||||
def bars_callback(self, bar, attr, value, old_value=None):
|
||||
if self._cancel_check():
|
||||
raise CancelledError()
|
||||
if not self._callback or bar not in self.bars:
|
||||
return
|
||||
total = self.bars[bar].get("total")
|
||||
if total and total > 0:
|
||||
pct = value / total
|
||||
self._callback(STAGE_WRITE, pct, f"Сохранение: {int(pct * 100)}%")
|
||||
self._callback(self._stage, pct, f"Сохранение: {int(pct * 100)}%")
|
||||
_HAS_PROGLOG = True
|
||||
except Exception:
|
||||
_HAS_PROGLOG = False
|
||||
@@ -264,7 +268,6 @@ class VideoProcessor:
|
||||
try:
|
||||
keep = self._ranges_to_keep(remove_ranges, video.duration)
|
||||
if not keep:
|
||||
current_step += 1
|
||||
continue
|
||||
part_clips = []
|
||||
for start, end in keep:
|
||||
@@ -279,13 +282,24 @@ class VideoProcessor:
|
||||
except Exception:
|
||||
pass
|
||||
temp_path = os.path.join(tmpdir, f"part_{i:04d}.mp4")
|
||||
write_kw = {"codec": "libx264", "bitrate": self.get_bitrate(quality), "audio_codec": "aac"}
|
||||
# В оконной сборке stdout/stderr могут быть None; отключаем дефолтный логгер MoviePy.
|
||||
write_kw = {"codec": "libx264", "bitrate": self.get_bitrate(quality), "audio_codec": "aac", "logger": None}
|
||||
if fps and fps > 0:
|
||||
write_kw["fps"] = fps
|
||||
if _HAS_PROGLOG and WriteProgressLogger is not None:
|
||||
write_kw["logger"] = WriteProgressLogger(cancel_check=cancel_check, stage=STAGE_PREPARE)
|
||||
try:
|
||||
part.write_videofile(temp_path, **write_kw)
|
||||
except TypeError:
|
||||
part.write_videofile(temp_path, codec="libx264", bitrate=self.get_bitrate(quality), audio_codec="aac")
|
||||
part.write_videofile(
|
||||
temp_path,
|
||||
codec="libx264",
|
||||
bitrate=self.get_bitrate(quality),
|
||||
audio_codec="aac",
|
||||
logger=None,
|
||||
)
|
||||
if cancel_check():
|
||||
raise CancelledError()
|
||||
part.close()
|
||||
temp_paths.append(temp_path)
|
||||
finally:
|
||||
@@ -353,20 +367,32 @@ class VideoProcessor:
|
||||
if progress_callback:
|
||||
progress_callback(STAGE_WRITE, 0.0, "Сохранение итогового файла...")
|
||||
self.logger.log("INFO", f"Сохранение файла: {output_path}")
|
||||
write_kw = {"codec": "libx264", "bitrate": self.get_bitrate(quality), "audio_codec": "aac"}
|
||||
write_kw = {"codec": "libx264", "bitrate": self.get_bitrate(quality), "audio_codec": "aac", "logger": None}
|
||||
if fps is not None and fps > 0:
|
||||
write_kw["fps"] = fps
|
||||
write_kw["preset"] = preset
|
||||
write_kw["audio_bitrate"] = audio_bitrate
|
||||
if _HAS_PROGLOG and progress_callback and WriteProgressLogger is not None:
|
||||
write_kw["logger"] = WriteProgressLogger(progress_callback)
|
||||
if _HAS_PROGLOG and WriteProgressLogger is not None:
|
||||
write_kw["logger"] = WriteProgressLogger(
|
||||
callback=progress_callback,
|
||||
cancel_check=check,
|
||||
stage=STAGE_WRITE,
|
||||
)
|
||||
try:
|
||||
to_write.write_videofile(output_path, **write_kw)
|
||||
except TypeError:
|
||||
write_kw.pop("preset", None)
|
||||
write_kw.pop("audio_bitrate", None)
|
||||
write_kw.pop("logger", None)
|
||||
write_kw["logger"] = None
|
||||
to_write.write_videofile(output_path, **write_kw)
|
||||
if check():
|
||||
raise CancelledError()
|
||||
except CancelledError:
|
||||
self._remove_if_exists(output_path)
|
||||
raise
|
||||
except Exception:
|
||||
self._remove_if_exists(output_path)
|
||||
raise
|
||||
if resized is not None:
|
||||
try:
|
||||
resized.close()
|
||||
@@ -382,6 +408,14 @@ class VideoProcessor:
|
||||
_write_video_metadata(output_path, meta, self.logger)
|
||||
return output_path
|
||||
|
||||
@staticmethod
|
||||
def _remove_if_exists(path):
|
||||
try:
|
||||
if path and os.path.isfile(path):
|
||||
os.remove(path)
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
def get_bitrate(self, quality):
|
||||
"""Определение битрейта в зависимости от качества"""
|
||||
quality_settings = {
|
||||
|
||||
Reference in New Issue
Block a user