Пример #1
0
class VideoPlaybackDevice(Filter):
    playbackStarted = Signal()
    playbackPaused = Signal()
    sequenceOpened = Signal(str, QDateTime, QDateTime, list)
    currentTimestampChanged = Signal(QDateTime)

    def __init__(self, environment):
        super().__init__(False, False, environment)
        self.video_out = OutputPort(False, "video", environment)
        self.audio_out = OutputPort(False, "audio", environment)
        self.addStaticPort(self.video_out)
        self.addStaticPort(self.audio_out)
        self.filename = self.propertyCollection().defineProperty(
            "filename", "", "avi file name")

    def newDuration(self, newDuration):
        logger.debug("newDuration %s", newDuration)
        self.sequenceOpened.emit(self.filename,
                                 QDateTime.fromMSecsSinceEpoch(0),
                                 QDateTime.fromMSecsSinceEpoch(newDuration),
                                 ["video"])

    def currentMediaChanged(self, media):
        logger.debug("currentMediaChanged videoAv=%s audioAv=%s",
                     self.player.isVideoAvailable(),
                     self.player.isAudioAvailable())

    def _openVideo(self):
        logger.debug("entering _openVideo")
        self.player = QMediaPlayer(None, QMediaPlayer.VideoSurface)
        self.videoOutput = DummyVideoSurface(self.player)
        #self.videoOutput = QVideoWidget()
        #self.videoOutput.show()
        self.player.setVideoOutput(self.videoOutput)
        #self.player.setMuted(True)
        self.player.durationChanged.connect(self.newDuration)
        self.player.currentMediaChanged.connect(self.currentMediaChanged)
        self.player.setMedia(QUrl.fromLocalFile(self.filename))
        logger.debug("leaving _openVideo; videoAv=%s audioAv=%s",
                     self.player.isVideoAvailable(),
                     self.player.isAudioAvailable())

    def _closeVideo(self):
        try:
            del self.player
            del self.playlist
        except:
            pass

    def onStart(self):
        ctrlSrv = Services.getService("PlaybackControl")
        ctrlSrv.setupConnections(self)
        self.playbackPaused.emit()
        if self.filename != "":
            self._openVideo()

    def onStop(self):
        ctrlSrv = Services.getService("PlaybackControl")
        ctrlSrv.removeConnections(self)
        self._closeVideo()

    @Slot()
    def startPlayback(self):
        self.player.play()
        self.playbackStarted.emit()
        logger.debug("leaving startPlayback; videoAv=%s audioAv=%s",
                     self.player.isVideoAvailable(),
                     self.player.isAudioAvailable())

    @Slot()
    def pausePlayback(self):
        self.player.pause()
        self.playbackPaused.emit()

    def newDataEvent(self):
        t = time.monotonic()
        if self.lastSendTime is not None:
            if t - self.lastSendTime < self.timeout_ms * 1e-3:
                # we are still earlier than the requested framerate
                return
        self.lastSendTime = t
        self.counter += 1
        c = "Sample %d" % self.counter
        s = DataSample(c.encode("utf8"), "text/utf8",
                       int(time.time() / DataSample.TIMESTAMP_RES))
        logging.getLogger(__name__).info("transmit: %s", c)
        self.beforeTransmit(s)
        self.outPort.transmit(s)
        self.afterTransmit()

    def stepForward(self):
        pass

    def stepBackward(self):
        pass

    def seekBeginning(self):
        pass

    def seekEnd(self):
        pass

    def seekTime(self, timestamp):
        pass

    def setSequence(self, filename):
        self.filename

    def setTimeFactor(self, factor):
        pass
Пример #2
0
class Sound:
    """Loads a sound from the specified URL.

    Supports whatever audio formats that PySide2 supports (depending on locally-installed codecs).
    No error is raised if the file isn't found or is of an unsupported format.

    Sounds are tracked

    :param url: the URL to load the sound from, can be a local file
    """
    def __init__(self, url):
        # type: (str) -> None
        self.__url = url  # Only used for debugging

        # Tell the app not to quit while this sound is loading, since it is plausible that a user is using sounds
        # without using a frame or any timers:
        TheApp.add_tracked(self)

        self.__player = QMediaPlayer(TheApp, flags=QMediaPlayer.LowLatency)
        self.__player.setAudioRole(QAudio.GameRole)
        self.__player.mediaStatusChanged.connect(self.__on_status_changed)
        self.__player.error.connect(self.__on_status_changed)

        req = request(url)
        content = QMediaContent(req)
        self.__player.setMedia(content)

        self.__sound_loaded = False
        self.__play_requested = False

    def __on_status_changed(self, _):
        # type: (QMediaPlayer.MediaStatus) -> None
        """Checks if the sound is loaded.

        If the sound has loaded without error, and the user has already told it to start playing, this will start the
        sound playing.

        If there was any failure in loading the sound, this is recorded, and the sound will never be
        able to be played.  TheApp will also be notified that it can close if this sound is all it is waiting for.

        This event is also triggered by other status changes.  The only other one that matters is the EndOfMedia status.
        In this case, TheApp is also told that it can close.

        :param _: (unused) media status object
        """
        error = self.__player.error()
        status = self.__player.mediaStatus()
        if status < QMediaPlayer.LoadedMedia:
            return

        if error == QMediaPlayer.NoError and QMediaPlayer.LoadedMedia <= status < QMediaPlayer.InvalidMedia:
            # Check if the media is actually an audio file that is playable
            if self.__player.isAudioAvailable():
                self.__sound_loaded = True
                if self.__play_requested and status != QMediaPlayer.EndOfMedia:
                    # Play and don't do anything else now
                    self.play()
                    return
        else:
            self.__sound_loaded = False
        self.__play_requested = False
        TheApp.remove_tracked(self)

    def play(self):
        """Starts playing a sound, or restarts playing it at the point it was paused."""
        if self.__sound_loaded:
            self.__player.play()
            TheApp.add_tracked(self)
        self.__play_requested = True

    def pause(self):
        """Stops the playing of the sound. Playing can be restarted at the stopped point with :meth:`play`."""
        if self.__sound_loaded:
            self.__player.pause()
            TheApp.remove_tracked(self)
        self.__play_requested = False

    def rewind(self):
        """Stops playing the sound, makes it so the next :meth:`play` will start playing the sound at the beginning."""
        if self.__sound_loaded:
            self.__player.stop()
            TheApp.remove_tracked(self)
        self.__play_requested = False

    def set_volume(self, volume):
        # type: (float) -> None
        """Changes the volume for the sound to be the given level on a 0 (silent) – 1.0 (maximum) scale. Default is 1.

        :param volume: the volume to set
        """
        assert 0.0 <= volume <= 1.0, "volume must be given in range 0-1 inclusive"
        self.__player.setVolume(int(100 * volume))