Ошибка Python-vlc: сбой HTTP-соединения

#python #http #pyqt #vlc #python-vlc

#python #http #pyqt #vlc #python-vlc

Вопрос:

Я пытаюсь воспроизвести онлайн-видео с помощью python-vlc библиотеки.

Сначала я использовал простую версию проигрывателя, чтобы протестировать ее:

 import vlc

#example url
url="https://player.vimeo.com/external/363536021.hd.mp4?s=6f6e87d86a49149479ebdab6c8bc421aa89f327camp;profile_id=175amp;oauth2_token_id=57447761"
player = vlc.Instance().media_player_new()
player.set_media(vlc.Instance().media_new(url))
player.play()


while str(player.get_state()) != "State.Ended":
    pass
player.stop()
  

Он воспроизводит видео while с URL без каких-либо проблем!

Теперь я хотел использовать более сложную версию с pyqt5 графическим интерфейсом (исходный исходный код здесь):

 import sys

import os.path
from PyQt5.QtCore import Qt, QTimer
from PyQt5.QtGui import QPalette, QColor
from PyQt5.QtWidgets import QMainWindow, QWidget, QFrame, QSlider, QHBoxLayout, QPushButton, 
    QVBoxLayout, QAction, QFileDialog, QApplication
import vlc

class Player(QMainWindow):
    def __init__(self, videoUrl, master=None):
        QMainWindow.__init__(self, master)
        self.setWindowTitle("Media Player")

        # creating a basic vlc instance
        self.instance = vlc.Instance()
        # creating an empty vlc media player
        self.mediaplayer = self.instance.media_player_new()
        self.playableVideo = videoUrl

        self.createUI()
        self.isPaused = False

    def createUI(self):
        """Set up the user interface, signals amp; slots
        """
        self.widget = QWidget(self)
        self.setCentralWidget(self.widget)

        # In this widget, the video will be drawn
        if sys.platform == "darwin": # for MacOS
            from PyQt5.QtWidgets import QMacCocoaViewContainer  
            self.videoframe = QMacCocoaViewContainer(0)
        else:
            self.videoframe = QFrame()
        self.palette = self.videoframe.palette()
        self.palette.setColor (QPalette.Window,
                               QColor(0,0,0))
        self.videoframe.setPalette(self.palette)
        self.videoframe.setAutoFillBackground(True)

        self.positionslider = QSlider(Qt.Horizontal, self)
        self.positionslider.setToolTip("Position")
        self.positionslider.setMaximum(5000)
        self.positionslider.sliderMoved.connect(self.setPosition)

        self.hbuttonbox = QHBoxLayout()
        self.playbutton = QPushButton("Play")
        self.hbuttonbox.addWidget(self.playbutton)
        self.playbutton.clicked.connect(self.PlayPause)

        self.stopbutton = QPushButton("Exit")
        self.hbuttonbox.addWidget(self.stopbutton)
        self.stopbutton.clicked.connect(self.Stop)

        self.hbuttonbox.setAlignment(Qt.AlignHCenter)

        self.vboxlayout = QVBoxLayout()
        self.vboxlayout.addWidget(self.videoframe)
        self.vboxlayout.addWidget(self.positionslider)
        self.vboxlayout.addLayout(self.hbuttonbox)

        self.widget.setLayout(self.vboxlayout)

        self.timer = QTimer(self)
        self.timer.setInterval(200)
        self.timer.timeout.connect(self.updateUI)

    def PlayPause(self):
        """Toggle play/pause status
        """
        if self.mediaplayer.is_playing():
            self.mediaplayer.pause()
            self.playbutton.setText("Play")
            self.isPaused = True
        else:
            if self.mediaplayer.play() == -1:
                self.OpenFile()
                return
            self.mediaplayer.play()
            self.playbutton.setText("Pause")
            self.timer.start()
            self.isPaused = False

    def Stop(self):
        """Stop player
        """
        self.mediaplayer.stop()
        self.playbutton.setText("Play")

    def OpenFile(self, filename=None):
        """Open a media file in a MediaPlayer
        """
        if filename is None:
            filename = self.playableVideo
        if not filename:
            return

        # create the media
        if sys.version < '3':
            filename = unicode(filename)
        self.media = self.instance.media_new(filename)
        # put the media in the media player
        self.mediaplayer.set_media(self.media)

        # parse the metadata of the file
        self.media.parse()
        # set the title of the track as window title
        self.setWindowTitle(self.media.get_meta(0))

        # the media player has to be 'connected' to the QFrame
        # (otherwise a video would be displayed in it's own window)
        # this is platform specific!
        # you have to give the id of the QFrame (or similar object) to
        # vlc, different platforms have different functions for this
        if sys.platform.startswith('linux'): # for Linux using the X Server
            self.mediaplayer.set_xwindow(self.videoframe.winId())
        elif sys.platform == "win32": # for Windows
            self.mediaplayer.set_hwnd(self.videoframe.winId())
        elif sys.platform == "darwin": # for MacOS
            self.mediaplayer.set_nsobject(int(self.videoframe.winId()))
        self.PlayPause()

    def setPosition(self, position):
        self.mediaplayer.set_position(position / 1000.0)

    def updateUI(self):
        self.positionslider.setValue(self.mediaplayer.get_position() * 1000)

        if not self.mediaplayer.is_playing():
            self.timer.stop()
            if not self.isPaused:
                self.Stop()

if __name__ == "__main__":
    app = QApplication(sys.argv)
    player = Player("https://player.vimeo.com/external/363536021.hd.mp4?s=6f6e87d86a49149479ebdab6c8bc421aa89f327camp;profile_id=175amp;oauth2_token_id=57447761")
    player.show()
    player.resize(640, 480)
    if sys.argv[1:]:
        player.OpenFile(sys.argv[1])
    sys.exit(app.exec_())
  

Этот код продолжает возвращать access stream error: HTTP connection failure .

Ответ №1:

Проблема в том, что, как только вы начинаете воспроизводить видео, оно становится недоступным, поскольку загрузка происходит не сразу, но с помощью вашего кода вы пытаетесь обновить позицию. Решение состоит в том, чтобы обновить, чтобы получить позицию после того, как она начала воспроизводиться:

 def updateUI(self):
    if not self.mediaplayer.is_playing():
        return
    self.positionslider.setValue(self.mediaplayer.get_position() * 1000)
    if not self.mediaplayer.is_playing():
        self.timer.stop()
        if not self.isPaused:
            self.Stop()