[PyQt] Fwd: QAbstractVideoSurface RTP player
Dennis Jensen
djensen at pgcontrols.com
Mon Nov 18 14:40:15 GMT 2019
Hey Fran while I cannot help you personally with this issue I have a
couple of advanced students that have already resolved much of this
video implementation in python-pyqt5 and if you shoot me a message on
Discord at either `DenniO#8137` and/or `DeJoker#1460` I can get you
introduced to them and they can probably help you get everything sorted
out. Otherwise good luck in solving this.
On 11/18/2019 3:24 AM, Fran Raga wrote:
> hi all
>
> I'm trying to play a video via RTP but strange things happen.
>
> The video plays but not always and does not return any error message.
> Sometimes when I open it it works and another does not
>
> I don't know if I'm missing a flag or I'm doing it wrong.
>
> Any suggestion about this?
>
> this is my code
>
> import sys
> import os
> from PyQt5.QtGui import *
> from PyQt5.QtWidgets import *
> from PyQt5.QtCore import *
> from PyQt5.QtNetwork import *
> from PyQt5.QtMultimedia import *
> from PyQt5.QtMultimediaWidgets import *
> import time
>
> fileName = 'rtp://127.0.0.1:8888 <http://127.0.0.1:8888>'
>
>
> class VideoWidgetSurface(QAbstractVideoSurface):
>
> def __init__(self, widget, parent=None):
> super(VideoWidgetSurface, self).__init__(parent)
>
> self.widget = widget
> self.imageFormat = QImage.Format_Invalid
>
> def supportedPixelFormats(self,
> handleType=QAbstractVideoBuffer.NoHandle):
> formats = [QVideoFrame.PixelFormat()]
> if (handleType == QAbstractVideoBuffer.NoHandle):
> for f in [QVideoFrame.Format_RGB32,
> QVideoFrame.Format_ARGB32,
> QVideoFrame.Format_ARGB32_Premultiplied,
> QVideoFrame.Format_RGB565,
> QVideoFrame.Format_RGB555
> ]:
> formats.append(f)
> return formats
>
> def isFormatSupported(self, _format):
> imageFormat =
> QVideoFrame.imageFormatFromPixelFormat(_format.pixelFormat())
> size = _format.frameSize()
> _bool = False
> if (imageFormat != QImage.Format_Invalid and not \
> size.isEmpty() and _format.handleType() ==
> QAbstractVideoBuffer.NoHandle):
> _bool = True
> return _bool
>
> def start(self, _format):
> imageFormat =
> QVideoFrame.imageFormatFromPixelFormat(_format.pixelFormat())
> size = _format.frameSize()
> if (imageFormat != QImage.Format_Invalid and not size.isEmpty()):
> self.imageFormat = imageFormat
> self.imageSize = size
> self.sourceRect = _format.viewport()
> QAbstractVideoSurface.start(self, _format)
> self.widget.updateGeometry()
> self.updateVideoRect()
> return True
> else:
> return False
>
> def stop(self):
> self.currentFrame = QVideoFrame()
> self.targetRect = QRect()
> QAbstractVideoSurface.stop(self)
> self.widget.update()
>
> def present(self, frame):
> if (self.surfaceFormat().pixelFormat() != frame.pixelFormat()
> or self.surfaceFormat().frameSize() != frame.size()):
> self.setError(QAbstractVideoSurface.IncorrectFormatError)
> self.stop()
> return False
> else:
> self.currentFrame = frame
> self.widget.repaint(self.targetRect)
> return True
>
> def videoRect(self):
> return self.targetRect
>
> def updateVideoRect(self):
> size = self.surfaceFormat().sizeHint()
> size.scale(self.widget.size().boundedTo(size), Qt.KeepAspectRatio)
> self.targetRect = QRect(QPoint(0, 0), size)
> self.targetRect.moveCenter(self.widget.rect().center())
>
> def paint(self, painter):
> try: # maybe raise no �cruuentFrame� error
> if (self.currentFrame.map(QAbstractVideoBuffer.ReadOnly)):
> oldTransform = painter.transform()
>
> if (self.surfaceFormat().scanLineDirection() ==
> QVideoSurfaceFormat.BottomToTop):
> painter.scale(1, -1);
> painter.translate(0, -self.widget.height())
>
> image = QImage(self.currentFrame.bits(),
> self.currentFrame.width(), \
> self.currentFrame.height(),
> self.currentFrame.bytesPerLine(), self.imageFormat)
>
> painter.drawImage(self.targetRect, image, self.sourceRect)
> painter.setTransform(oldTransform)
>
> self.currentFrame.unmap()
> except Exception as e:
> print("Error paint : " , str(e))
> pass
>
>
> class VideoWidget(QWidget):
>
> def __init__(self, parent=None):
> super(VideoWidget, self).__init__(parent)
>
> self.setAutoFillBackground(False)
> self.setAttribute(Qt.WA_NoSystemBackground, True)
> self.setAttribute(Qt.WA_PaintOnScreen, True)
> palette = self.palette()
> palette.setColor(QPalette.Background, Qt.black)
> self.setPalette(palette)
> self.setSizePolicy(QSizePolicy.MinimumExpanding,
> QSizePolicy.MinimumExpanding)
> self.surface = VideoWidgetSurface(self)
>
> def videoSurface(self):
> return self.surface
>
> def closeEvent(self, event):
> del self.surface
>
> def sizeHint(self):
> return self.surface.surfaceFormat().sizeHint()
>
> def paintEvent(self, event):
> painter = QPainter(self)
> painter.setRenderHint(QPainter.HighQualityAntialiasing)
> print ("surface active : ", self.surface.isActive())
> if (self.surface.isActive()):
> self.surface.paint(painter)
> else:
> painter.fillRect(event.rect(), self.palette().window())
>
> def resizeEvent(self, event):
> QWidget.resizeEvent(self, event)
> self.surface.updateVideoRect()
>
>
> class VideoPlayer(QWidget):
>
> def __init__(self, parent=None):
> super(VideoPlayer, self).__init__(parent)
>
> self.mediaPlayer = QMediaPlayer(None,
> QMediaPlayer.VideoSurface or QMediaPlayer.StreamPlayback)
> self.videoWidget = VideoWidget()
> self.openButton = QPushButton("Open...")
> self.openButton.clicked.connect(self.openFile)
> self.playButton = QPushButton()
> self.playButton.setEnabled(False)
> self.playButton.setIcon(self.style().standardIcon(QStyle.SP_MediaPlay))
> self.playButton.clicked.connect(self.play)
>
> self.positionSlider = QSlider(Qt.Horizontal)
> self.positionSlider.setRange(0, 0)
> self.positionSlider.sliderMoved.connect(self.setPosition)
> self.controlLayout = QHBoxLayout()
> self.controlLayout.setContentsMargins(0, 0, 0, 0)
> self.controlLayout.addWidget(self.openButton)
> self.controlLayout.addWidget(self.playButton)
> self.controlLayout.addWidget(self.positionSlider)
> layout = QVBoxLayout()
> layout.addWidget(self.videoWidget)
> layout.addLayout(self.controlLayout)
>
> self.setLayout(layout)
>
> self.mediaPlayer.setVideoOutput(self.videoWidget.videoSurface())
> self.mediaPlayer.stateChanged.connect(self.mediaStateChanged)
> self.mediaPlayer.positionChanged.connect(self.positionChanged)
> self.mediaPlayer.durationChanged.connect(self.durationChanged)
>
> url = QUrl(fileName)
> media = QMediaContent(url)
>
> self.mediaPlayer.setMedia(media)
> self.playButton.setEnabled(True)
> time.sleep(.300)
> self.mediaPlayer.play()
>
> def openFile(self):
> file_name = QFileDialog.getOpenFileName(self, "Open Movie",
> QDir.homePath())[0]
> if os.path.exists(file_name):
> self.mediaPlayer.setMedia(QMediaContent(QUrl.fromLocalFile(file_name)))
> self.playButton.setEnabled(True)
>
> def play(self):
> if self.mediaPlayer.state() == QMediaPlayer.PlayingState:
> self.mediaPlayer.pause()
> else:
> self.mediaPlayer.play()
>
> def mediaStateChanged(self, state):
> if state == QMediaPlayer.PlayingState:
> self.playButton.setIcon(self.style().standardIcon(QStyle.SP_MediaPause))
> else:
> self.playButton.setIcon(self.style().standardIcon(QStyle.SP_MediaPlay))
>
> def positionChanged(self, position):
> self.positionSlider.setValue(position)
>
> def durationChanged(self, duration):
> self.positionSlider.setRange(0, duration)
>
> def setPosition(self, position):
> self.mediaPlayer.setPosition(position)
>
>
> if __name__ == '__main__':
> app = QApplication(sys.argv)
>
> player = VideoPlayer()
> player.setGeometry(100, 300, 600, 380)
> player.setFixedSize(QSize(600, 600)) # setFixedSize(QSize)
> player.show()
>
> sys.exit(app.exec_())
>
>
> And for start server I'm using
>
> ffmpeg -fflags +genpts -stream_loop -1 -re -i "C:\Users\Fran
> Raga\Desktop\video_test\Cheyenne.ts" -f rtp_mpegts -c copy -map 0:v
> -map 0:a -map 0:d rtp://127.0.0.1:8888 <http://127.0.0.1:8888>
>
> thanks
>
> *Francisco Raga** | *Full-Stack Open Source GIS Developer
> Móvil: (+34) 654275432*| *e-Mail: franka1986 at gmail.com
> <mailto:franka1986 at gmail.com> *| *skype: francisco_raga
> Github: https://goo.gl/ydNTjY*|*Linkedin:
> https://goo.gl/TCfj8S*|*Site: https://goo.gl/qiypDj
>
> "La vida real no tiene ningún mapa.." Ivy Compton Burnett
>
> _______________________________________________
> PyQt mailing list PyQt at riverbankcomputing.com
> https://www.riverbankcomputing.com/mailman/listinfo/pyqt
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://www.riverbankcomputing.com/pipermail/pyqt/attachments/20191118/9f25bbed/attachment-0001.html>
More information about the PyQt
mailing list