Page 1 of 1

Python and vlclib application

Posted: 28 Apr 2016 14:22
by Liaram
Hi
I want to develop a python application to read an MPEG-TS file with 4 video stream and 2 audio stream. I use Qt for the interface and vlc.py for teh libvlc
The application seems like a mosaic (with 4 Qframe to draw the streams).
For now, I declare 4 instances each with 1 player and there own settings (to extract each stream separately).
I give the code I use

Code: Select all

import sys import os.path import vlc import time from PyQt4 import QtGui, QtCore class Player(QtGui.QMainWindow): """A Media Player using VLC and Qt for EVN video""" def __init__(self, master=None): QtGui.QMainWindow.__init__(self, master) self.setWindowTitle("Media Player for EVN video") # creating a basic vlc instance self.instance1 = vlc.Instance('--demux=ts --no-audio --sout-all --sout=#duplicate{dst=display,select="es=257"]')#,dst=display,select="es=17"}') self.instance2 = vlc.Instance('--demux=ts --no-audio --sout-all --sout=#duplicate{dst=display,select="es=258"') self.instance3 = vlc.Instance('--demux=ts --no-audio --sout-all --sout=#duplicate{dst=display,select="es=822"}') self.instance4 = vlc.Instance('--demux=ts --no-audio --sout-all --sout=#duplicate{dst=display,select="es=1031"}') # creating an empty vlc media player self.mediaplayer1 = self.instance1.media_player_new() self.mediaplayer2 = self.instance2.media_player_new() self.mediaplayer3 = self.instance3.media_player_new() self.mediaplayer4 = self.instance4.media_player_new() self.createUI() self.isPaused = False def createUI(self): """Set up the user interface, signals & slots""" self.widget = QtGui.QWidget(self) self.setCentralWidget(self.widget) # In this widget, the video will be drawn if sys.platform == "darwin": # for MacOS self.videoframe1 = QtGui.QMacCocoaViewContainer(0) self.videoframe2 = QtGui.QMacCocoaViewContainer(0) self.videoframe3 = QtGui.QMacCocoaViewContainer(0) self.videoframe4 = QtGui.QMacCocoaViewContainer(0) else: self.videoframe1 = QtGui.QFrame() self.videoframe2 = QtGui.QFrame() self.videoframe3 = QtGui.QFrame() self.videoframe4 = QtGui.QFrame() self.palette = self.videoframe1.palette() self.palette.setColor (QtGui.QPalette.Window,QtGui.QColor(0,0,0)) self.videoframe1.setPalette(self.palette) self.videoframe1.setAutoFillBackground(True) self.videoframe2.setPalette(self.palette) self.videoframe2.setAutoFillBackground(True) self.videoframe3.setPalette(self.palette) self.videoframe3.setAutoFillBackground(True) self.videoframe4.setPalette(self.palette) self.videoframe4.setAutoFillBackground(True) self.positionslider = QtGui.QSlider(QtCore.Qt.Horizontal, self) self.positionslider.setToolTip("Position") self.positionslider.setMaximum(1000) self.connect(self.positionslider,QtCore.SIGNAL("sliderMoved(int)"), self.setPosition) self.hbuttonbox = QtGui.QHBoxLayout() self.playbutton = QtGui.QPushButton("Play") self.hbuttonbox.addWidget(self.playbutton) self.connect(self.playbutton, QtCore.SIGNAL("clicked()"),self.PlayPause) self.stopbutton = QtGui.QPushButton("Stop") self.hbuttonbox.addWidget(self.stopbutton) self.connect(self.stopbutton, QtCore.SIGNAL("clicked()"),self.Stop) self.gettimebutton = QtGui.QPushButton("Get Time") self.hbuttonbox.addWidget(self.gettimebutton) self.connect(self.gettimebutton, QtCore.SIGNAL("clicked()"),self.getTime) self.hbuttonbox.addStretch(1) self.volumeslider = QtGui.QSlider(QtCore.Qt.Horizontal, self) self.volumeslider.setMaximum(100) self.volumeslider.setValue(self.mediaplayer1.audio_get_volume()) self.volumeslider.setToolTip("Volume") self.hbuttonbox.addWidget(self.volumeslider) self.connect(self.volumeslider,QtCore.SIGNAL("valueChanged(int)"),self.setVolume) self.splitter1 = QtGui.QSplitter(QtCore.Qt.Horizontal) self.splitter1.addWidget(self.videoframe1) self.splitter1.addWidget(self.videoframe2) self.splitter1.setSizes([100,100]) self.splitter2 = QtGui.QSplitter(QtCore.Qt.Horizontal) self.splitter2.addWidget(self.videoframe3) self.splitter2.addWidget(self.videoframe4) self.splitter2.setSizes([100,100]) self.vboxlayout = QtGui.QVBoxLayout() self.vboxlayout.addWidget(self.splitter1) self.vboxlayout.addWidget(self.splitter2) self.vboxlayout.addWidget(self.positionslider) self.vboxlayout.addLayout(self.hbuttonbox) self.widget.setLayout(self.vboxlayout) open = QtGui.QAction("&Open", self) self.connect(open, QtCore.SIGNAL("triggered()"), self.OpenFile) exit = QtGui.QAction("&Exit", self) self.connect(exit, QtCore.SIGNAL("triggered()"), sys.exit) menubar = self.menuBar() filemenu = menubar.addMenu("&File") filemenu.addAction(open) filemenu.addSeparator() filemenu.addAction(exit) self.timer = QtCore.QTimer(self) self.timer.setInterval(200) self.connect(self.timer, QtCore.SIGNAL("timeout()"),self.updateUI) def PlayPause(self): """Toggle play/pause status""" if self.mediaplayer1.is_playing(): self.mediaplayer1.pause() self.mediaplayer2.pause() self.mediaplayer3.pause() self.mediaplayer4.pause() self.playbutton.setText("Play") self.isPaused = True else: if self.mediaplayer1.play() == -1: self.OpenFile() return self.mediaplayer1.play() self.mediaplayer2.play() self.mediaplayer3.play() self.mediaplayer4.play() self.playbutton.setText("Pause") self.timer.start() self.isPaused = False def Stop(self): """Stop player""" self.mediaplayer1.stop() self.mediaplayer2.stop() self.mediaplayer3.stop() self.mediaplayer4.stop() self.playbutton.setText("Play") def OpenFile(self, filename=None): """Open a media file in a MediaPlayer""" if filename is None: filename = QtGui.QFileDialog.getOpenFileName(self, "Open File", os.path.expanduser('~')) if not filename: return # create the media if sys.version < '3': filename = unicode(filename) self.media1 = self.instance1.media_new(filename) self.media2 = self.instance2.media_new(filename) self.media3 = self.instance3.media_new(filename) self.media4 = self.instance4.media_new(filename) # put the media in the media player self.mediaplayer1.set_media(self.media1) self.mediaplayer2.set_media(self.media2) self.mediaplayer3.set_media(self.media3) self.mediaplayer4.set_media(self.media4) # parse the metadata of the file self.media1.parse() # set the title of the track as window title self.setWindowTitle(self.media1.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.mediaplayer1.set_xwindow(self.videoframe1.winId()) self.mediaplayer2.set_xwindow(self.videoframe2.winId()) self.mediaplayer3.set_xwindow(self.videoframe3.winId()) self.mediaplayer4.set_xwindow(self.videoframe4.winId()) elif sys.platform == "win32": # for Windows self.mediaplayer1.set_hwnd(self.videoframe1.winId()) self.mediaplayer2.set_hwnd(self.videoframe2.winId()) self.mediaplayer3.set_hwnd(self.videoframe3.winId()) self.mediaplayer4.set_hwnd(self.videoframe4.winId()) elif sys.platform == "darwin": # for MacOS self.mediaplayer1.set_nsobject(self.videoframe1.winId()) self.mediaplayer2.set_nsobject(self.videoframe2.winId()) self.mediaplayer3.set_nsobject(self.videoframe3.winId()) self.mediaplayer4.set_nsobject(self.videoframe4.winId()) self.PlayPause() def setVolume(self, Volume): """Set the volume""" self.mediaplayer1.audio_set_volume(Volume) def setPosition(self, position): """Set the position""" # setting the position to where the slider was dragged # the vlc MediaPlayer needs a float value between 0 and 1, Qt # uses integer variables, so you need a factor; the higher the # factor, the more precise are the results # (1000 should be enough) self.mediaplayer1.set_position(position / 1000.0) self.mediaplayer2.set_position(position / 1000.0) self.mediaplayer3.set_position(position / 1000.0) self.mediaplayer4.set_position(position / 1000.0) def getPosition(self): """Get the position""" return self.mediaplayer1.get_position() def getTime(self): """Get current time in ms""" duration = self.media1.get_duration() position = self.mediaplayer1.get_position() return duration * position def updateUI(self): """updates the user interface""" # setting the slider to the desired position self.positionslider.setValue(self.mediaplayer1.get_position() * 1000) if not self.mediaplayer1.is_playing(): # no need to call this function if nothing is played self.timer.stop() if not self.isPaused: # after the video finished, the play button stills shows # "Pause", not the desired behavior of a media player # this will fix it self.Stop() if __name__ == "__main__": app = QtGui.QApplication(sys.argv) player = Player() player.show() player.resize(800, 600) if sys.argv[1:]: player.OpenFile(sys.argv[1]) sys.exit(app.exec_())
So I have some questions :
- Is it possible to have only one instance for all stream ? I tried to declare 1 instance with 4 players and open the file with different settings. But the application don't use the settings and show only the first video stream (on the 4 player)
- Is it possible to control all the players with only one command for each action (play, pause, stop, etc...) ? For now I use a command line for each player. Vlc can do that so I think it's possible but don't know how to.

Re: Python and vlclib application

Posted: 30 Apr 2016 19:18
by OlivierAubert
Hi

- one instance for all streams: it depends on the settings you want to set. Looking at your code, it seems to me that sout must be set at the instance level. You should dig into the libvlc doc/code (not python-specific) to be sure.
- AFAIK, there is no native way of synchronizing multiple players, apart doing as you did here - wrapping a general method to call it on every player (personally, I would store the various instances in a list and iterate commands on the list, but it does not really matter)

Re: Python and vlclib application

Posted: 13 May 2016 16:46
by Liaram
Hi
Thanks for your response.
I tried to define the sout option in only one instance.
In this case, if I load one mediaplayer and connect it to a Qframe, that's display the first video stream into the the Qframe and open three vlc windows to display the others video stream.

If I load 4 mediaplayer and connect to the 4 Qframe, they all display the main video frame and open three vlc windows for each mediaplayer (12 windows) to display the others video stream.

So I will stay with the first version for the moment. And continue to search for a better solution or to find the correct settings.