问题描述
我正在尝试使用python-vlc
库播放在线视频。
首先,我正在使用播放器的简单版本进行测试:
import vlc
#example url
url="https://player.vimeo.com/external/363536021.hd.mp4?s=6f6e87d86a49149479ebdab6c8bc421aa89f327c&profile_id=175&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()
它可以播放URL中的while视频,没有任何问题!
现在我想在pyqt5
GUI(original source-code here)中使用更复杂的版本:
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 & 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))
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=6f6e87d86a49149479ebdab6c8bc421aa89f327c&profile_id=175&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
。
解决方法
问题在于,一旦您开始播放视频,该视频将不可用,因为下载不是立即进行的,而是尝试使用您的代码来更新位置。解决方案是更新是在开始播放后获取位置:
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()