Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion videocaptioner/cli/commands/synthesize.py
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,11 @@ def run(args: Namespace, config: dict) -> int:
def progress_callback(*cb_args) -> None:
if progress and cb_args:
try:
progress.update(int(float(cb_args[0])), f"Encoding [{subtitle_mode}]")
percent = int(float(cb_args[0]))
message = cb_args[1] if len(cb_args) > 1 else ""
current_time = cb_args[2] if len(cb_args) > 2 else None
total_duration = cb_args[3] if len(cb_args) > 3 else None
progress.update(percent, message, current_time, total_duration)
except (ValueError, TypeError):
pass

Expand Down
29 changes: 28 additions & 1 deletion videocaptioner/cli/output.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,22 @@ def start(self) -> "ProgressLine":
self._thread.start()
return self

def update(self, percent: int, message: str = "") -> None:
def update(
self,
percent: int,
message: str = "",
current_time: Optional[float] = None,
total_duration: Optional[float] = None,
) -> None:
self.percent = percent
if message:
self.message = message
if current_time is not None and total_duration is not None:
self._time_display = f" {format_time(current_time)} / {format_time(total_duration)}"
elif total_duration is not None:
self._time_display = f" / {format_time(total_duration)}"
else:
self._time_display = ""

def _cleanup(self) -> None:
self._stop.set()
Expand All @@ -93,11 +105,26 @@ def fail(self, message: str = "") -> None:
def _spin(self) -> None:
while not self._stop.is_set():
char = self.SPINNER[self._frame % len(self.SPINNER)]
time_display = getattr(self, "_time_display", "")
if self.percent is not None:
line = f"\r{char} {self.message} [{self.percent}%]"
if time_display:
line += time_display
else:
line = f"\r{char} {self.message}"
sys.stderr.write(f"{line}\033[K")
sys.stderr.flush()
self._frame += 1
self._stop.wait(0.1)


def format_time(seconds: float) -> str:
"""Format seconds to MM:SS or HH:MM:SS format."""
if seconds < 0:
seconds = 0
hours = int(seconds // 3600)
minutes = int((seconds % 3600) // 60)
secs = int(seconds % 60)
if hours > 0:
return f"{hours}:{minutes:02d}:{secs:02d}"
return f"{minutes}:{secs:02d}"
2 changes: 1 addition & 1 deletion videocaptioner/core/subtitle/ass_renderer.py
Original file line number Diff line number Diff line change
Expand Up @@ -386,7 +386,7 @@ def render_ass_video(
# 计算进度百分比
if total_duration:
progress = (current_time / total_duration) * 100
progress_callback(f"{round(progress)}", "正在合成")
progress_callback(f"{round(progress)}", "正在合成", current_time, total_duration)

if progress_callback:
progress_callback("100", "合成完成")
Expand Down
4 changes: 3 additions & 1 deletion videocaptioner/core/utils/video_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -339,7 +339,9 @@ def add_subtitles(
# 计算进度百分比
if total_duration:
progress = (current_time / total_duration) * 100
progress_callback(f"{round(progress)}", "正在合成")
progress_callback(
f"{round(progress)}", "正在合成", current_time, total_duration
)

if progress_callback:
progress_callback("100", "合成完成")
Expand Down