Source code for QVideo.QCamcorder

#!/usr/bin/env python3

'''Composite camcorder widget combining a video screen, camera controls,
and DVR.

Run directly to launch a full camcorder application with camera selection::

    python -m QVideo.QCamcorder [-b|-c|-f|-i|-m|-p|-r|-v] [cameraID]

Camera flags (mutually exclusive):

.. code-block:: text

    -b [cameraID]   Basler camera (requires pylon SDK)
    -c [cameraID]   OpenCV camera
    -f [cameraID]   FLIR camera (requires Spinnaker SDK)
    -i [cameraID]   IDS Imaging camera (requires IDS peak SDK)
    -m [cameraID]   MATRIX VISION mvGenTLProducer (universal GenICam, not FLIR)
    -p [cameraID]   Raspberry Pi camera module (requires picamera2)
    -r [cameraID]   OpenCV camera with resolution drop-down selector
    -v [cameraID]   Allied Vision VimbaX camera
    -h              Show help and exit

If no flag is given, a noise camera is used as a fallback.
'''

from qtpy import QtCore, QtWidgets, QtGui
from QVideo.lib import QCameraTree, QVideoSource, QVideoScreen, QSnapshot
from QVideo.dvr import QDVRWidget


__all__ = ['QCamcorder']


[docs] class QCamcorder(QtWidgets.QWidget): '''A widget combining a video screen, camera controls, and DVR. Lays out a :class:`~QVideo.lib.QVideoScreen.QVideoScreen` alongside a :class:`~QVideo.dvr.QDVRWidget.QDVRWidget` and an arbitrary :class:`~QVideo.lib.QCameraTree.QCameraTree` control panel. Live frames from the camera source are routed to the screen; when the DVR starts playback the screen is switched to the playback stream and the camera controls are disabled until playback ends. A :class:`~QVideo.lib.QSnapshot.QSnapshot` is wired to the screen's ``newFrame`` signal, enabling still-frame capture via two hotkeys: - ``Ctrl+Shift+S`` — save a timestamped PNG to the home directory - ``Ctrl+Shift+Alt+S`` — open a file dialog pre-filled with the same name Parameters ---------- cameraWidget : QCameraTree Camera control tree to embed in the controls panel. *args : Additional positional arguments forwarded to :class:`~pyqtgraph.Qt.QtWidgets.QWidget`. **kwargs : Additional keyword arguments forwarded to :class:`~pyqtgraph.Qt.QtWidgets.QWidget`. ''' def __init__(self, cameraWidget: QCameraTree, *args, **kwargs) -> None: super().__init__(*args, **kwargs) self.cameraWidget = cameraWidget self._setupUi() self._snapshot = QSnapshot(self) self._connectSignals() self.screen.source = self.source self.dvr.source = self.source def _setupUi(self) -> None: self.screen = QVideoScreen(self) self.dvr = QDVRWidget(self) self.controls = QtWidgets.QWidget(self) controlsLayout = QtWidgets.QVBoxLayout(self.controls) controlsLayout.addWidget(self.dvr) controlsLayout.addWidget(self.cameraWidget) layout = QtWidgets.QHBoxLayout(self) layout.addWidget(self.screen) layout.addWidget(self.controls) layout.setStretch(0, 1) layout.setStretch(1, 0) def _connectSignals(self) -> None: self.dvr.playing.connect(self.dvrPlayback) self.screen.newFrame.connect(self._snapshot.newFrame)
[docs] def closeEvent(self, event: QtGui.QCloseEvent) -> None: '''Stop the camera source when the widget is closed.''' self.cameraWidget.stop() super().closeEvent(event)
[docs] @QtCore.Slot(bool) def dvrPlayback(self, playback: bool) -> None: '''Switch the screen source between live camera and DVR playback. Connected to :attr:`~QVideo.dvr.QDVRWidget.QDVRWidget.playing`. When playback starts the camera source is disconnected from the screen and the DVR's :attr:`~QVideo.dvr.QDVRWidget.QDVRWidget.newFrame` signal is connected instead; the camera controls are disabled. When playback ends the connections are reversed and the controls are re-enabled. Parameters ---------- playback : bool ``True`` when DVR playback begins, ``False`` when it ends. ''' self.screen.source = self.dvr.player if playback else self.source self.cameraWidget.setDisabled(playback)
@property def source(self) -> QVideoSource: '''The :class:`~QVideo.lib.QVideoSource.QVideoSource` from the camera widget.''' return self.cameraWidget.source
def main() -> None: # pragma: no cover '''Launch the camcorder with an interactively chosen camera.''' import pyqtgraph as pg from QVideo.lib import choose_camera pg.mkQApp('QCamcorder') camera = choose_camera() widget = QCamcorder(camera.start()) widget.show() pg.exec() if __name__ == '__main__': main()