mirror of
https://github.com/jeertmans/manim-slides.git
synced 2025-05-17 10:45:53 +08:00
fix(present): black video flashes and other bugs linked to Qt (#465)
* Relies on Pixel Format instead of Size * chore(lib): remove deprecated warning * chore(deps): update lockfiles * chore(lib): cleanup code * chore(ci): run fmt * chore: update changelog * chore: typo * chore(docs): remove ref. to black screen * fix(deps): issue on Windows --------- Co-authored-by: PeculiarProgrammer <179261820+PeculiarProgrammer@users.noreply.github.com>
This commit is contained in:
@ -11,23 +11,6 @@ from ..commons import config_path_option, folder_path_option, verbosity_option
|
||||
from ..config import Config, PresentationConfig
|
||||
from ..logger import logger
|
||||
|
||||
PREFERRED_QT_VERSIONS = ("6.5.1", "6.5.2")
|
||||
|
||||
|
||||
def warn_if_non_desirable_pyside6_version() -> None:
|
||||
from qtpy import API, QT_VERSION
|
||||
|
||||
if sys.version_info < (3, 12) and (
|
||||
API != "pyside6" or QT_VERSION not in PREFERRED_QT_VERSIONS
|
||||
):
|
||||
logger.warn(
|
||||
f"You are using {API = }, {QT_VERSION = }, "
|
||||
"but we recommend installing 'PySide6==6.5.2', mainly to avoid "
|
||||
"flashing screens between slides, "
|
||||
"see issue https://github.com/jeertmans/manim-slides/issues/293. "
|
||||
"You can do so with `pip install 'manim-slides[pyside6]'`."
|
||||
)
|
||||
|
||||
|
||||
@click.command()
|
||||
@folder_path_option
|
||||
@ -302,8 +285,6 @@ def present(
|
||||
if start_at[1]:
|
||||
start_at_slide_number = start_at[1]
|
||||
|
||||
warn_if_non_desirable_pyside6_version()
|
||||
|
||||
from qtpy.QtCore import Qt
|
||||
from qtpy.QtGui import QScreen
|
||||
|
||||
|
@ -226,6 +226,8 @@ class Player(QMainWindow): # type: ignore[misc]
|
||||
self.icon = QIcon(":/icon.png")
|
||||
self.setWindowIcon(self.icon)
|
||||
|
||||
self.frame = QVideoFrame()
|
||||
|
||||
self.audio_output = QAudioOutput()
|
||||
self.video_widget = QVideoWidget()
|
||||
self.video_sink = self.video_widget.videoSink()
|
||||
@ -240,18 +242,6 @@ class Player(QMainWindow): # type: ignore[misc]
|
||||
self.presentation_changed.connect(self.presentation_changed_callback)
|
||||
self.slide_changed.connect(self.slide_changed_callback)
|
||||
|
||||
old_frame = None
|
||||
|
||||
def frame_changed(frame: QVideoFrame) -> None:
|
||||
nonlocal old_frame
|
||||
|
||||
if old_frame and (frame.size() != old_frame.size()):
|
||||
self.video_sink.setVideoFrame(old_frame)
|
||||
frame = old_frame
|
||||
|
||||
self.info.video_sink.setVideoFrame(frame)
|
||||
old_frame = frame
|
||||
|
||||
self.info = Info(
|
||||
full_screen=full_screen,
|
||||
aspect_ratio_mode=aspect_ratio_mode,
|
||||
@ -259,7 +249,7 @@ class Player(QMainWindow): # type: ignore[misc]
|
||||
)
|
||||
self.info.close_event.connect(self.closeEvent)
|
||||
self.info.key_press_event.connect(self.keyPressEvent)
|
||||
self.video_sink.videoFrameChanged.connect(frame_changed)
|
||||
self.video_sink.videoFrameChanged.connect(self.frame_changed)
|
||||
self.hide_info_window = hide_info_window
|
||||
|
||||
# Connecting key callbacks
|
||||
@ -555,6 +545,34 @@ class Player(QMainWindow): # type: ignore[misc]
|
||||
else:
|
||||
self.setCursor(Qt.BlankCursor)
|
||||
|
||||
def frame_changed(self, frame: QVideoFrame) -> None:
|
||||
"""
|
||||
Slot to handle possibly invalid frames.
|
||||
|
||||
This slot cannot be decorated with ``@Slot`` as
|
||||
the video sinks are handled in different threads.
|
||||
|
||||
As of Qt>=6.5.3, the last frame of every video is "flushed",
|
||||
resulting in a short black screen between each slide.
|
||||
|
||||
To avoid this issue, we check every frame, and avoid playing
|
||||
invalid ones.
|
||||
|
||||
References
|
||||
----------
|
||||
1. https://github.com/jeertmans/manim-slides/issues/293
|
||||
2. https://github.com/jeertmans/manim-slides/pull/464
|
||||
|
||||
:param frame: The most recent frame.
|
||||
|
||||
"""
|
||||
if frame.isValid():
|
||||
self.frame = frame
|
||||
else:
|
||||
self.video_sink.setVideoFrame(self.frame) # Reuse previous frame
|
||||
|
||||
self.info.video_sink.setVideoFrame(self.frame)
|
||||
|
||||
def closeEvent(self, event: QCloseEvent) -> None: # noqa: N802
|
||||
self.close()
|
||||
|
||||
|
Reference in New Issue
Block a user