Source code for araviq6.videowidgets
"""
Video widgets
=============
:mod:`araviq6.videowidgets` provides convenience widgets with pre-built video
pipelines.
.. autoclass:: PlayerProcessWidget
:members:
.. autoclass:: CameraProcessWidget
:members:
"""
from .videostream import VideoFrameWorker, VideoFrameProcessor
from .util import MediaController
from araviq6.qt_compat import QtCore, QtWidgets, QtMultimedia, QtMultimediaWidgets
__all__ = [
"PlayerProcessWidget",
"CameraProcessWidget",
]
[docs]
class PlayerProcessWidget(QtWidgets.QWidget):
"""
Widget to play video file with array processing.
By default this widget does not perform any array processing. User may define
own :class:`VideoFrameWorker` instance and set by :meth:`setWorker`.
Examples
========
.. tabs::
.. code-tab:: python PySide6
from PySide6.QtCore import QUrl
from PySide6.QtWidgets import QApplication
import sys
from araviq6 import PlayerProcessWidget, VideoFrameWorker
from araviq6.util import get_data_path
class FlipWorker(VideoFrameWorker):
def processArray(self, array):
return array[::-1]
def runGUI():
app = QApplication(sys.argv)
w = PlayerProcessWidget()
w.setWorker(FlipWorker())
w.setSource(QUrl.fromLocalFile(get_data_path('hello.mp4')))
w.show()
app.exec()
app.quit()
runGUI() # doctest: +SKIP
"""
def __init__(self, parent=None):
super().__init__(parent)
self._videoPlayer = QtMultimedia.QMediaPlayer()
self._playerVideoSink = QtMultimedia.QVideoSink()
self._frameProcessor = VideoFrameProcessor()
self._videoWidget = QtMultimediaWidgets.QVideoWidget()
self._mediaController = MediaController()
# set up the pipeline
self._videoPlayer.setVideoSink(self._playerVideoSink)
self._playerVideoSink.videoFrameChanged.connect(
self._frameProcessor.processVideoFrame
)
self._frameProcessor.videoFrameProcessed.connect(self.displayVideoFrame)
self._mediaController.setPlayer(self._videoPlayer)
layout = QtWidgets.QVBoxLayout()
layout.addWidget(self._videoWidget)
layout.addWidget(self._mediaController)
self.setLayout(layout)
def videoPlayer(self) -> QtMultimedia.QMediaPlayer:
return self._videoPlayer
def frameProcessor(self) -> VideoFrameProcessor:
return self._frameProcessor
def setSource(self, url: QtCore.QUrl):
self._videoPlayer.setSource(url)
def setWorker(self, worker: VideoFrameWorker):
self._frameProcessor.setWorker(worker)
@QtCore.Slot(QtMultimedia.QVideoFrame)
def displayVideoFrame(self, frame: QtMultimedia.QVideoFrame):
self._videoWidget.videoSink().setVideoFrame(frame)
def closeEvent(self, event):
self._frameProcessor.stop()
super().closeEvent(event)
[docs]
class CameraProcessWidget(QtWidgets.QWidget):
"""
Widget to stream camera with array processing.
By default this widget does not perform any array processing. User may define
own :class:`VideoFrameWorker` instance and set by :meth:`setWorker`.
Examples
========
.. tabs::
.. code-tab:: python PySide6
from PySide6.QtWidgets import QApplication
from PySide6.QtMultimedia import QCamera
import sys
from araviq6 import VideoFrameWorker, CameraProcessWidget
class FlipWorker(VideoFrameWorker):
def processArray(self, array):
return array[::-1]
def runGUI():
app = QApplication(sys.argv)
widget = CameraProcessWidget()
widget.setWorker(FlipWorker())
camera = QCamera()
widget.setCamera(camera)
camera.start()
widget.show()
app.exec()
app.quit()
runGUI() # doctest: +SKIP
"""
def __init__(self, parent=None):
super().__init__(parent)
self._captureSession = QtMultimedia.QMediaCaptureSession()
self._cameraVideoSink = QtMultimedia.QVideoSink()
self._frameProcessor = VideoFrameProcessor()
self._videoWidget = QtMultimediaWidgets.QVideoWidget()
# set up the pipeline
self._captureSession.setVideoSink(self._cameraVideoSink)
self._cameraVideoSink.videoFrameChanged.connect(
self._frameProcessor.processVideoFrame
)
self._frameProcessor.videoFrameProcessed.connect(self.displayVideoFrame)
layout = QtWidgets.QVBoxLayout()
layout.addWidget(self._videoWidget)
self.setLayout(layout)
def captureSession(self) -> QtMultimedia.QMediaCaptureSession:
return self._captureSession
def frameProcessor(self) -> VideoFrameProcessor:
return self._frameProcessor
@QtCore.Slot(QtMultimedia.QCamera)
def setCamera(self, camera: QtMultimedia.QCamera):
self._captureSession.setCamera(camera)
def setWorker(self, worker: VideoFrameWorker):
self._frameProcessor.setWorker(worker)
@QtCore.Slot(QtMultimedia.QVideoFrame)
def displayVideoFrame(self, frame: QtMultimedia.QVideoFrame):
self._videoWidget.videoSink().setVideoFrame(frame)
def closeEvent(self, event):
self._frameProcessor.stop()
super().closeEvent(event)